|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package SPOPS::Tie;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # $Id: Tie.pm,v 3.8 2004/06/02 00:48:22 lachoy Exp $  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
74500
 | 
 use strict;  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1532
 | 
    | 
| 
6
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
112
 | 
 use base  qw( Exporter );  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
108
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3777
 | 
    | 
| 
7
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
119
 | 
 use vars  qw( $PREFIX_TEMP $PREFIX_INTERNAL );  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
58
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1290
 | 
    | 
| 
8
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
3094
 | 
 use Data::Dumper     qw( Dumper );  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13871
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1327
 | 
    | 
| 
9
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
1767
 | 
 use Log::Log4perl    qw( get_logger );  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
71313
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
193
 | 
    | 
| 
10
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
3162
 | 
 use SPOPS::Exception qw( spops_error );  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
204
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 @SPOPS::Tie::EXPORT_OK = qw( IDX_DATA IDX_CHANGE IDX_SAVE IDX_INTERNAL IDX_TEMP  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                              IDX_CHECK_FIELDS IDX_LAZY_LOADED  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                              $PREFIX_TEMP $PREFIX_INTERNAL );  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $SPOPS::Tie::VERSION   = sprintf("%d.%02d", q$Revision: 3.8 $ =~ /(\d+)\.(\d+)/);  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
3933
 | 
 use constant IDX_DATA          => '_dat';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1553
 | 
    | 
| 
18
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
105
 | 
 use constant IDX_CHANGE        => '_chg';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
926
 | 
    | 
| 
19
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
105
 | 
 use constant IDX_SAVE          => '_svd';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
855
 | 
    | 
| 
20
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
106
 | 
 use constant IDX_INTERNAL      => '_int';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
779
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
945
 | 
    | 
| 
21
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
102
 | 
 use constant IDX_TEMP          => '_tmp';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1040
 | 
    | 
| 
22
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
108
 | 
 use constant IDX_IS_LAZY_LOAD  => '_ill';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
894
 | 
    | 
| 
23
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
98
 | 
 use constant IDX_LAZY_LOADED   => '_ll';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1107
 | 
    | 
| 
24
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
100
 | 
 use constant IDX_LAZY_LOAD_SUB => '_lls';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
933
 | 
    | 
| 
25
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
103
 | 
 use constant IDX_CHECK_FIELDS  => '_chk';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
876
 | 
    | 
| 
26
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
101
 | 
 use constant IDX_IS_MULTIVALUE => '_imv';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
819
 | 
    | 
| 
27
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
271
 | 
 use constant IDX_MULTIVALUE    => '_mv';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
851
 | 
    | 
| 
28
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
92
 | 
 use constant IDX_IS_FIELD_MAP  => '_ifm';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
854
 | 
    | 
| 
29
 | 
19
 | 
 
 | 
 
 | 
  
19
  
 | 
 
 | 
95
 | 
 use constant IDX_FIELD_MAP     => '_fm';  | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
    | 
| 
 
 | 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75795
 | 
    | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $log = get_logger();  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $PREFIX_TEMP       = 'tmp_';  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $PREFIX_INTERNAL   = '_internal';  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Tie interface stuff below here; see 'perldoc perltie' for what  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # each method does. (Or better yet, read Damian Conway's discussion  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # of tie in 'Object Oriented Perl'.)  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # First activate the callback for the field check, then return the  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # object. The object always keeps track of the actual properties, the  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # class, whether the object's properties have been changed and keeps  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # any temporary data that lives only for the object's lifetime.  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub TIEHASH {  | 
| 
47
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
     my ( $class, $base_class, $p ) = @_;  | 
| 
48
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
     $p ||= {};  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # See if we're supposed to do any field checking  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $HAS_FIELD = $class->_field_check( $base_class, $p );  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Be able to deal with either an arrayref or a hashref of multivalue fields  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( ref $p->{multivalue} eq 'HASH' ) {  | 
