|
2
|
1 #!/usr/bin/perl -w
|
|
|
2
|
|
|
3 #for a complete list of genes and a list of sites, sorts genes close to sites
|
|
|
4 #printDistance
|
|
|
5
|
|
|
6 #read only gene files with refSeqGenes
|
|
|
7 #counts only once overlapping transcripts or genes
|
|
|
8
|
|
|
9 #calculates some stats about locations of peaks
|
|
|
10
|
|
|
11 use strict;
|
|
|
12
|
|
|
13 my $SitesFilename ;
|
|
|
14 my $SitesFilename2 ="";
|
|
|
15 my $GenesFilename ;
|
|
|
16 my $MirFilename = "";
|
|
|
17 my $BIGNUMBER = 10000000;
|
|
|
18 my $verbose = 0;
|
|
|
19 my $header = 0;
|
|
|
20 my $noXY = 0;
|
|
|
21 my $minscore = 0;
|
|
|
22
|
|
|
23 my $usage = qq{
|
|
|
24 $0
|
|
|
25
|
|
|
26 -----------------------------
|
|
|
27 mandatory parameters:
|
|
|
28
|
|
|
29 -g filename file with all genes
|
|
|
30 -f filename file with sites in BED format
|
|
|
31
|
|
|
32 -----------------------------
|
|
|
33 optional parameters:
|
|
|
34 -v for verbose
|
|
|
35 -minScore minimal score
|
|
|
36 -mir filename file with positions of miRNA
|
|
|
37 -head if there is a header
|
|
|
38 -reg filename file with FoldChanges or expression values and annotation (should in colomn 4)
|
|
|
39 -noXY
|
|
|
40 -o filename output file
|
|
|
41 };
|
|
|
42
|
|
|
43 if(scalar(@ARGV) == 0){
|
|
|
44 print $usage;
|
|
|
45 exit(0);
|
|
|
46 }
|
|
|
47
|
|
|
48 my $ResFilename = "";
|
|
|
49
|
|
|
50 my $regFilename = "";
|
|
|
51
|
|
|
52 while(scalar(@ARGV) > 0){
|
|
|
53 my $this_arg = shift @ARGV;
|
|
|
54 if ( $this_arg eq '-h') {print "$usage\n"; exit; }
|
|
|
55
|
|
|
56 elsif ( $this_arg eq '-g') {$GenesFilename = shift @ARGV;}
|
|
|
57 elsif ( $this_arg eq '-f') {$SitesFilename = shift @ARGV;}
|
|
|
58 elsif ( $this_arg eq '-mir') {$MirFilename = shift @ARGV;}
|
|
|
59 elsif ( $this_arg eq '-v') {$verbose = 1;}
|
|
|
60 elsif ( $this_arg eq '-head') {$header = 1;}
|
|
|
61 elsif ( $this_arg eq '-noXY') {$noXY = 1;}
|
|
|
62 elsif ( $this_arg eq '-o') {$ResFilename = shift @ARGV;}
|
|
|
63 elsif ( $this_arg eq '-reg') {$regFilename = shift @ARGV;}
|
|
|
64 elsif ( $this_arg eq '-minScore') {$minscore = shift @ARGV;}
|
|
|
65 elsif ( $this_arg =~ m/^-/ ) { print "unknown flag: $this_arg\n";}
|
|
|
66 }
|
|
|
67
|
|
|
68 if ($ResFilename eq "") {
|
|
|
69 $ResFilename = $SitesFilename.".withGenes.txt";
|
|
|
70 }
|
|
|
71
|
|
|
72
|
|
|
73
|
|
|
74 #------------read expression/foldChange annotation of genes---------
|
|
|
75
|
|
|
76 my %geneReg;
|
|
|
77 if ( $regFilename eq ""){
|
|
|
78 print "you did not specify file with expression of fold change values\n";
|
|
|
79 }
|
|
|
80 else {
|
|
|
81 open (REG, "<$regFilename ") or die "Cannot open file $regFilename !!!!: $!";
|
|
|
82 #Gene median mad flag
|
|
|
83 #RPL41 13.60755187 0.074233841 EXPRESSED
|
|
|
84 #A 1110013L07Rik 0.26 up-regulated
|
|
|
85
|
|
|
86 while (<REG>) {
|
|
|
87 chomp;
|
|
|
88 my ($name, $value) = (split)[1,3];
|
|
|
89 $geneReg{$name} = $value;
|
|
|
90 }
|
|
|
91 close REG;
|
|
|
92 }
|
|
|
93 #-----------read genes----------------
|
|
|
94
|
|
|
95 my %genes;
|
|
|
96
|
|
|
97 my $count = 0;
|
|
|
98
|
|
|
99 open (GENES, "<$GenesFilename") or die "Cannot open file $GenesFilename!!!!: $!";
|
|
|
100 <GENES>;
|
|
|
101
|
|
|
102 my ($name,$chr,$strand,$leftPos,$rightPos);
|
|
|
103
|
|
|
104 while (<GENES>) {
|
|
|
105 chomp;
|
|
|
106 if (/(chr\S*)\s(\d+)\s(\d+)\s([-]?1)\s\S+\s\S+\s(\S+)/){
|
|
|
107 $name = $5;
|
|
|
108 $chr = $1;
|
|
|
109
|
|
|
110 $strand = $4;
|
|
|
111 if ($strand eq '1') {
|
|
|
112 $strand = 1;
|
|
|
113 }
|
|
|
114 else {
|
|
|
115 $strand = -1;
|
|
|
116 }
|
|
|
117 $leftPos = $2;
|
|
|
118 $rightPos = $3;
|
|
|
119 next if (($chr =~ m/[XY]/)&&($noXY));
|
|
|
120 next if ($name =~ m/MIR/);
|
|
|
121 } elsif (/(chr\S*)\s([+-])\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\S+)\s(\S+)\s\S+\s(\S+)/) {
|
|
|
122 $name = $10;
|
|
|
123 $chr = $1;
|
|
|
124 $strand = $2;
|
|
|
125 $leftPos = $3;
|
|
|
126 $rightPos = $4;
|
|
|
127 next if (($chr =~ m/[XY]/)&&($noXY));
|
|
|
128 next if ($name =~ m/MIR/);
|
|
|
129
|
|
|
130 if ($strand eq '+') {
|
|
|
131 $strand = 1;
|
|
|
132 }
|
|
|
133 else {
|
|
|
134 $strand = -1;
|
|
|
135 }
|
|
|
136 } else {
|
|
|
137 print "Wrong type: ",$_,"\n";
|
|
|
138 }
|
|
|
139 my $ID = "$name\t$chr:$leftPos-$rightPos";
|
|
|
140 my $reg = "NA";
|
|
|
141 if (exists($geneReg{$name})) {
|
|
|
142 $reg = $geneReg{$name};
|
|
|
143 }
|
|
|
144 unless (exists($genes{$chr})) {
|
|
|
145 my %h;
|
|
|
146 $genes{$chr} = \%h;
|
|
|
147 }
|
|
|
148 unless (exists($genes{$chr}->{$ID})) {
|
|
|
149 my %h1;
|
|
|
150 $genes{$chr}->{$ID} = \%h1;
|
|
|
151 $count++;
|
|
|
152 }
|
|
|
153 $genes{$chr}->{$ID}{'name'} = $name ;
|
|
|
154 $genes{$chr}->{$ID}{'left'} = $leftPos ;
|
|
|
155 $genes{$chr}->{$ID}{'right'} = $rightPos ;
|
|
|
156
|
|
|
157 $genes{$chr}->{$ID}{'strand'} = $strand;
|
|
|
158
|
|
|
159 $genes{$chr}->{$ID}{'TSS'} = ($strand == 1) ? $leftPos :$rightPos ;
|
|
|
160 $genes{$chr}->{$ID}{'TE'} = ($strand == -1) ? $leftPos :$rightPos ;
|
|
|
161 $genes{$chr}->{$ID}{'reg'} = $reg;
|
|
|
162 $genes{$chr}->{$ID}{'length'} = abs ($leftPos-$rightPos);
|
|
|
163 $genes{$chr}->{$ID}{'closestPicDist'} = $BIGNUMBER;
|
|
|
164 $genes{$chr}->{$ID}{'closestPositivePicDist'} = $BIGNUMBER;
|
|
|
165 $genes{$chr}->{$ID}{'closestNegativePicDist'} = -$BIGNUMBER;
|
|
|
166
|
|
|
167 $genes{$chr}->{$ID}{'closestPicDistTE'} = $BIGNUMBER;
|
|
|
168
|
|
|
169 }
|
|
|
170 print "Total genes : $count\n";
|
|
|
171
|
|
|
172
|
|
|
173
|
|
|
174 close GENES;
|
|
|
175 print "\t\t$GenesFilename is read!\n";
|
|
|
176 #for my $gName (sort keys %{$genes{'chr18'}}) {
|
|
|
177
|
|
|
178 # print "$gName\t$genes{'chr18'}->{$gName}{'TSS'}\n";
|
|
|
179 #}
|
|
|
180
|
|
|
181 #-----------read file with sites miRNA, store as genes-----
|
|
|
182
|
|
|
183 if ( $MirFilename eq ""){
|
|
|
184 print "you did not specify file with miRNA\n";
|
|
|
185 }
|
|
|
186 else {
|
|
|
187
|
|
|
188
|
|
|
189 open (MIR, "<$MirFilename ") or die "Cannot open file $MirFilename !!!!: $!";
|
|
|
190 #chr1 20669090 20669163 mmu-mir-206 960 +
|
|
|
191 while (<MIR>) {
|
|
|
192 chomp;
|
|
|
193 my ($name, $chr, $leftPos, $rightPos, $strand );
|
|
|
194 #1 . miRNA 20669091 20669163 . + . ACC="MI0000249"; ID="mmu-mir-206";
|
|
|
195 if (/([0-9XYM]+)\s.\smiRNA\s(\d+)\s(\d+)\s.\s([+-])\s.\sACC=.*ID=\"(.*)\"/) {
|
|
|
196 $name = $5;
|
|
|
197 $chr = $1;
|
|
|
198 $leftPos = $2;
|
|
|
199 $rightPos = $3;
|
|
|
200 $strand = $4;
|
|
|
201 }
|
|
|
202 elsif (/(.*)\s(\d+)\s(\d+)\s(.*)\s(.*)\s(.*)/){
|
|
|
203 $name = $4;
|
|
|
204 $chr = $1;
|
|
|
205 $leftPos = $2;
|
|
|
206 $rightPos = $3;
|
|
|
207 $strand = $6;
|
|
|
208 } else {
|
|
|
209 next;
|
|
|
210 }
|
|
|
211
|
|
|
212 unless ($chr =~ m/chr/) {
|
|
|
213 $chr = "chr".$chr;
|
|
|
214 }
|
|
|
215 my $ID = "$name\t$chr:$leftPos-$rightPos";
|
|
|
216
|
|
|
217 if ($strand eq '+') {
|
|
|
218 $strand = 1;
|
|
|
219 }
|
|
|
220 else {
|
|
|
221 $strand = -1;
|
|
|
222 }
|
|
|
223
|
|
|
224 unless (exists($genes{$chr})) {
|
|
|
225 my %h;
|
|
|
226 $genes{$chr} = \%h;
|
|
|
227 }
|
|
|
228 unless (exists($genes{$chr}->{$ID})) {
|
|
|
229 my %h1;
|
|
|
230 $genes{$chr}->{$ID} = \%h1;
|
|
|
231 $count++;
|
|
|
232 }
|
|
|
233 $genes{$chr}->{$ID}{'name'} = $name ;
|
|
|
234 $genes{$chr}->{$ID}{'left'} = $leftPos ;
|
|
|
235 $genes{$chr}->{$ID}{'right'} = $rightPos ;
|
|
|
236 $genes{$chr}->{$ID}{'cdsStart'} = $leftPos ;
|
|
|
237 $genes{$chr}->{$ID}{'cdsEnd'} = $rightPos ;
|
|
|
238 $genes{$chr}->{$ID}{'strand'} = $strand;
|
|
|
239 $genes{$chr}->{$ID}{'length'} = abs ($leftPos-$rightPos);
|
|
|
240 $genes{$chr}->{$ID}{'exonCount'} = 1;
|
|
|
241 $genes{$chr}->{$ID}{'exonStarts'} = $leftPos ;
|
|
|
242 $genes{$chr}->{$ID}{'exonEnds'} = $rightPos ;
|
|
|
243 $genes{$chr}->{$ID}{'TSS'} = ($strand == 1) ? $leftPos :$rightPos ;
|
|
|
244 $genes{$chr}->{$ID}{'TE'} = ($strand == -1) ? $leftPos :$rightPos ;
|
|
|
245 $genes{$chr}->{$ID}{'reg'} = "miRNA";
|
|
|
246 ($genes{$chr}->{$ID}{'firstIntronStart'},$genes{$chr}->{$ID}{'firstIntronEnd'}) = (0,0);
|
|
|
247 $genes{$chr}->{$ID}{'closestPicDist'} = $BIGNUMBER;
|
|
|
248 $genes{$chr}->{$ID}{'closestPicDistTE'} = $BIGNUMBER;
|
|
|
249 $genes{$chr}->{$ID}{'closestPositivePicDist'} = $BIGNUMBER;
|
|
|
250 $genes{$chr}->{$ID}{'closestNegativePicDist'} = -$BIGNUMBER;
|
|
|
251
|
|
|
252
|
|
|
253 }
|
|
|
254
|
|
|
255
|
|
|
256 close MIR;
|
|
|
257 print "\t\t$MirFilename is read!\n" if ($verbose) ;
|
|
|
258 }
|
|
|
259
|
|
|
260
|
|
|
261
|
|
|
262 #-----------read file with sites and find overlapping genes-----
|
|
|
263 my $numberOfAllSites = 0;
|
|
|
264
|
|
|
265 my $lengthLosses = 0;
|
|
|
266 my $lengthGains = 0;
|
|
|
267
|
|
|
268 open (FILE, "<$SitesFilename") or die "Cannot open file $SitesFilename!!!!: $!";
|
|
|
269 open (OUT , ">$ResFilename") or die "Cannot open file $ResFilename!!!!: $!";
|
|
|
270 print OUT "chrom start end max_coord score Dist DistTE geneName geneCoord Reg\n";
|
|
|
271 open (GENESOUT , ">$ResFilename.genes") or die "Cannot open file $ResFilename.genes!!!!: $!";
|
|
|
272
|
|
|
273 print GENESOUT "Name\tGeneCoord\tDistS\tDistE\tDistTE\tReg\n";
|
|
|
274
|
|
|
275 my $correction = 0;
|
|
|
276
|
|
|
277 if ($header) {
|
|
|
278 my $headerString = <FILE>; #read header
|
|
|
279 my @a = split (/\t/,$header );
|
|
|
280
|
|
|
281 if ($a[1] =~m/chr/) {
|
|
|
282 $correction=1;
|
|
|
283 }
|
|
|
284 }
|
|
|
285
|
|
|
286 $count = 0;
|
|
|
287 print $SitesFilename, "\n";
|
|
|
288 while (<FILE>) {
|
|
|
289 chomp;
|
|
|
290 next if (/track/);
|
|
|
291 my $string = $_;
|
|
|
292 chomp $string;
|
|
|
293 $numberOfAllSites++;
|
|
|
294 my @a = split /\t/;
|
|
|
295 if (($a[1] =~m/chr/)&&($correction==0)) {
|
|
|
296 $correction=1;
|
|
|
297 }
|
|
|
298 my $chro = $a[0+$correction];
|
|
|
299 next if (($chro =~ m/[XY]/)&&($noXY));
|
|
|
300 unless ($chro =~ m/chr/) {
|
|
|
301 $chro = "chr".$chro;
|
|
|
302 }
|
|
|
303
|
|
|
304 my $fpos = $a[1+$correction];
|
|
|
305 my $lpos = $a[2+$correction];
|
|
|
306 my $score = $a[4+$correction];
|
|
|
307 if ($minscore>0) {
|
|
|
308 next if ($score<$minscore);
|
|
|
309 }
|
|
|
310 next if ($chro=~m/M/);
|
|
|
311
|
|
|
312 print OUT $string, "\t";
|
|
|
313
|
|
|
314 findClosestTSS ($fpos,$lpos,$chro,\%genes);
|
|
|
315
|
|
|
316 $count ++;
|
|
|
317 }
|
|
|
318 close FILE;
|
|
|
319 close OUT ;
|
|
|
320 close GENESOUT;
|
|
|
321 print "Total Sites: $count\n";
|
|
|
322
|
|
|
323 open (GENESOUT , ">$ResFilename.genes.ClosestPeakDist") or die "Cannot open file $ResFilename.genes.ClosestPeakDist!!!!: $!";
|
|
|
324 print GENESOUT "Name Coord Dist DistTE Reg posDist negDist\n";
|
|
|
325 for my $chro (keys %genes) {
|
|
|
326 for my $gName (keys %{$genes{$chro}}) {
|
|
|
327 print GENESOUT "$gName\t",$genes{$chro}->{$gName}{'closestPicDist'},"\t",$genes{$chro}->{$gName}{'closestPicDistTE'},"\t",$genes{$chro}->{$gName}{'reg'},"\t",$genes{$chro}->{$gName}{'closestPositivePicDist'},"\t",$genes{$chro}->{$gName}{'closestNegativePicDist'},"\n";
|
|
|
328 }
|
|
|
329 }
|
|
|
330 close GENESOUT;
|
|
|
331
|
|
|
332 #my @arr = @{$genes{'chr'}};
|
|
|
333
|
|
|
334 sub overlapGenes {
|
|
|
335 my ($otherGene,$bestGene,$chro,$genes)= @_;
|
|
|
336 my $a1 = $genes->{$chro}{$otherGene}{'left'};
|
|
|
337 my $a2 = $genes->{$chro}{$bestGene}{'left'};
|
|
|
338 my $e1 = $genes->{$chro}{$otherGene}{'right'};
|
|
|
339 my $e2 = $genes->{$chro}{$bestGene}{'right'};
|
|
|
340 if (($a1 >= $a2)&&($a1 <= $e2)) {
|
|
|
341 return 1;
|
|
|
342 }
|
|
|
343 if (($a2 >= $a1)&&($a2 <= $e1)) {
|
|
|
344 return 1;
|
|
|
345 }
|
|
|
346 return 0;
|
|
|
347 }
|
|
|
348
|
|
|
349 sub overlap {
|
|
|
350 my ($a1,$a2,$e1,$e2)= @_; #e for genes
|
|
|
351
|
|
|
352 if ($a1 > $a2) {
|
|
|
353 ($a1,$a2) = ($a2,$a1);
|
|
|
354 }
|
|
|
355
|
|
|
356 if ($e1 > $e2) {
|
|
|
357 ($e1,$e2) = ($e2,$e1);
|
|
|
358 }
|
|
|
359
|
|
|
360
|
|
|
361 if (($a1 >= $e1)&&($a1 <= $e2)) {
|
|
|
362 return 2;
|
|
|
363 }
|
|
|
364 if (($a2 >= $e1)&&($a2 <= $e2)) {
|
|
|
365 return 2;
|
|
|
366 }
|
|
|
367 if (($e1 >= $a1)&&($e2 <= $a2)) {
|
|
|
368 return 1;
|
|
|
369 }
|
|
|
370
|
|
|
371 return 0;
|
|
|
372 }
|
|
|
373
|
|
|
374
|
|
|
375 sub findClosestTSS {
|
|
|
376 my ($fpos,$lpos,$chro,$genes) = @_;
|
|
|
377 my $pos = ($fpos+$lpos)/2;
|
|
|
378 my $gene = "";
|
|
|
379 my $tssDist=$BIGNUMBER;
|
|
|
380 my $teDist=$BIGNUMBER;
|
|
|
381
|
|
|
382 for my $gName (keys %{$genes->{$chro}}) {
|
|
|
383 my $TSS = $genes->{$chro}{$gName}{'TSS'};
|
|
|
384 #print $gName,":",$TSS," " if ($chro eq "chr15");
|
|
|
385 my $geneDist = ($pos-$TSS)*$genes->{$chro}{$gName}{'strand'};
|
|
|
386 $geneDist = ($fpos-$TSS)*$genes->{$chro}{$gName}{'strand'} if (abs($fpos-$TSS)<abs($geneDist)) ;
|
|
|
387 $geneDist = ($lpos-$TSS)*$genes->{$chro}{$gName}{'strand'} if (abs($lpos-$TSS)<abs($geneDist)) ;
|
|
|
388 $geneDist = 0 if ($TSS>=$fpos && $TSS<=$lpos);
|
|
|
389
|
|
|
390 if (abs($geneDist)<abs($tssDist)) {
|
|
|
391 $gene=$gName;
|
|
|
392 $tssDist = $geneDist;
|
|
|
393 $teDist = ($pos-$genes->{$chro}{$gName}{'TE'})*$genes->{$chro}{$gName}{'strand'};
|
|
|
394 }
|
|
|
395 if (abs($geneDist)<$BIGNUMBER) {
|
|
|
396 ###HERE!!!
|
|
|
397 print GENESOUT "$gName\t",($fpos-$TSS)*$genes->{$chro}{$gName}{'strand'},"\t",($lpos-$TSS)*$genes->{$chro}{$gName}{'strand'},"\t",($pos-$genes->{$chro}{$gName}{'TE'})*$genes->{$chro}{$gName}{'strand'},"\t",$genes->{$chro}{$gName}{'reg'},"\n";
|
|
|
398
|
|
|
399 if (abs($geneDist)<abs($genes->{$chro}{$gName}{'closestPicDist'})) {
|
|
|
400 $genes->{$chro}{$gName}{'closestPicDist'} = $geneDist;
|
|
|
401 $genes->{$chro}{$gName}{'closestPicDistTE'} = ($pos-$genes->{$chro}{$gName}{'TE'})*$genes->{$chro}{$gName}{'strand'};
|
|
|
402 }
|
|
|
403 if ($geneDist>=0 && abs($geneDist)<$genes{$chro}->{$gName}{'closestPositivePicDist'} ) {
|
|
|
404 $genes->{$chro}{$gName}{'closestPositivePicDist'} = $geneDist;
|
|
|
405 }
|
|
|
406 if (($geneDist)*$genes->{$chro}{$gName}{'strand'}<=0 && -1*abs($pos-$TSS)>$genes{$chro}->{$gName}{'closestNegativePicDist'} ) {
|
|
|
407 $genes->{$chro}{$gName}{'closestNegativePicDist'} = ($pos-$TSS)*$genes->{$chro}{$gName}{'strand'};
|
|
|
408 }
|
|
|
409
|
|
|
410 }
|
|
|
411 }
|
|
|
412 print OUT "$tssDist\t$teDist\t$gene\t$genes{$chro}->{$gene}{'reg'}\n" if ($gene ne "");
|
|
|
413 if ($gene eq "") {
|
|
|
414 print OUT "$tssDist $teDist NA NA NA\n";
|
|
|
415 }
|
|
|
416
|
|
|
417 }
|
|
|
418
|
|
|
419 sub printOvelapingGenes {
|
|
|
420 my ($fpos,$lpos,$chro,$genes,$globalH,$type) = @_;
|
|
|
421 #print $fpos,$lpos,$chro,$genes,$globalH,$type,"\n";
|
|
|
422 my %hash1;
|
|
|
423 my %hash2;
|
|
|
424 my @array2return;
|
|
|
425 for my $gName (keys %{$genes->{$chro}}) {
|
|
|
426 my $TSS = $genes->{$chro}{$gName}{'TSS'};
|
|
|
427 my $TE = $genes->{$chro}{$gName}{'TE'};
|
|
|
428
|
|
|
429 if (overlap($fpos,$lpos,$TSS,$TE)==1) {
|
|
|
430 $hash1{$gName} = overlap($fpos,$lpos,$TSS,$TE);
|
|
|
431 }
|
|
|
432 if (overlap($fpos,$lpos,$TSS,$TE)==2) {
|
|
|
433 $hash2{$gName} = overlap($fpos,$lpos,$TSS,$TE);
|
|
|
434 }
|
|
|
435 }
|
|
|
436 print OUT join(",", sort keys %hash1),"\t",join(",", sort keys %hash2),"\n";
|
|
|
437 if ($type eq "loss") {
|
|
|
438 for my $key (sort keys %hash1) {
|
|
|
439 $globalH->{$key} = 1;
|
|
|
440 }
|
|
|
441 for my $key (sort keys %hash2) {
|
|
|
442 $globalH->{$key} = 1;
|
|
|
443 }
|
|
|
444 }else {
|
|
|
445 for my $key (sort keys %hash1) {
|
|
|
446 $globalH->{$key} = 1;
|
|
|
447 }
|
|
|
448 }
|
|
|
449
|
|
|
450 }
|
|
|
451
|
|
|
452 sub min {
|
|
|
453 return $_[0] if ($_[0]<$_[1]);
|
|
|
454 $_[1];
|
|
|
455 }
|