|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Locale::Babelfish;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: Perl I18n using https://github.com/nodeca/babelfish format.  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '2.003'; # VERSION  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
572
 | 
 use utf8;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
    | 
| 
9
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
27
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
10
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
 use warnings;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
 use Carp qw/ confess /;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
13
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use File::Find qw( find );  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
    | 
| 
14
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use File::Spec ();  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
16
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
252
 | 
 use YAML::SyckWrapper qw( load_yaml );  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11856
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
17
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
305
 | 
 use Locale::Babelfish::Phrase::Parser ();  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
18
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use Locale::Babelfish::Phrase::Compiler ();  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
 use parent qw( Class::Accessor::Fast );  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use constant {  | 
| 
24
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
410
 | 
     MTIME_INDEX => 9,  | 
| 
25
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
48
 | 
 };  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __PACKAGE__->mk_accessors( qw(  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     dictionaries  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     fallbacks  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     fallback_cache  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     dirs  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     suffix  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     default_locale  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     watch  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     watchers  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ) );  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $parser = Locale::Babelfish::Phrase::Parser->new();  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $compiler = Locale::Babelfish::Phrase::Compiler->new();  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _built_config {  | 
| 
43
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
2
 | 
     my ( $cfg ) = @_;  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return {  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         dictionaries   => {},  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fallbacks      => {},  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fallback_cache => {},  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         suffix         => $cfg->{suffix} // 'yaml',  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         default_locale => $cfg->{default_locale} // 'en_US',  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         watch          => $cfg->{watch} || 0,  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         watchers       => {},  | 
| 
52
 | 
1
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
12
 | 
         %{ $cfg // {} },  | 
| 
 
 | 
1
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
57
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
522
 | 
     my ( $class, $cfg ) = @_;  | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $self = bless {  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         _cfg => $cfg,  | 
| 
61
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
         %{ _built_config( $cfg ) },  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }, $class;  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
64
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     $self->load_dictionaries;  | 
| 
65
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $self->locale( $self->{default_locale} );  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
67
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     return $self;  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub locale {  | 
| 
72
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
8
 | 
     my $self = shift;  | 
| 
73
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     return $self->{locale}  if scalar(@_) == 0;  | 
| 
74
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     $self->{locale} = $self->detect_locale( $_[0] );  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub on_watcher_change {  | 
| 
79
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my ( $self ) = @_;  | 
| 
80
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     delete $self->{keys %$self};  | 
| 
81
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my %new_cfg = %{ _built_config( $self->{_cfg} ) };  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
82
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     while( my ( $key, $value ) = each %new_cfg ) {  | 
| 
83
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->{$key} = $value;  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
85
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->load_dictionaries;  | 
| 
86
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->locale( $self->{default_locale} );  | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub look_for_watchers {  | 
| 
91
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my ( $self ) = @_;  | 
| 
92
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return  unless $self->{watch};  | 
| 
93
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $ok = 1;  | 
| 
94
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     while ( my ( $file, $mtime ) = each %{ $self->watchers } ) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
95
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $new_mtime = (stat($file))[MTIME_INDEX];  | 
| 
96
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
         if ( !defined( $mtime ) || !defined( $new_mtime ) || $new_mtime != $mtime ) {  | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
97
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $ok = 0;  | 
| 
98
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             last;  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
101
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return  if $ok;  | 
| 
102
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->on_watcher_change();  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub t_or_undef {  | 
| 
107
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
  
1
  
 | 
64
 | 
     my ( $self, $dictname_key, $params, $custom_locale ) = @_;  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
110
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
55
 | 
     confess 'No dictname_key' unless $dictname_key;  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # запÑеÑаем клÑÑи не ASCII  | 
| 
112
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
89
 | 
     confess("wrong dictname_key: $dictname_key")  if $dictname_key =~ m/\P{ASCII}/;  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
114
 | 
22
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
61
 | 
     my $locale = $custom_locale ? $self->detect_locale( $custom_locale ) : $self->{locale};  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
116
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     my $r = $self->{dictionaries}->{$locale}->{$dictname_key};  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
22
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     if ( defined $r ) {  | 
| 
119
 | 
19
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
53
 | 
         if ( ref( $r ) eq 'SCALAR' ) {  | 
| 
120
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
             $self->{dictionaries}->{$locale}->{$dictname_key} = $r = $compiler->compile(  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $parser->parse( $$r, $locale ),  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             );  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      # fallbacks  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
127
 | 
3
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
14
 | 
         $self->{fallback_cache}->{$locale} //= {};  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # в кÑÑе Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ undef, ÑÑÐ¾Ð±Ñ Ð½Ðµ пÑобегаÑÑ Ð»Ð¾ÐºÐ°Ð»Ð¸ Ð´Ð»Ñ Ð½ÐµÑÑÑеÑÑвÑÑÑиÑ
 клÑÑей повÑоÑно.  | 
| 
129
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         if ( exists $self->{fallback_cache}->{$locale}->{$dictname_key} ) {  | 
| 
130
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $r = $self->{fallback_cache}->{$locale}->{$dictname_key};  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
133
 | 
3
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
6
 | 
             my @fallback_locales = @{ $self->{fallbacks}->{$locale} // [] };  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
    | 
| 
134
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
             for ( @fallback_locales ) {  | 
| 
135
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
                 $r = $self->{dictionaries}->{$_}->{$dictname_key};  | 
| 
136
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
                 if ( defined $r ) {  | 
| 
137
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
                     if ( ref( $r ) eq 'SCALAR' ) {  | 
| 
138
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
                         $self->{dictionaries}->{$_}->{$dictname_key} = $r = $compiler->compile(  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             $parser->parse( $$r, $_ ),  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         );  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
142
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
                     last;  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
145
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
             $self->{fallback_cache}->{$locale}->{$dictname_key} = $r;  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
149
 | 
22
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
77
 | 
     if ( ref( $r ) eq 'CODE' ) {  | 
| 
150
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
         my $flat_params = {};  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # ÐеÑеводим Ñ
ÑÑ Ð¿Ð°ÑамеÑÑов в "плоÑкÑÑ ÑоÑмÑ" Ñак как в babelfish они имеÑÑ Ð²Ð¸Ð´ params.key.subkey  | 
| 
152
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
37
 | 
         if ( defined($params) ) {  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # пеÑеданнÑй ÑкалÑÑ Ð¿ÑевÑаÑаем в Ñ
ÑÑ { count, value }.  | 
| 
154
 | 
16
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
40
 | 
             if ( ref($params) eq '' ) {  | 
| 
155
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
                 $flat_params = {  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     count => $params,  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     value => $params,  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 };  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             else {  | 
| 
161
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
                 _flat_hash_keys( $params, '', $flat_params );  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
165
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
380
 | 
         return $r->( $flat_params );  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
167
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     return $r;  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub t {  | 
| 
172
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
  
1
  
 | 
474
 | 
     my $self = shift;  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
174
 | 
22
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
53
 | 
     return $self->t_or_undef( @_ ) || "[$_[0]]";  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub has_any_value {  | 
| 
179
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
4
 | 
     my ( $self, $dictname_key, $custom_locale ) = @_;  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # запÑеÑаем клÑÑи не ASCII  | 
| 
182
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     confess("wrong dictname_key: $dictname_key")  if $dictname_key =~ m/\P{ASCII}/;  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
184
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my $locale = $custom_locale ? $self->detect_locale( $custom_locale ) : $self->{locale};  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
186
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     return 1  if $self->{dictionaries}->{$locale}->{$dictname_key};  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     $self->{fallback_cache}->{$locale} //= {};  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return ( ( defined $self->{fallback_cache}->{$locale}->{$dictname_key} ) ? 1 : 0 )  | 
| 
190
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if exists $self->{fallback_cache}->{$locale}->{$dictname_key};  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
192
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     my @fallback_locales = @{ $self->{fallbacks}->{$locale} // [] };  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
193
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     for ( @fallback_locales ) {  | 
| 
194
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         return 1  if defined $self->{dictionaries}->{$_}->{$dictname_key};  | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub load_dictionaries {  | 
| 
201
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
2
 | 
     my $self = shift;  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
203
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
     for my $dir ( @{$self->dirs} ) {  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
204
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
         my $fdir = File::Spec->rel2abs( $dir );  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         find( {  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             follow   => 1,  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             no_chdir => 1,  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             wanted   => sub {  | 
| 
209
 | 
14
 | 
 
 | 
 
 | 
  
14
  
 | 
 
 | 
333
 | 
                 my $file = File::Spec->rel2abs( $File::Find::name );  | 
| 
210
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
419
 | 
                 return unless -f $file;  | 
| 
211
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75
 | 
                 my ( $volume, $directories, $base ) = File::Spec->splitpath( $file );  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
213
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
                 my @tmp = split m/\./, $base;  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
                 my $cur_suffix = pop @tmp;  | 
| 
216
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
140
 | 
                 return unless $cur_suffix eq $self->suffix;  | 
| 
217
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
                 my $lang = pop @tmp;  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
219
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
                 pop @tmp  if $tmp[-1] eq 'tt'; # ÑловаÑи вида formatting.tt.ru_RU.yaml - имеÑÑ Ð¸Ð¼Ñ formatting  | 
| 
220
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
13
 | 
                 if ( $tmp[-1] eq 'js') {  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # ÑловаÑи .js пеÑекÑÑваÑÑ Ð¾Ð´Ð½Ð¾Ð¸Ð¼ÑннÑе ÑловаÑи без ÑÑÑÑикÑа  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # еÑли ÑÑо нежелаÑелÑное поведение - ÑловаÑÑ Ñ ÑÑÑÑикÑом .tt пеÑекÑÐ¾ÐµÑ Ð¾Ð´Ð½Ð¾Ð¸Ð¼ÑннÑй .js, и бÑÐ´ÐµÑ Ð´Ð¾ÑÑÑпен ÑолÑко на ÑеÑвеÑе  | 
| 
223
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     pop @tmp; # ÑловаÑи вида formatting.js.ru_RU.yaml - имеÑÑ Ð¸Ð¼Ñ formatting  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # и не загÑÑжаÑÑÑÑ, еÑли еÑÑÑ Ð°Ð½Ð°Ð»Ð¾Ð³Ð¸ÑнÑй tt.  | 
| 
225
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     return  if -f File::Spec->catpath( $volume, $directories, join('.', @tmp). ".tt.$lang.$cur_suffix" );  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
227
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
                 my $dictname = join('.', @tmp);  | 
| 
228
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
                 my $subdir = File::Spec->catpath( $volume, $directories, '' );  | 
| 
229
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
55
 | 
                 if ( $subdir =~ m/\A\Q$fdir\E[\\\/](.+)\z/ ) {  | 
| 
230
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
                     $dictname = "$1$dictname";  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
                 $self->load_dictionary($dictname, $lang, $file);  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             },  | 
| 
235
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
         }, $dir );  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
237
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     $self->prepare_to_compile;  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub load_dictionary {  | 
| 
242
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
17
 | 
     my ( $self, $dictname, $lang, $file ) = @_;  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
244
 | 
8
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
117
 | 
     $self->dictionaries->{$lang} //= {};  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
     my $yaml = load_yaml( $file );  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
248
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9119
 | 
     _flat_hash_keys( $yaml, "$dictname.", $self->dictionaries->{$lang} );  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
250
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
151
 | 
     return  unless $self->watch;  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
252
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->watchers->{$file} = (stat($file))[MTIME_INDEX];  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub phrase_need_compilation {  | 
| 
257
 | 
21
 | 
 
 | 
 
 | 
  
21
  
 | 
  
1
  
 | 
29
 | 
     my ( undef, $phrase, $key ) = @_;  | 
| 
258
 | 
21
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     die "L10N: $key is undef"  unless defined $phrase;  | 
| 
259
 | 
21
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
89
 | 
     return 1  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         && ref($phrase) eq ''  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         && $phrase =~ m/ (?: \(\( | \#\{ | \\\\ )/x  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ;  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub prepare_to_compile {  | 
| 
268
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
3
 | 
     my ( $self ) = @_;  | 
| 
269
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     while ( my ($lang, $dic) = each(%{ $self->{dictionaries} }) ) {  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
270
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         while ( my ($key, $value) = each(%$dic) ) {  | 
| 
271
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
33
 | 
             if ( $self->phrase_need_compilation( $value, $key ) ) {  | 
| 
272
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
                 $dic->{$key} = \$value; # оÑÐ»Ð¾Ð¶ÐµÐ½Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð¸Ð»ÑÑÐ¸Ñ  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 #my $ast = $parser->parse($value, $lang);  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 #$dic->{$key} = $compiler->compile( $ast );  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
278
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     return 1;  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub detect_locale {  | 
| 
283
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
9
 | 
     my ( $self, $locale ) = @_;  | 
| 
284
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
76
 | 
     return $locale  if $self->dictionaries->{$locale};  | 
| 
285
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     my @alt_locales = grep { $_ =~ m/\A\Q$locale\E[\-_]/i } keys %{ $self->dictionaries };  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
286
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     confess "only one alternative locale allowed: ", join ',', @alt_locales  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if @alt_locales > 1;  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
289
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
     my $alt_locale = $alt_locales[0];  | 
| 
290
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
19
 | 
     if ( $alt_locale && $self->dictionaries->{$alt_locale} ) {  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Ñделаем locale dictionary ÑÑÑлкой на alt locale dictinary.  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # ÑÑо ÑÑкоÑÐ¸Ñ ÑабоÑÑ Ð²ÑеÑ
 t Ñ Ñказанием ÑзÑка Ñипа "ru" вмеÑÑо локали "ru_RU".  | 
| 
293
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         $self->dictionaries->{$locale} = $self->dictionaries->{$alt_locale};  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->fallback_cache->{$locale} = $self->fallback_cache->{$alt_locale}  | 
| 
296
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
             if exists $self->fallback_cache->{$alt_locale};  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->fallbacks->{$locale} = $self->fallbacks->{$alt_locale}  | 
| 
299
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
             if exists $self->fallbacks->{$alt_locale};  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
301
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
         return $locale;  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
303
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $self->{default_locale}  if $self->dictionaries->{ $self->{default_locale} };  | 
| 
304
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     confess "bad locale: $locale and bad default_locale: $self->{default_locale}.";  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub set_fallback {  | 
| 
309
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
6
 | 
     my ( $self, $locale, @fallback_locales ) = @_;  | 
| 
310
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     return  unless scalar( @fallback_locales );  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
312
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     $locale = $self->detect_locale( $locale );  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
314
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
9
 | 
     @fallback_locales = @{ $fallback_locales[0] }  if 1  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         && scalar( @fallback_locales ) == 1  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         && ref( $fallback_locales[0] ) eq 'ARRAY'  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ;  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     $self->fallbacks->{ $locale } = \@fallback_locales;  | 
| 
320
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     delete $self->{fallback_cache}->{ $locale };  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
322
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     return 1;  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _flat_hash_keys {  | 
| 
327
 | 
29
 | 
 
 | 
 
 | 
  
29
  
 | 
 
 | 
86
 | 
     my ( $hash, $prefix, $store ) = @_;  | 
| 
328
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
109
 | 
     while ( my ($key, $value) = each(%$hash) ) {  | 
| 
329
 | 
46
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
95
 | 
         if (ref($value) eq 'HASH') {  | 
| 
330
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
             _flat_hash_keys( $value, "$prefix$key.", $store );  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
332
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
134
 | 
             $store->{"$prefix$key"} = $value;  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
335
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
     return 1;  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =pod  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =encoding utf-8  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Locale::Babelfish - Perl I18n using https://github.com/nodeca/babelfish format.  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 VERSION  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 version 2.003  | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐиблиоÑека локализаÑии.  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Locale::Babelfish  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSYS  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     package Foo;  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use Locale::Babelfish ();  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $bf = Locale::Babelfish->new( { dirs => [ '/path/to/dictionaries' ] } );  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print $bf->t('dictionary.firstkey.nextkey', { foo => 'bar' } );  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 More sophisticated example:  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     package Foo::Bar;  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     use Locale::Babelfish ();  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $bf = Locale::Babelfish->new( {  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # configuration  | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         dirs         => [ '/path/to/dictionaries' ],  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         default_locale => [ 'ru_RU' ], # By default en_US  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } );  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # using default locale  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print $bf->t( 'dictionary.akey' );  | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print $bf->t( 'dictionary.firstkey.nextkey', { foo => 'bar' } );  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # using specified locale  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print $bf->t( 'dictionary.firstkey.nextkey', { foo => 'bar' }, 'by_BY' );  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # using scalar as count or value variable  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print $bf->t( 'dictionary.firstkey.nextkey', 90 );  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # same as  | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print $bf->t( 'dictionary.firstkey.nextkey', { count => 90, value => 90 } );  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # set locale  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $bf->locale( 'en_US' );  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print $bf->t( 'dictionary.firstkey.nextkey', { foo => 'bar' } );  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Get current locale  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     print $bf->locale;  | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DICTIONARIES  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Phrases Syntax  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #{varname} Echoes value of variable  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ((Singular|Plural1|Plural2)):variable Plural form  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ((Singular|Plural1|Plural2)) Short plural form for "count" variable  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Example:  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     I have #{nails_count} ((nail|nails)):nails_count  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 or short form  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     I have #{count} ((nail|nails))  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 or with zero and onÑ plural forms:  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     I have ((=0 no nails|=1 a nail|#{nails_count} nail|#{nails_count} nails)):nails_count  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Dictionary file example  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Module support only YAML format. Create dictionary file like: B<dictionary.en_US.yaml> where  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C<dictionary> is name of dictionary and C<en_US> - its locale.  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     profile:  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         apps:  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             forums:  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 new_topic: New topic  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 last_post:  | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     title : Last message  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     demo:  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         apples: I have #{count} ((apple|apples))  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DETAILS  | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 СловаÑи гÑÑзÑÑÑÑ Ð¿Ñи Ñоздании ÑкземплÑÑа, ÑÑÐ°Ð·Ñ Ð² плоÑкой ÑоÑме  | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $self->{dictionaries}->{ru_RU}->{dictname_key}...  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐÑиÑем вÑе ÑкалÑÑнÑе знаÑениÑ, пÑи необÑ
одимоÑÑи (еÑÑÑ ÑпеÑÑÐ¸Ð¼Ð²Ð¾Ð»Ñ Babelfish),  | 
| 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 пÑеобÑазÑÑÑÑÑ Ð² ÑÑÑлки на ÑкалÑÑÑ (Ñлаг - "нÑжно ÑкомпилиÑоваÑÑ").  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐеÑод t_or_undef полÑÑÐ°ÐµÑ Ð·Ð½Ð°Ñение по ÑÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð¼Ñ ÐºÐ»ÑÑÑ.  | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐÑли ÑÑо ÑÑÑлка на ÑкалÑÑ, Ñо паÑÑÐ¸Ñ Ð¸ компилиÑÑÐµÑ ÑÑÑокÑ.  | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 РезÑлÑÑÐ°Ñ ÐºÐ¾Ð¼Ð¿Ð¸Ð»ÑÑии либо ÑÑÑлка на подпÑогÑаммÑ, лмбо пÑоÑÑо ÑÑÑока.  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐÑли ÑÑо ÑÑÑлка на подпÑогÑаммÑ, Ð¼Ñ Ð¿ÑоÑÑо вÑзÑваем ее Ñ Ð¿Ð»Ð¾Ñкими паÑамеÑÑами.  | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐÑли пÑоÑÑо ÑÑÑока, Ñо возвÑаÑаем ÐµÑ as is.  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐоддеÑживаеÑÑÑ Ð¾Ð±ÑÐ¸Ñ watch.  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 METHODS  | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item locale  | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐÑли Ñказана локалÑ, ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²ÐµÑ ÐµÑ. ÐÑли Ð½ÐµÑ - возвÑаÑаеÑ.  | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item on_watcher_change  | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐеÑеÑиÑÑÐ²Ð°ÐµÑ Ð²Ñе ÑловаÑи.  | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item look_for_watchers  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐбновлÑÐµÑ ÑловаÑи оп меÑе необÑ
одимоÑÑи, ÑеÑез L</on_watcher_change>.  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item t_or_undef  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->t_or_undef( 'main.key.subkey' , { paaram1 => 1 , param2 => 'test' } , 'ru' );  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐокализаÑÐ¸Ñ Ð¿Ð¾ клÑÑÑ.  | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 пеÑвой ÑаÑÑÑÑ Ð² клÑÑе $key должен идÑи ÑловаÑÑ, напÑимеÑ, main.key  | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 паÑамеÑÑ ÑзÑка не обÑзаÑелÑнÑй.  | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $params - Ñ
ÑÑ Ð¿Ð°ÑамеÑÑов  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item t  | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
486
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->t( 'main.key.subkey' , { paaram1 => 1 , param2 => 'test' } , 'ru' );  | 
| 
487
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐокализаÑÐ¸Ñ Ð¿Ð¾ клÑÑÑ.  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 пеÑвой ÑаÑÑÑÑ Ð² клÑÑе $key должен идÑи ÑловаÑÑ, напÑимеÑ, main.key  | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 паÑамеÑÑ ÑзÑка не обÑзаÑелÑнÑй.  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $params - Ñ
ÑÑ Ð¿Ð°ÑамеÑÑов  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
495
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item has_any_value  | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->has_any_value( 'main.key.subkey' );  | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐÑовеÑÑÐµÑ ÐµÑÑÑ Ð»Ð¸ клÑÑ Ð² ÑловаÑе  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 пеÑвой ÑаÑÑÑÑ Ð² клÑÑе должен идÑи ÑловаÑÑ, напÑимеÑ, main.  | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item load_dictionaries  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐагÑÑÐ¶Ð°ÐµÑ Ð²Ñе yaml ÑловаÑи Ñ Ð´Ð¸Ñка  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item load_dictionary  | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐагÑÑÐ¶Ð°ÐµÑ Ð¾Ð´Ð¸Ð½ yaml ÑловаÑÑ Ñ Ð´Ð¸Ñка  | 
| 
510
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item phrase_need_compilation  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->phrase_need_compilation( $phrase, $key )  | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $class->phrase_need_compilation( $phrase, $key )  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐпÑеделÑеÑ, ÑÑебÑеÑÑÑ Ð»Ð¸ компилÑÑÐ¸Ñ ÑÑазÑ.  | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐÑполÑзÑеÑÑÑ Ñакже пÑи компилÑÑии плÑÑалов (вложеннÑе вÑÑажениÑ).  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item prepare_to_compile  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->prepare_to_compile()  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Ðибо маÑкиÑÑÐµÑ ÐºÐ°Ðº refscalar ÑÑÑоки в ÑловаÑÑÑ
, ÑÑебÑÑÑие компилÑÑии,  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 либо пÑоÑÑо компилиÑÑÐµÑ Ð¸Ñ
.  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item detect_locale  | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->detect_locale( $locale );  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐпÑеделÑем какой ÑзÑк бÑÐ´ÐµÑ Ð¸ÑполÑзован.  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 пÑиоÑиÑÐµÑ $locale, далее default_locale.  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item set_fallback  | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->set_fallback( 'by_BY', 'ru_RU', 'en_US');  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->set_fallback( 'by_BY', [ 'ru_RU', 'en_US' ] );  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐÐ»Ñ Ñказанной локали ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑпиÑок локалей, на коÑоÑÑе бÑÐ´ÐµÑ Ð¿ÑоизводиÑÑÑ Ð¾ÑÐºÐ°Ñ  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 в ÑлÑÑае оÑÑÑÑÑÑÐ²Ð¸Ñ ÑÑÐ°Ð·Ñ Ð² Ñказанной.  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐапÑимеÑ, в вÑÑеÑказаннÑÑ
 пÑимеÑаÑ
 пÑи оÑÑÑÑÑÑвии ÑÑÐ°Ð·Ñ Ð²  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 белоÑÑÑÑкой локали бÑÐ´ÐµÑ Ð·Ð°Ñем иÑкаÑÑÑÑ ÑÑаза в ÑÑÑÑкой локали,  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 заÑем в англоамеÑиканÑкой.  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item _flat_hash_keys  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _flat_hash_keys( $hash, '', $result );  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐнÑÑÑеннÑÑ, ÑекÑÑÑивнаÑ.  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ÐÑеобÑазÑÐµÑ Ñ
ÑÑ Ð»Ñбой вложенноÑÑи в ÑÑÑокÑ, где клÑÑи Ñ
еÑей ÑÐ°Ð·Ð´ÐµÐ»ÐµÐ½Ñ ÑоÑками.  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHORS  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
557
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over 4  | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
559
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Akzhan Abdulin <akzhan@cpan.org>  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Igor Mironov <grif@cpan.org>  | 
| 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Victor Efimov <efimov@reg.ru>  | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item *  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 REG.RU LLC  | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT AND LICENSE  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This software is Copyright (c) 2014 by REG.RU LLC.  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is free software, licensed under:  | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   The MIT (X11) License  | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  |