| 
57
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $p->{multivalue} = { map { lc $_ => lc $p->{multivalue}{ $_ } } keys %{ $p->{multivalue} } };  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
60
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( ref $p->{multivalue} eq 'ARRAY' ) {  | 
| 
61
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $p->{multivalue} = { map { lc $_ => 1 } @{ $p->{multivalue} } };  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Be sure all field map fields are lower-cased  | 
| 
65
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( ref $p->{field_map} eq 'HASH' ) {  | 
| 
66
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $p->{field_map} = { map { lc $_ => lc $p->{field_map}{ $_ } } keys %{ $p->{field_map} } };  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return bless ({ class              => $base_class,  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_TEMP()         => {},  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_INTERNAL()     => {},  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_CHANGE()       => 0,  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_SAVE()         => 0,  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_DATA()         => {},  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_IS_LAZY_LOAD() => $p->{is_lazy_load},  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_LAZY_LOADED()  => {},  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_LAZY_LOAD_SUB()=> $p->{lazy_load_sub},  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_IS_MULTIVALUE()=> ( ref $p->{multivalue} eq 'HASH' ),  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_MULTIVALUE()   => $p->{multivalue},  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_IS_FIELD_MAP() => ( ref $p->{field_map} eq 'HASH' ),  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_FIELD_MAP()    => $p->{field_map},  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     IDX_CHECK_FIELDS() => $HAS_FIELD }, $class );  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
85
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 sub _field_check { return undef; }  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
87
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Just go through each of the possible things that could be  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # set and do the appropriate action.  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub FETCH {  | 
| 
91
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
     my ( $self, $key ) = @_;  | 
| 
92
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return unless ( $key );  | 
| 
93
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $cmp_key = lc $key;  | 
| 
94
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $log->is_debug &&  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $log->debug( " tie: Trying to retrieve value for ($key)" );  | 
| 
96
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->{ IDX_CHANGE() }                 if ( $key eq IDX_CHANGE );  | 
| 
97
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->{ IDX_SAVE() }                   if ( $key eq IDX_SAVE );  | 
| 
98
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->{ IDX_TEMP() }{ $cmp_key }     if ( $key =~ /^$PREFIX_TEMP/ );  | 
| 
99
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->{ IDX_INTERNAL() }{ $cmp_key } if ( $key =~ /^$PREFIX_INTERNAL/ );  | 
| 
100
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return undef unless ( $self->_can_fetch( $key ) );  | 
| 
101
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
     if ( $self->{ IDX_IS_FIELD_MAP() } and  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          $self->{ IDX_FIELD_MAP() }{ $cmp_key } ) {  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #warn "(FETCH) using field map: old value ($cmp_key) new ($self->{ IDX_FIELD_MAP() }{ $cmp_key })";  | 
| 
104
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $cmp_key = $self->{ IDX_FIELD_MAP() }{ $cmp_key };  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
106
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
     if ( $self->{ IDX_IS_LAZY_LOAD() } and  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          ! $self->{ IDX_LAZY_LOADED() }{ $cmp_key } ) {  | 
| 
108
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->_lazy_load( $key );  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
110
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
     if ( $self->{ IDX_IS_MULTIVALUE() } and $self->{ IDX_MULTIVALUE() }{ $cmp_key } ) {  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #warn "(FETCH) using multivalue for key $cmp_key";  | 
| 
112
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return [ keys %{ $self->{ IDX_DATA() }{ $cmp_key } } ];  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
114
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->{ IDX_DATA() }{ $cmp_key };  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 sub _can_fetch { return 1 }  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _lazy_load {  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ( $self, $key ) = @_;  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $cmp_key = lc $key;  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unless ( ref $self->{ IDX_LAZY_LOAD_SUB() } eq 'CODE' ) {  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         spops_error "Lazy loading activated but no load function specified!";  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $log->is_info &&  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $log->info( "Lazy loading [$key]; is-loaded marker empty" );  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->{ IDX_DATA() }{ $cmp_key } =   | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     $self->{ IDX_LAZY_LOAD_SUB() }->( $self->{class},  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                                       $self->{ IDX_DATA() },  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                                       $key );  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->{ IDX_LAZY_LOADED() }{ $cmp_key }++;  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Similar to FETCH  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub STORE {  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ( $self, $key, $value ) = @_;  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $cmp_key = lc $key;  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $log->is_debug &&  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $log->debug( " tie: Storing [$key] => [", ( defined $value ) ? $value : 'undef', "]" );  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->{ IDX_CHANGE() } = $value                 if ( $key eq IDX_CHANGE );  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->{ IDX_SAVE() } = $value                   if ( $key eq IDX_SAVE );  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->{ IDX_TEMP() }{ $cmp_key } = $value     if ( $key =~ /^$PREFIX_TEMP/ );  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $self->{ IDX_INTERNAL() }{ $cmp_key } = $value if ( $key =~ /^$PREFIX_INTERNAL/ );  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return undef unless ( $self->_can_store( $key, $value ) );  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->{ IDX_CHANGE() }++;  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( $self->{ IDX_IS_FIELD_MAP() } and   | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          $self->{ IDX_FIELD_MAP() }{ $cmp_key } ) {  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #warn "(STORE) using field map: old value ($cmp_key) new ($self->{ IDX_FIELD_MAP() }{ $cmp_key })";  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $cmp_key = $self->{ IDX_FIELD_MAP() }{ $cmp_key };  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Non-multivalue properties just return the newly stored value  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unless ( $self->{ IDX_IS_MULTIVALUE() } and $self->{ IDX_MULTIVALUE() }{ $cmp_key } ) {  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->{ IDX_IS_LAZY_LOAD() } && $self->{ IDX_LAZY_LOADED() }{ $cmp_key }++;  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return $self->{ IDX_DATA() }{ $cmp_key } = $value;  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #warn "(STORE) using multivalue for key $cmp_key";  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # If we're using multiple values we need to see what type of  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # $value we've got  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # If $value is undef, we clear out all values in the object  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unless ( defined $value ) {  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->{ IDX_DATA() }{ $cmp_key } = {};  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return undef;  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $typeof = ref $value;  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # If a scalar, just set it  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unless ( $typeof ) {  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->{ IDX_DATA() }{ $cmp_key }{ $value } = 1;  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return $value;  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # If array, set it (if the array is empty, then we're  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # resetting the values)  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( $typeof eq 'ARRAY' ) {  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #warn "(STORE) Current value of ($cmp_key)", Dumper( $self->{ IDX_DATA() }{ $cmp_key } ), "";  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->{ IDX_DATA() }{ $cmp_key } = { map { $_ => 1 } @{ $value } };  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #warn "(STORE) Value after set of ($cmp_key)", Dumper( $self->{ IDX_DATA() }{ $cmp_key } ), "";  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return undef;  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
195
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # If hash, go through each of the potential options and  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # perform the action; everything else is ignored  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( $typeof eq 'HASH' ) {  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $remove_fields =  ( ref $value->{remove} eq 'ARRAY' ) ? $value->{remove} : [ $value->{remove} ];  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         foreach my $rmv ( @{ $remove_fields } ) {  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             next unless ( $rmv );  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             delete $self->{ IDX_DATA() }{ $cmp_key }{ $rmv };  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $modify_fields = $value->{modify} || {};  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         foreach my $mdfy ( keys %{ $modify_fields } ) {  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             delete $self->{ IDX_DATA() }{ $cmp_key }{ $mdfy };  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $self->{ IDX_DATA() }{ $cmp_key }{ $modify_fields->{ $mdfy } } = 1  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return undef;  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # We don't know how to handle anything else  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     spops_error "Cannot handle a value type of [$typeof] with multivalues";  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _can_store { return 1 }  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # For EXISTS and DELETE, We can only do these actions on the actual  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # data; use the object methods for the other information.  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub EXISTS {  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ( $self, $key ) = @_;  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $log->is_debug &&  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $log->debug( " tie: Checking for existence of ($key)" );  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return exists $self->{ IDX_DATA() }{ lc $key };  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $log->error( "Field '$key' is not valid, cannot check existence" );  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub DELETE {  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ( $self, $key ) = @_;  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $log->is_debug &&  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $log->debug( " tie: Clearing value for ($key)" );  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     delete $self->{ IDX_DATA() }{ lc $key };  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->{ IDX_CHANGE() }++;  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # We've disabled the ability to do: $object = {} or %{ $object } = ();  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # nothing bad happens, it's just a no-op  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub CLEAR {  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ( $self ) = @_;  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $log->error( "Trying to clear object through hash means failed; use object interface" );  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Note that you only see the data when you cycle through the keys   | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # or even do a Data::Dumper::Dumper( $object ); you do not see  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # the meta-data being tracked. This is a feature.  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub FIRSTKEY {  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ( $self ) = @_;  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $log->is_debug &&  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $log->debug( " tie: Finding first key in data object" );  | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     keys %{ $self->{ IDX_DATA() } };  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $first_key = each %{ $self->{ IDX_DATA() } };  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return undef unless defined $first_key;  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $first_key;  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub NEXTKEY {  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ( $self ) = @_;  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $log->is_debug &&  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $log->debug( " tie: Finding next key in data object" );  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $next_key = each %{ $self->{ IDX_DATA() } };  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return undef unless defined $next_key;  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $next_key;  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |