line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package File::Find::ProjectCycleMigration;
|
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
26096
|
use 5.008004;
|
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
42
|
|
4
|
1
|
|
|
1
|
|
7
|
use strict;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
172
|
|
5
|
1
|
|
|
1
|
|
8
|
use File::Find;
|
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
96
|
|
6
|
1
|
|
|
1
|
|
6
|
use File::Path;
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
62
|
|
7
|
1
|
|
|
1
|
|
1086
|
use File::Copy;
|
|
1
|
|
|
|
|
6319
|
|
|
1
|
|
|
|
|
93
|
|
8
|
1
|
|
|
1
|
|
10
|
use File::Spec;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
9
|
1
|
|
|
1
|
|
1351
|
use Data::Dumper;
|
|
1
|
|
|
|
|
9235
|
|
|
1
|
|
|
|
|
102
|
|
10
|
1
|
|
|
1
|
|
984
|
use Time::Local;
|
|
1
|
|
|
|
|
2036
|
|
|
1
|
|
|
|
|
3324
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
require Exporter;
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
our @ISA = qw(Exporter);
|
15
|
|
|
|
|
|
|
our @EXPORT = qw(FindReplace);
|
16
|
|
|
|
|
|
|
our $VERSION = '0.01';
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
sub FindReplace{
|
19
|
0
|
|
|
0
|
0
|
|
my $config = shift;
|
20
|
0
|
|
|
|
|
|
my ($cycle_year,$srcdir) = ($config->{year}, $config->{srcdir});
|
21
|
0
|
0
|
0
|
|
|
|
unless(($cycle_year =~/^\d\d\d\d$/) || (-d $srcdir)){
|
22
|
0
|
|
|
|
|
|
separator(80,'*');
|
23
|
0
|
0
|
|
|
|
|
unless(($cycle_year =~/^\d\d\d\d$/))
|
24
|
|
|
|
|
|
|
{
|
25
|
0
|
|
|
|
|
|
textFormat(80, "Please enter correct year the given year must be a 4 digit numeric number.\n");
|
26
|
|
|
|
|
|
|
}
|
27
|
0
|
0
|
|
|
|
|
unless(-d $srcdir){
|
28
|
0
|
|
|
|
|
|
textFormat(80,"The given path does not exist please give absolute path.");
|
29
|
|
|
|
|
|
|
}
|
30
|
0
|
|
|
|
|
|
separator(80,'*');
|
31
|
0
|
|
|
|
|
|
die &Usage;
|
32
|
|
|
|
|
|
|
}
|
33
|
0
|
|
|
|
|
|
my $nextyear = $cycle_year + 1;
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# The directory to be search on.
|
36
|
0
|
|
|
|
|
|
my @directories = File::Spec->splitdir($srcdir);
|
37
|
0
|
|
|
|
|
|
my $lastpath = pop @directories; # Get the last directory to be search on
|
38
|
0
|
0
|
|
|
|
|
$lastpath = pop @directories if $lastpath eq ''; # If the user gave a / at end of the path then we need to pop twice to skip the ''
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# Creating the absolute path for the directory to be search on.
|
41
|
0
|
|
|
|
|
|
my $folderPath = File::Spec->catdir( @directories, $lastpath );
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# Creeating the backup directory .
|
44
|
0
|
|
|
|
|
|
my $backupFolderPath = File::Spec->catdir( @directories, $lastpath . '_bkp' );
|
45
|
0
|
|
|
|
|
|
my $logFilePath = File::Spec->catdir( @directories, $lastpath . '_log' );
|
46
|
|
|
|
|
|
|
|
47
|
0
|
|
|
|
|
|
my $grepregex = '[a-zA-Z]+' . $cycle_year . '[^a-zA-Z0-9\_\,]'; #Creating a regex for searching the pattern ie. the year (we can customized it as per the requirement)
|
48
|
0
|
|
|
|
|
|
my $grepoutput = `egrep -rhn '$grepregex' $folderPath`; # egrep should be quicker than going file by file and looking for patterns in file using perl only.
|
49
|
0
|
|
|
|
|
|
my @op = ( $grepoutput =~ /([a-zA-Z]{4,}$cycle_year)[\/\:-]/g ); # We got the patterns that look like stuff we need to replace along with stupid stuff that egrep tries to churn out.
|
50
|
0
|
|
|
|
|
|
my %findReplaceH;
|
51
|
0
|
|
|
|
|
|
foreach my $string (@op) { # We build a hash to make things easier and removes the duplicate keys ie. search pattern.
|
52
|
0
|
|
|
|
|
|
my $replacementstring = $string;
|
53
|
0
|
|
|
|
|
|
$replacementstring =~ s/$cycle_year/$nextyear/;
|
54
|
0
|
0
|
|
|
|
|
$findReplaceH{$string} = $replacementstring if ( $string =~ /[a-zA-Z]{4,}$cycle_year/ ); # Replace when there are at least 4 more alphanumeric char associated with year.
|
55
|
|
|
|
|
|
|
}
|
56
|
0
|
|
|
|
|
|
$findReplaceH{$cycle_year} = $nextyear;
|
57
|
0
|
0
|
|
|
|
|
mkdir $logFilePath unless(-e $logFilePath);
|
58
|
|
|
|
|
|
|
|
59
|
0
|
|
|
|
|
|
my $logFile = "$logFilePath/FindReplace.log";
|
60
|
0
|
0
|
|
|
|
|
open( FILE, ">>$logFile" ) || die "cann't open the $!\n";
|
61
|
0
|
|
|
|
|
|
my ( $seconds, $minutes, $hours, $day_of_month, $month, $year, $wday, $yday, $isdst ) = gmtime(time);
|
62
|
0
|
|
|
|
|
|
$year = $year + 1900;
|
63
|
0
|
|
|
|
|
|
$month = $month + 1;
|
64
|
0
|
|
|
|
|
|
my $date_string = "$hours:$minutes:$seconds - $day_of_month/$month/$year";
|
65
|
0
|
|
|
|
|
|
print FILE "Here we are going to keep logs - TIME : $date_string\n";
|
66
|
0
|
|
|
|
|
|
close FILE;
|
67
|
|
|
|
|
|
|
|
68
|
0
|
|
|
|
|
|
my $input;
|
69
|
0
|
|
0
|
|
|
|
while ((lc($input) ne 'yes' ) && ( scalar(keys%findReplaceH))) {
|
70
|
0
|
|
|
|
|
|
separator(80,'*');
|
71
|
0
|
|
|
|
|
|
textFormat(80, "Replacement List-");print "\n";
|
|
0
|
|
|
|
|
|
|
72
|
0
|
|
|
|
|
|
textFormat(80, "Right side values are the possible replacement of Left side pattern(given year associated with some alphanumeric characters) find in the directory and sub dir-ectory So possible replacements are-");
|
73
|
0
|
|
|
|
|
|
print "\n";
|
74
|
0
|
|
|
|
|
|
while(my($key,$val)=(each %findReplaceH)){
|
75
|
0
|
|
|
|
|
|
printf ("%35s",$key); print " => " ; printf("%-50s", $val); print "\n" ;
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
}
|
77
|
0
|
|
|
|
|
|
separator(80,'*');
|
78
|
0
|
|
|
|
|
|
textFormat(150, "Current Config Settings-");print "\n";
|
|
0
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
|
textFormat(80, "'Current Directory' is the directory where script starts search operation for replacement also script automatically backs up the current code in 'Back-up Dir-ectory' and for logs it creates a 'Log Directory' at one level above the 'Current Directory'");
|
80
|
0
|
|
|
|
|
|
print "\n";
|
81
|
0
|
|
|
|
|
|
textFormat(150, "Current Directory : $folderPath");
|
82
|
0
|
|
|
|
|
|
textFormat(150, "Back-up Directory : $backupFolderPath");
|
83
|
0
|
|
|
|
|
|
textFormat(150, "Log Directory \t : $logFile");
|
84
|
0
|
|
|
|
|
|
separator(80,'*');
|
85
|
0
|
|
|
|
|
|
textFormat(80, "README-");
|
86
|
0
|
|
|
|
|
|
textFormat(80,"i. If you want to proceed with above Replacement List/Current Config Settings then type YES otherwise NO to quit ...");
|
87
|
0
|
|
|
|
|
|
textFormat(80,"ii. If you want to remove any key => value pair from Replacement List then type the key(Case Sensitive) on terminal. e.g. type key name (left side element) 'foo2011' to remove key-value pair from 'Replacement List'- 'foo2011 => foo2012'");
|
88
|
0
|
|
|
|
|
|
print "\t";
|
89
|
0
|
|
|
|
|
|
$input = ;
|
90
|
0
|
|
|
|
|
|
$input =~ s/^\s+|\s+$//g;
|
91
|
|
|
|
|
|
|
|
92
|
0
|
0
|
|
|
|
|
if ( $input =~ /^yes$/i ) {
|
|
|
0
|
|
|
|
|
|
93
|
0
|
|
|
|
|
|
textFormat(80,"Here we go with current Replacement List/Config Settings...");
|
94
|
|
|
|
|
|
|
}
|
95
|
|
|
|
|
|
|
elsif ( $input =~ /^no$/i ) {
|
96
|
0
|
|
|
|
|
|
textFormat(80,"Please check your Current Config Settings in the script.");
|
97
|
0
|
|
|
|
|
|
separator(80, '*');
|
98
|
0
|
|
|
|
|
|
exit;
|
99
|
|
|
|
|
|
|
}
|
100
|
|
|
|
|
|
|
else{
|
101
|
0
|
|
|
|
|
|
$input =~ s/^\s|\s+$//g;
|
102
|
0
|
0
|
|
|
|
|
unless(grep $_ eq $input, keys%findReplaceH){
|
103
|
0
|
|
|
|
|
|
textFormat(80,"Please pass only YES/NO option or a valid key name from Replacement List to remove key-value pair from search result.");
|
104
|
|
|
|
|
|
|
}
|
105
|
0
|
|
|
|
|
|
delete( $findReplaceH{$input} );
|
106
|
|
|
|
|
|
|
}
|
107
|
|
|
|
|
|
|
}
|
108
|
0
|
0
|
|
|
|
|
if(scalar(keys%findReplaceH) == 0){
|
109
|
0
|
|
|
|
|
|
textFormat(80,"No search result found for the given year.");
|
110
|
0
|
|
|
|
|
|
separator(80, '*');
|
111
|
0
|
|
|
|
|
|
exit;
|
112
|
|
|
|
|
|
|
}
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# This closure will rename all directory recursively as per given in hash keys/values
|
115
|
|
|
|
|
|
|
finddepth(
|
116
|
|
|
|
|
|
|
sub {
|
117
|
0
|
0
|
|
0
|
|
|
return unless -d;
|
118
|
0
|
0
|
0
|
|
|
|
return if ( $_ eq '.' || $_ eq '..' );
|
119
|
0
|
0
|
|
|
|
|
return if ( $_ =~ /.svn|\.svn/ );
|
120
|
0
|
|
|
|
|
|
my $new = $_;
|
121
|
0
|
|
|
|
|
|
foreach my $key1 ( keys %findReplaceH ) {
|
122
|
0
|
|
|
|
|
|
my $pattern = quotemeta($key1);
|
123
|
0
|
0
|
|
|
|
|
if ( $new =~ /$pattern/ ) {
|
124
|
0
|
|
|
|
|
|
$new =~ s/$pattern/$findReplaceH{$key1}/;
|
125
|
|
|
|
|
|
|
}
|
126
|
|
|
|
|
|
|
}
|
127
|
0
|
0
|
|
|
|
|
if ( $_ eq $new ) {
|
128
|
0
|
|
|
|
|
|
return;
|
129
|
|
|
|
|
|
|
}
|
130
|
0
|
|
|
|
|
|
my $currentDir = $File::Find::dir;
|
131
|
0
|
|
|
|
|
|
$currentDir .= "/" . $_;
|
132
|
0
|
|
|
|
|
|
my $renamedDir = $File::Find::dir;
|
133
|
0
|
|
|
|
|
|
$renamedDir .= "/" . $new;
|
134
|
|
|
|
|
|
|
|
135
|
0
|
0
|
|
|
|
|
rename $_, $new or warn "Error while renaming $_ to $new in $File::Find::dir: $!";
|
136
|
0
|
0
|
|
|
|
|
open( FILE, ">>$logFile" ) || die "cann't open the $!\n";
|
137
|
0
|
|
|
|
|
|
print FILE "Current Directory: $currentDir :: Renamed Directory: $renamedDir\n";
|
138
|
0
|
|
|
|
|
|
close FILE;
|
139
|
0
|
|
|
|
|
|
}, $folderPath
|
140
|
|
|
|
|
|
|
);
|
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# $useRegexQ has values 1 or 0. If 1, interprets the pairs in %findReplaceH to be regex.
|
143
|
0
|
|
|
|
|
|
my $useRegexQ = 0;
|
144
|
0
|
|
|
|
|
|
$folderPath =~ s/\/$//;
|
145
|
0
|
|
|
|
|
|
$backupFolderPath =~ s/\/$//;
|
146
|
0
|
|
|
|
|
|
$folderPath =~ m/\/(\w+)$/;
|
147
|
0
|
|
|
|
|
|
my $previousDir = $`;
|
148
|
0
|
|
|
|
|
|
my $lastDir = $1;
|
149
|
0
|
|
|
|
|
|
my $backupRoot = $backupFolderPath . '/' . $1;
|
150
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
|
my $refchangedFiles = [];
|
152
|
0
|
|
|
|
|
|
my $totalFileChangedCount = 0;
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub fileFilterQ ($) {
|
155
|
0
|
|
|
0
|
0
|
|
my $fileName = $_[0];
|
156
|
0
|
0
|
|
|
|
|
next if ( $fileName =~ /(svn|\.svn)/ig );
|
157
|
|
|
|
|
|
|
|
158
|
0
|
0
|
|
|
|
|
if ( -f $fileName ) {
|
159
|
|
|
|
|
|
|
#print "processing files: $fileName\n";
|
160
|
0
|
|
|
|
|
|
return 1;
|
161
|
|
|
|
|
|
|
}
|
162
|
|
|
|
|
|
|
}
|
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# go through each file, accumulate a hash.
|
165
|
|
|
|
|
|
|
sub processFile {
|
166
|
0
|
|
|
0
|
0
|
|
my $currentFile = $File::Find::name;
|
167
|
0
|
|
|
|
|
|
my $currentDir = $File::Find::dir;
|
168
|
0
|
|
|
|
|
|
my $previousDir = $`;
|
169
|
0
|
|
|
|
|
|
my $lastDir = $1;
|
170
|
0
|
|
|
|
|
|
my $currentFileName = $_;
|
171
|
0
|
0
|
|
|
|
|
if ( not fileFilterQ($currentFile) ) {
|
172
|
|
|
|
|
|
|
# fileFilterQ It returns true in case of file, false in case of dir, not a text file.
|
173
|
0
|
|
|
|
|
|
return 1;
|
174
|
|
|
|
|
|
|
}
|
175
|
|
|
|
|
|
|
# open file. Read in the whole file.
|
176
|
0
|
0
|
|
|
|
|
if( not( open FILE, "<$currentFile" ) ) {
|
177
|
0
|
|
|
|
|
|
die("Error opening file: $!");
|
178
|
|
|
|
|
|
|
}
|
179
|
0
|
|
|
|
|
|
my $wholeFileString;
|
180
|
0
|
|
|
|
|
|
{ local $/ = undef; $wholeFileString = ; };
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
181
|
0
|
0
|
|
|
|
|
if ( not( close(FILE) ) ) { die("Error closing file: $!"); }
|
|
0
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
# do the replacement.
|
184
|
0
|
|
|
|
|
|
my $replaceCount = 0;
|
185
|
0
|
|
|
|
|
|
foreach my $key1 ( keys %findReplaceH ) {
|
186
|
0
|
0
|
|
|
|
|
my $pattern = ( $useRegexQ ? $key1 : quotemeta($key1) );
|
187
|
0
|
|
|
|
|
|
$replaceCount = $replaceCount + ( $wholeFileString =~ s/$pattern/$findReplaceH{$key1}/g );
|
188
|
|
|
|
|
|
|
}
|
189
|
0
|
0
|
|
|
|
|
if ( $replaceCount > 0 ) { # replacement has happened
|
190
|
0
|
|
|
|
|
|
push( @$refchangedFiles, $currentFile );
|
191
|
0
|
|
|
|
|
|
$totalFileChangedCount++;
|
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
# do backup make a directory in the backup path, make a backup copy.
|
194
|
0
|
|
|
|
|
|
my $pathAdd = $currentDir;
|
195
|
0
|
|
|
|
|
|
$pathAdd =~ s[$folderPath][];
|
196
|
0
|
|
|
|
|
|
mkpath( "$backupRoot/$pathAdd", 0, 0777 );
|
197
|
0
|
0
|
|
|
|
|
copy( $currentFile, "$backupRoot/$pathAdd/$currentFileName" ) or die "error: file copying file failed on $currentFile\n$!";
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
# write to the original and get the file mode.
|
200
|
0
|
|
|
|
|
|
my ( $mode, $uid, $gid ) = ( stat($currentFile) )[ 2, 4, 5 ];
|
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# write out a new file.
|
203
|
0
|
0
|
|
|
|
|
if ( not( open OUTFILE, ">$currentFile" ) ) { die("Error opening file: $!"); }
|
|
0
|
|
|
|
|
|
|
204
|
0
|
|
|
|
|
|
print OUTFILE $wholeFileString;
|
205
|
0
|
0
|
|
|
|
|
if ( not( close(OUTFILE) ) ) { die("Error closing file: $!"); }
|
|
0
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# set the file mode.
|
208
|
0
|
|
|
|
|
|
chmod( $mode, $currentFile );
|
209
|
0
|
|
|
|
|
|
chown( $uid, $gid, $currentFile );
|
210
|
|
|
|
|
|
|
|
211
|
0
|
0
|
|
|
|
|
open( FILE, ">>$logFile" ) || die "cann't open the $!\n";
|
212
|
0
|
|
|
|
|
|
print FILE "---------------------------------------------\n";
|
213
|
0
|
|
|
|
|
|
print FILE "$replaceCount replacements made at\n";
|
214
|
0
|
|
|
|
|
|
print FILE "$currentFile\n";
|
215
|
0
|
|
|
|
|
|
close FILE;
|
216
|
|
|
|
|
|
|
}
|
217
|
|
|
|
|
|
|
}
|
218
|
0
|
|
|
|
|
|
find( \&processFile, $folderPath );
|
219
|
0
|
0
|
|
|
|
|
open( FILE, ">>$logFile" ) || die "cann't open the $!\n";
|
220
|
0
|
|
|
|
|
|
print FILE "--------------------------------------------\n";
|
221
|
0
|
|
|
|
|
|
print FILE "Total changed files -> $totalFileChangedCount\n";
|
222
|
|
|
|
|
|
|
|
223
|
0
|
0
|
|
|
|
|
if ( scalar @$refchangedFiles > 0 ) {
|
224
|
0
|
|
|
|
|
|
print FILE "\nFollowing files are changed:\n";
|
225
|
0
|
|
|
|
|
|
print FILE Dumper($refchangedFiles);
|
226
|
|
|
|
|
|
|
}
|
227
|
0
|
|
|
|
|
|
close FILE;
|
228
|
|
|
|
|
|
|
}
|
229
|
|
|
|
|
|
|
sub Usage {
|
230
|
0
|
|
|
0
|
0
|
|
print<<'EOF';
|
231
|
|
|
|
|
|
|
Usage:
|
232
|
|
|
|
|
|
|
#!/usr/bin/perl
|
233
|
|
|
|
|
|
|
use File::Find::ProjectCycleMigration;
|
234
|
|
|
|
|
|
|
my $config = {year=>2011, srcdir=>'/home/uid/foo/project2011'};
|
235
|
|
|
|
|
|
|
FindReplace($config);
|
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
File::Find::ProjectCycleMigration is to convert a project from one cycle to next. The Script scans
|
238
|
|
|
|
|
|
|
the code in provided path and auto generates a list of possible replacements
|
239
|
|
|
|
|
|
|
required for moving the code to the next cycle.
|
240
|
|
|
|
|
|
|
Once you run the script from command line it shows you the list of possible
|
241
|
|
|
|
|
|
|
replacements in your specified folder and prompts you to confirm or selectively
|
242
|
|
|
|
|
|
|
remove some of the auto generated list of replacements. enter a name of a
|
243
|
|
|
|
|
|
|
replacement key to remove it from the list of replacements or type yes or no to
|
244
|
|
|
|
|
|
|
continue or abort.
|
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
--year= replace with 4-digits of current cycle year.
|
247
|
|
|
|
|
|
|
For example if you are moving the code base from 2011 to 2012 cycle
|
248
|
|
|
|
|
|
|
replace with 2011.
|
249
|
|
|
|
|
|
|
Required
|
250
|
|
|
|
|
|
|
--srcdir= replace with the absolute path of the directory where the replacement
|
251
|
|
|
|
|
|
|
should be made. Also script automatically backs up the current code in 'Back-up Directory'
|
252
|
|
|
|
|
|
|
and for logs it creates a 'Log Directory' at one level above the 'Current Directory'.
|
253
|
|
|
|
|
|
|
Required
|
254
|
|
|
|
|
|
|
EOF
|
255
|
|
|
|
|
|
|
}
|
256
|
|
|
|
|
|
|
sub separator{
|
257
|
0
|
|
|
0
|
0
|
|
my ($length, $symbol) = @_;
|
258
|
0
|
|
|
|
|
|
print "\t";foreach(1..$length){print $symbol}; print "\n";
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
}
|
260
|
|
|
|
|
|
|
sub textFormat{
|
261
|
0
|
|
|
0
|
0
|
|
my ($limit, $text) = @_;
|
262
|
0
|
|
|
|
|
|
my $ln = length($text);
|
263
|
0
|
|
|
|
|
|
my $sp=0;
|
264
|
0
|
|
|
|
|
|
while($ln>0){print "\t", (substr($text,$sp, $limit)) . "\n"; $sp += $limit;$ln -=$limit;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
}
|
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
1;
|
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
__END__
|