Donations gladly accepted
If you're new here please read PerlMonks FAQ and Create a new user.
Want Mega XP? Prepare to have your hopes dashed, join in on the: poll ideas quest 2012 (Don't worry; you've got plenty of time.)
|
New Questions
|
Attempt to reload IO/Socket.pm aborted
1 direct reply — Read more / Contribute
|
by trillich
on Nov 02, 2012 at 18:10
|
|
|
This is an odd situation and I'm just about at wit's end...
On HP/UX we have some perl scripts to communicate via LWP::UserAgent.
Some users can run the script, no problem; others get the following error:
Socket object version 1.94 does not match bootstrap parameter 2.006 at
+ /opt/perl514/lib/5.14.2/PA-RISC2.0-thread-multi/DynaLoader.pm line 2
+13.
Compilation failed in require at /opt/perl514/lib/5.14.2/PA-RISC2.0-th
+read-multi/IO/Socket.pm line 12.
BEGIN failed--compilation aborted at /opt/perl514/lib/5.14.2/PA-RISC2.
+0-thread-multi/IO/Socket.pm line 12.
Where it dies is on "require IO::Socket" (or anything that pulls in "Socket.pm").
In trying to debug this, we've dumped lots of environment variables and @INC and %INC at various stages. All users show they're using /opt/perl514/lib/... for loading libraries.
So for debugging output we generated a listing of loaded modules based on keys %INC:
foreach my $file ( sort keys %INC ) {
my $mod = "$file";
next unless $mod =~ s/[.]pm$//;
$mod =~ s{/}{::}g;
my $ver = eval('$' . $mod . '::VERSION or "[unknown]"');
push @output, [ $mod, $ver ];
}
...
Users who CAN run the script have these modules loaded right before "require IO::Socket":
AutoLoader 5.71
Carp 1.20
Compress::Raw::Zlib 2.045
Config [unknown]
Crypt::SSLeay 0.58
Crypt::SSLeay::CTX [unknown]
Crypt::SSLeay::MainContext [unknown]
Crypt::SSLeay::X509 [unknown]
Errno 1.13
Exporter 5.64_03
Exporter::Heavy 5.64_03
Fcntl 1.11
File::Glob 1.13
File::GlobMapper 1.000
File::Spec 3.33
File::Spec::Unix 3.33
Getopt::Std 1.06
HTTP::Config 5.815
HTTP::Date 5.831
HTTP::Headers 5.827
HTTP::Message 5.834
HTTP::Request 5.827
HTTP::Response 5.824
HTTP::Status 5.817
IO 1.25_04
IO::Compress::Base::Common 2.045
IO::Compress::Gzip::Constants 2.045
IO::Compress::Zlib::Extra 2.045
IO::File 1.15
IO::Handle 1.31
IO::Seekable 1.1
IO::Socket 1.32
IO::Socket::INET 1.31
IO::Socket::UNIX 1.23
IO::Uncompress::Adapter::Inflate 2.045
IO::Uncompress::Base 2.046
IO::Uncompress::Gunzip 2.045
IO::Uncompress::RawInflate 2.045
LWP 5.834
LWP::MemberMixin [unknown]
LWP::Protocol 5.829
LWP::Protocol::http [unknown]
LWP::Protocol::https [unknown]
LWP::UserAgent 5.834
List::Util 1.23
MIME::Base64 3.13
Net::HTTP 5.834
Net::HTTP::Methods 5.834
Net::HTTPS 5.819
Net::SSL 2.85
Scalar::Util 1.23
SelectSaver 1.02
Socket 2.006
Storable 2.30
Symbol 1.07
Time::Local 1.2000
URI 1.59
URI::Escape 3.31
URI::_generic [unknown]
URI::_idna [unknown]
URI::_punycode 0.04
URI::_query [unknown]
URI::_server [unknown]
URI::http [unknown]
URI::https [unknown]
XSLoader 0.13
bytes 1.04
constant 1.21
feature 1.20
integer 1.00
overload 1.13
strict 1.04
utf8 1.09
vars 1.02
warnings 1.12
warnings::register 1.02
By contrast, the users who CANNOT run the script, have these modules loaded instead -- e.g. DynaLoader instead of AutoLoader?
Carp 1.20
Config [unknown]
DynaLoader 1.13
Errno 1.13
Exporter 5.64_03
Exporter::Heavy 5.64_03
Fcntl 1.11
Getopt::Std 1.06
HTTP::Config 5.815
HTTP::Date 5.831
HTTP::Headers 5.827
HTTP::Message 5.834
HTTP::Request 5.827
HTTP::Response 5.824
HTTP::Status 5.817
IO 1.25_04
IO::Handle 1.31
IO::Socket [unknown]
IO::Socket::INET [unknown]
LWP 5.834
LWP::MemberMixin [unknown]
LWP::Protocol 5.829
LWP::Protocol::http [unknown]
LWP::Protocol::https [unknown]
LWP::UserAgent 5.834
MIME::Base64 3.13
Net::HTTP 5.834
SelectSaver 1.02
Socket 2.006
Storable 2.30
Symbol 1.07
Time::Local 1.2000
URI 1.59
URI::Escape 3.31
URI::_generic [unknown]
URI::_idna [unknown]
URI::_punycode 0.04
URI::_query [unknown]
URI::_server [unknown]
URI::http [unknown]
URI::https [unknown]
XSLoader 0.13
constant 1.21
integer 1.00
overload 1.13
strict 1.04
vars 1.02
warnings 1.12
warnings::register 1.02
All module-paths (from values %INC) are /opt/perl514/lib/...
Suggestions?
|
Taint mode limitations
3 direct replies — Read more / Contribute
|
by alain_desilets
on Nov 02, 2012 at 11:32
|
|
|
I'm a total newb when it comes to security, and I am trying to figure out how to use taint mode to locate and patch vulnerabilities in a Perl CGI application.
I have read a bit about taint mode, and I am puzzled by two things that don't seem to make sense. So I am wondering if I am just misunderstanding something.
Firstly, it seems that when I apply a regexp match to a tainted variable, then Perl considers the matched groups to NOT be tainted. The assumption being that I executed this regexp match specifically to remove potential threats from the tainted sting.
This seems to be a very naive assumption. For example, it is very common for me to remove leading and trailing space from a text input, before proceeding ahead with it. From then on, Perl would consider that the input is untainted, eventhough the regexp match I applied to it has nothing to do with removing potential threats from it.
When I first read about taint mode, I assume that there would be some kind of function untainted(), which would label a particular variable as having been untainted. But there doesn't seem to be a way to do that.
The other thing I notice is that Perl only considers tainted variable as being dangerous when used in system calls and the like. But there are many other situations where using a tainted variable is dangerous. For example, if I write some JavaScript code to my CGI scripts STDOUT, and that code is composed based on the content of a tainted variable, then I might be opening my application to a cross site scripting attack. Yet, Perl considers that priting a tainted value to STDOUT is safe.
Again, when I first started reading about taint mode, I expected that it would identify every single instance of tainted variable and force me to look at it explicitly. But instead, it only flags the use of tainted variables in contexts where Perl thinks it might be unsafe to use, and obviously, Perl's idea of what is safe is too permissive. Is there a way to tell taint mode to identify all tainted variables, whether they are used in an unsafe fashion or not?
Thanks.
Alain
|
Mouse role fails
1 direct reply — Read more / Contribute
|
by karlgoethebier
on Nov 02, 2012 at 08:52
|
|
|
Hi, i'm playing around with Mouse roles and got stuck.
Role #1:
package ReadFile;
use Mouse::Role;
use MyTypes;
use IO::File;
requires qw(lines);
has '_io' => (
is => 'ro',
isa => 'MyCompany::ReadFile',
builder => '_build_read_file',
handles => [ qw( open getlines close) ],
init_arg => undef,
lazy => 1,
);
sub _build_read_file() {
my $self = shift;
IO::File->new();
}
# sub read_file() {
# my ( $self, $file ) = @_;
# $self->open( $file);
# my @lines = $self->getlines();
# $self->close();
# chomp(@lines);
# $self->lines(\@lines);
# }
1;
This one fails on init with the followings errors:
Could not load class (ReadFile) because : Undefined subroutine &IO::Handle::_create_getline_subs called at C:/strawberry/perl/lib/IO/Handle.pm line 434.
In Handle.pm Line 434: # Special XS wrapper to make them inherit lexical hints from the caller. _create_getline_subs(<<'END' ) or die $@;
Compilation failed in require at C:/strawberry/perl/lib/IO/Seekable.pm line 101.
In Seekable.pm line 101: use IO::Handle ();
Compilation failed in require at C:/strawberry/perl/lib/IO/File.pm line 133.
In File.pm line 133: use IO::Seekable;
But the next one works.
Role #2:
package DBIxODBC;
use Mouse::Role;
use MyTypes;
use DBIx::Simple;
requires qw( user passwd dsn );
with qw(Timestamp);
has 'data' => (
is => 'rw',
isa => 'HashRef',
trigger => \&_load,
);
has '_dbix' => (
is => 'ro',
isa => 'MyCompany::DBIx',
handles => [qw( insert)],
builder => '_build_dbix',
init_arg => undef,
lazy => 1,
);
sub _build_dbix() {
my $self = shift;
my $connect_string;
$connect_string = "dbi:ODBC:" . $self->dsn;
DBIx::Simple->new( $connect_string, $self->user, $self->passwd );
}
sub _load() {
my ( $self, $input ) = @_;
my $table = ( keys %$input )[0];
$self->insert( $table, $input->{$table} );
print $self->timestamp . qq(\n);
}
1;
Thank you very much for any advice.
Best regards,
Karl
|
How best to strip text from a file?
4 direct replies — Read more / Contribute
|
by bobdabuilda
on Nov 01, 2012 at 22:39
|
|
|
Hi guys. I've been mulling this one over for awhile now, trying to decide/work out how best to handle it.
One of my users has a report she would like to run which results in over 1000 pages of rather poorly-presented text. Needless to say, she would like it if I could arrange for this to be trimmed considerably. My intention is to build this up, firstly, getting the data extraction right, and then I will use Spreadsheet::WriteExcel to put it into a much more friendly format for her.
See below for an example of the kind of text I'm working with - note this is just part of one "order", and these are repeated numerous times throughout the file. All the dates etc. have the "ability" of being different, so each "order" and each "distribution" of each order need to be extracted and handled on an individual basis.
List of Distributions
+
+
Produced Tuesday, 9 October, 2012 at 1:38 PM
+
+
Order ID:PO-9999 fiscal cycle:21112
Vendor ID:VEND99 order type:SUBSCRIPT
15) requisition number: copies:9
call number:XX(9999999.999)
ISBN/ISSN:9999-999X
Title:Item title here.
ISSN:9999-999X
Publication info:More text here about stuff
Distribution--
packing list:STUFF-I-DONT-NEED-999
holding code:CODEINFO1 copies:1
date received:27/6/2012 date lo
+aded:27/6/
2012
Distribution--
packing list:STUFF-I-DONT-NEED-999
holding code:CODEINFO3 copies:2
date received:27/9/2012 date lo
+aded:27/6/
2012
Distribution--
packing list:STUFF-I-DONT-NEED-999
holding code:CODEINFO2 copies:1
date received:25/8/2012 date lo
+aded:27/6/
2012
So, out of that, I need to grab the values from the (in order of appearance) Order ID, fiscal cycle, Vendor ID, the number to the left of "requisition number", copies, title, ISBN/ISSN, holding code, copies, date received, date loaded.
My idea at this point in time, is to perform a loop, looking for the start of the data I need to grab. I have managed to get this part done using :
open (IN, "<$distfile") or die "Can't open $distfile\n";
print "File opened\n";
while ($line = <IN>) {
chomp($line);
if ( $line =~ /^(\s+.+)Order ID/ )
{
print "Found Order ID\n";
}
}
That part works fine. I then moved on to actually trying to extract the data from the crud. The idea was to just loop through each bracket of data, stripping the data out of each line separately.
So, for the first one, I designed a regex which matches everything except the two pieces of data I want from the "Order ID" line. The plan was to negate that match, and dump the results into a variable, then move on to the next line. Sounded relatively easy, but I've not been able to work out where I've gone wrong with it... I think if I can get a little help working out how to do this one line, then the rest of it should fall into place pretty readily...
The test I have been trying to use for this is :
my ($order,$fiscal) = ($line !~ m/(\s+Order ID:|\s+fiscal cycle:)/g)
+;
print "Order # $order, Fiscal year: $fiscal\n";
As it stands above, I get a string printed with null values. If I change the "!~" to "=~" then I get the output:
Order # Order ID:, Fiscal year: fiscal cycle:
... which is why I was trying to negate the regex match. So... could you please help me understand where it is I'm going wrong with this? Am I going about this the right way, or should I be thinking along different lines for processing all this text?
Thanks in advance for any assistance you can give.
|
Getting single element from an array
4 direct replies — Read more / Contribute
|
by gurpreetsingh13
on Nov 01, 2012 at 05:05
|
|
|
Hi Monks,
Was just trying some statements and wondered why a similar one doesn't work.
print ("adf","ff","f"); # Gladly prints the list
print ("adf","ff","f")[1]; #Gives a syntax error
$val=("adf","ff","f")[1];print $val; #Works easily
print join "",("adf","ff","f"); #Works
print join "",("adf","ff","f")[1]; #Works since treated in list contex
+t
I might be wrong on some basics. But why the 2nd statement fails.
I mean if such a thing works, then we can directly use it to print a single element returned from a function or method(like in Java).e.g.
(sort {$a<=>} @lst)[0] # an alternative way to get min value from some
+ numeric list.
Similarly in Java we can do:
obj.method()[2] #when we know that method returns an array
Tried to search a little about this, but could not find a reasonable thread for the same. Sorry again if this is some conceptual weakness of mine.
|
How to have OS specific code sections in Perl
3 direct replies — Read more / Contribute
|
by perltux
on Oct 31, 2012 at 12:55
|
|
|
Hi,
I'm trying to make some code in my perl script OS specific, but I still get the following error when I try to run the code below on Windows:
Can't locate MIDI/ALSA.pm in @INC
The "OS is Linux" line only gets printed on Linux as expected, on Windows it doesn't get printed, so the 'if' subroutine is never entered in Windows as expected, that's why I don't understand the above error on Windows.
The script:
#!/usr/bin/perl
if ($^O eq 'linux') { $LINUX=1; };
if ($LINUX) {
print STDERR "OS is Linux\n";
use MIDI::ALSA ('SND_SEQ_EVENT_PORT_UNSUBSCRIBED',
'SND_SEQ_EVENT_SYSEX');
MIDI::ALSA::client('test',1,1,1);
MIDI::ALSA::connectfrom(0,'MidiSport 4x4:0');
MIDI::ALSA::connectto(1,'MidiSport 4x4:0');
MIDI::ALSA::start();
}
Basically I want to load a Linux only module and then execute a few module specific commands only on Linux, on Windows I want that section of the script to be ignored.
How do I make this work?
|
Find Prefix if regex didn't match
3 direct replies — Read more / Contribute
|
by demoralizer
on Oct 31, 2012 at 07:16
|
|
|
Hi folks,
I'm "using" perlmonks since years and most of the time I've found good answers for my questions but now I fear I have a quite hard one what made it necessary to create an account and join you :)
Here it is:
I have a given regular expression and a GROWING string to be searched through. All the time the string enlarges I will do a search if the given expression can be machted now. If the string enlarges sign wise (and I don't know when it will become larger next time) and if it is quite large the searching becomes quite slow!
To speed this up the solution I have in mind is cutting the head of the string if it is impossible that the regular expression will be found there. This sounds easy because the string can be cut at that start searching position where the regexp engine reached the end of the string the first time. But I have no idea how I can get this information.
Here a little example:
$search="AB.*Z"
$string="WWWA" -> we can cat WWW
now string enlarges...
$string="WWWADBBBABC" -> we can cut WWWADBBB
and so on...
Stupid expressions like $search=".*ABC" are quite harder to handle but that's not so important and therefore I will ignore such special cases, just keep it simple what means if the regexp engine reaches end of string while matching use the position where it started search in that case to cut the string.
Any ideas?
|
reading files
4 direct replies — Read more / Contribute
|
by Anonymous Monk
on Oct 31, 2012 at 06:05
|
|
|
I created a file that upon exit, tracks the exit point, so I know what happened... however, the file runs every 4 minutes. That is 15 times per hour and 360 times per day.
So, I want to track how many entries, I want to keep it at 100 entries, so I can look back for the past 6 and 2/3 hours, that should be good enough...
So at the top of the file, I want to have it keep only the entries numbered 2-100, so it should strip out the first line only, so it will now be 1-99 then when it exists it will write line 100, so next time it will delete line 1 again, etc...
I don't know exactly how to do it effeciently though. I think there is a way to count the lines like this:
open(FILE,"/path/to/file.txt") or die "could not open file: $!";
my @_lines = <FILE>; # After I open the file for reading
close(FILE);
my $_numOfLines = scalar @_lines;# Is that right? I think it is, but m
+y mind is rusty, been a while since I learned all of the perl program
+ming
So if @_lines had 100 lines, can I not do a delete and have it remove only the first line and then just write the file again?
any ideas how how to do that?
Thank you kindly for any advice.
Richard
|
pipe perl
2 direct replies — Read more / Contribute
|
by mouser13
on Oct 30, 2012 at 14:40
|
|
|
Hello I have a old program that need very specific format for input and takes a very long time to load in the web world anyway (20 secs). So I want to use the open and pipe to send information to it. I have a server(c++) simmilar to cgi_speedy, but I never really worked with the open and pipe.
open(old, "| /bin/old");
foreach my $INPUT(@DATA)
{
my ($LAST_NAME,$FIRSTNAME,$ID_NUM,$BOOK) = split(/\s+/,$INPUT);
print old "$LAST_NAME\t$FIRSTNAME\n"
print old "\t$ID_NUM\t$BOOK\n"
}
The code doesn't work but if I do it by hand inputing via keyboard it works? Is their sometype of formating I need to do on the tab or newlines.
|
@array elements multiplication with another array elements.
5 direct replies — Read more / Contribute
|
by New Perlmonk
on Oct 30, 2012 at 12:19
|
|
|
Hi Monks and My Mentors,
I have two arrays @array1 and @array2 containing scalar variables. I would like to multiply the array elements of @array1 with @array2 elements.
Ex: @array1 = (3,4,6,5,8)
@array2 = (2,2,4,5,1)
after multiplication I want to see (6,8,24,25,8) please help here to play with elements of arrays.
|
How to find the last date of the previous month?
6 direct replies — Read more / Contribute
|
by MrSnrub
on Oct 29, 2012 at 22:39
|
|
|
How do I find out the last day of the previous month? In other words, I want a subroutine that, when run today, will return "09/30/2012" (a string in mm/dd/yyyy format)? If the function is run a week from now it will return "10/31/2012"? And if the function was run sometime last March, it would return "02/29/2012" (leap-year day). How do I do this?
|
Calling LWP/Mech from AnyEvent
1 direct reply — Read more / Contribute
|
by Anonymous Monk
on Oct 29, 2012 at 14:09
|
|
|
I have a program that uses AnyEvent and I want to call Finance::MtGox, but do
so without blocking the event loop. I tried both LWP::Protocol::AnyEvent::http
and calling an internal method in Finance::MtGox to just construct the
HTTP::Request and use AnyEvent::HTTP to make the request, but both of these
result in a 400 Bad Request. I'm including the code so hopefully somebody can
figure out where I'm going wrong. Thanks!
|
|
|
New Meditations
|
Humble Rookie Says Thank You
1 direct reply — Read more / Contribute
|
by marquezc329
on Oct 31, 2012 at 01:06
|
|
|
The moment of truth....
"user@host ~$ sudo parse config.lua"
And with this, the first functional 319 lines of code (aka parse) I've ever written, charge into my bare-bones implementation of a terminal based theme-manager for the Awesome Window Manager.
Blank stares from my girlfriend as I rejoice in the successful run resulted from the hours and days and nights of work on this project. The hundreds of pages and internet posts read through. The endless wall of warnings reminding me about this comma, or that semi-colon, that I forgot to add while my eyes battled sleep in the hours after midnight. Telling myself I just need 10 more minutes as the sun rises outside the window and I'm still trying to figure out where the heck the data from that hash really wound up. It all seems worth it in that moment.
I just wanted to say thank you to all the monks here at the Monastery contributing to the learning of others. It is here that I learned how to greet the world with print "hello world!\n";, and it is here that I read, and tried, and failed, and read more. These 319 lines of frustration and lightbulbs clicking on, torment and accomplishment, and failures and failures and failures, and success are my offering to the Monastery. From "Hello World", to hashes of arrays of hashes and multi-line regular expressions, I have you to thank. I have miles and years and tens of thousands of pages and posts to go, but it is my humble and hard-fought beginning.
To other Rookies fighting the good fight for no paycheck, and no homework assignment, learning for no purpose other than the great puzzle of it all, I say: You can do it too... All it takes is energy drinks and Seekers of Perl Wisdom.
Thank you all so much for your selfless contributions, words of advice and hours of experience shared with myself and others. The quality of this community is unsurpassed
-marquezc329
|
State of the art of PDFs in Perl
5 direct replies — Read more / Contribute
|
by mcdave
on Oct 27, 2012 at 10:57
|
|
|
I've been contemplating the state of the art of manipulating PDFs in Perl. The field is littered with the corpses of CPAN modules that try to make it easy to work with PDFs, but I settled on two as being the most useful: PDF::API2 and CAM::PDF. I welcome anyone's comments pointing out things I've missed or other useful tidbits.
My original motivation was a project in which I needed to input an existing PDF (generated by some unknown method) and prepend a coversheet containing a barcode derived from some metadata (passed in as separate arguments; not from the file itself). The barcodes are so people can fax them back to me and I can route the documents, but that's a different story.
If you like counting pixels and keeping track of text's baseline and things like that, you'll love PDF::API2. It's meant to be a low-level tool, and if you want very fine-grained control of your layouts, it's the tool for you. The best examples I found are
(that's an amazingly short list for such a complicated package, but "lack of examples" seems to be a common complaint). The other tool I've used for building PDFs is wkhtmltopdf but it's not Perl. If you're not above system calls, though, it's not bad.
As a low-level tool for creating PDFs, PDF::API2 is everything I want. For reading PDFs, my experience is a bit more mixed. There is a known issue with some features of PDF 1.5 and up. That is a problem for my project, because I consume PDFs people make and "please go back and save this as version 1.4" isn't an option.
To manipulate existing PDFs, CAM::PDF works fine. As of version 1.58, it doesn't claim to broad support for PDF versions beyond 1.5, but my experience is that it can read any PDF I've thrown at it. It bills itself as a PDF manipulation library, and it can do all the helpful things like rearrange pages, import pages from another document, and even clever tricks like swapping out one image for another. So if you have a document and want to tweak it or learn about it, CAM::PDF is a good choice.
In our particular case, we combined the two. We use PDF::API2 to create a one-page coversheet document, then use CAM::PDF to prepend it to the original. It's early days, and nobody is trying to mess me up with complicated PDFs yet, but so far it seems to be working out nicely.
|
|
|
New Obfuscated Code
|
JPEG Zig-Zag
No replies — Read more | Post response
|
by blackle
on Oct 29, 2012 at 13:07
|
|
|
For the last week I've been trying to figure out an algorithm for JPEG's zig-zag spacefilling curve. Specifically, I wanted an algorithm that maps all elements in an NxN matrix to a N*N array given their x and y values. I finally figured it out with the help of my analysis 101 TA. He's not a computer scientist, but he knows what pairing functions are. Anyway, after a few hours messing with perl, I made this subroutine:
sub getPos{
($x,$y,$s)=@_;($d=$x+$y)*($d++)/2
+($d%2?$y:$x)-($d>$s)*($d-$s)**2
}
To use it, you do something like this:
for(my $x = 0; $x < $size; $x++){
for(my $y = 0; $y < $size; $y++){
print getPos($x, $y, $size)." ";
}
print "\n";
}
For $size = 10 the loop will yield:
0 1 5 6 14 15 27 28 44 45
2 4 7 13 16 26 29 43 46 63
3 8 12 17 25 30 42 47 62 64
9 11 18 24 31 41 48 61 65 78
10 19 23 32 40 49 60 66 77 79
20 22 33 39 50 59 67 76 80 89
21 34 38 51 58 68 75 81 88 90
35 37 52 57 69 74 82 87 91 96
36 53 56 70 73 83 86 92 95 97
54 55 71 72 84 85 93 94 98 99
The body of getPos has 65 (non-whitespace) characters, any ideas on how to get it even smaller?
UPDATE:
This prints a JPEG zig-zag when $ARGV[0] is the size of the matrix:
$==pop;print map{$y=$_;map(($d=$y+$_)*($d++)/2-($d>$=)*($d-$=)**2+($d&
+1?$_:$y).$",@m),$/}@m=0..$=-1
99 characters! I started at 125!
|
|
|
|