line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
##---------------------------------------------------------------------------- |
2
|
|
|
|
|
|
|
## Stripe API - ~/lib/Net/API/Stripe/Billing/Subscription/Schedule.pm |
3
|
|
|
|
|
|
|
## Version v0.101.0 |
4
|
|
|
|
|
|
|
## Copyright(c) 2020 DEGUEST Pte. Ltd. |
5
|
|
|
|
|
|
|
## Author: Jacques Deguest <jack@deguest.jp> |
6
|
|
|
|
|
|
|
## Created 2019/12/25 |
7
|
|
|
|
|
|
|
## Modified 2022/10/29 |
8
|
|
|
|
|
|
|
## All rights reserved |
9
|
|
|
|
|
|
|
## |
10
|
|
|
|
|
|
|
## This program is free software; you can redistribute it and/or modify it |
11
|
|
|
|
|
|
|
## under the same terms as Perl itself. |
12
|
|
|
|
|
|
|
##---------------------------------------------------------------------------- |
13
|
|
|
|
|
|
|
BEGIN |
14
|
|
|
|
|
|
|
{ |
15
|
|
|
|
|
|
|
use strict; |
16
|
2
|
|
|
2
|
|
24148906
|
use warnings; |
|
2
|
|
|
|
|
12
|
|
|
2
|
|
|
|
|
62
|
|
17
|
2
|
|
|
2
|
|
10
|
use parent qw( Net::API::Stripe::Generic ); |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
58
|
|
18
|
2
|
|
|
2
|
|
11
|
use vars qw( $VERSION ); |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
11
|
|
19
|
2
|
|
|
2
|
|
141
|
our( $VERSION ) = 'v0.101.0'; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
118
|
|
20
|
2
|
|
|
2
|
|
39
|
}; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
use strict; |
23
|
2
|
|
|
2
|
|
10
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
38
|
|
24
|
2
|
|
|
2
|
|
9
|
|
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
1138
|
|
25
|
|
|
|
|
|
|
|
26
|
0
|
|
|
0
|
1
|
|
|
27
|
|
|
|
|
|
|
|
28
|
0
|
|
|
0
|
1
|
|
|
29
|
|
|
|
|
|
|
|
30
|
0
|
|
|
0
|
1
|
|
|
31
|
|
|
|
|
|
|
{ |
32
|
0
|
|
|
0
|
1
|
|
return( shift->_set_get_class( 'current_phase', |
33
|
|
|
|
|
|
|
{ |
34
|
0
|
|
|
0
|
1
|
|
end_date => { type => 'datetime' }, |
35
|
|
|
|
|
|
|
start_date => { type => 'datetime' }, |
36
|
0
|
|
|
0
|
1
|
|
}, @_ ) |
37
|
|
|
|
|
|
|
); |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
0
|
|
|
0
|
1
|
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
|
48
|
0
|
|
|
0
|
1
|
|
|
49
|
|
|
|
|
|
|
|
50
|
0
|
|
|
0
|
1
|
|
|
51
|
|
|
|
|
|
|
|
52
|
0
|
|
|
0
|
1
|
|
|
53
|
|
|
|
|
|
|
|
54
|
0
|
|
|
0
|
1
|
|
|
55
|
|
|
|
|
|
|
|
56
|
0
|
|
|
0
|
1
|
|
|
57
|
|
|
|
|
|
|
## Undocumented but appears in data returned |
58
|
0
|
|
|
0
|
1
|
|
|
59
|
|
|
|
|
|
|
|
60
|
0
|
|
|
0
|
1
|
|
## Undocumented but appears in data returned |
61
|
|
|
|
|
|
|
|
62
|
0
|
|
|
0
|
1
|
|
|
63
|
|
|
|
|
|
|
{ |
64
|
0
|
|
|
0
|
1
|
|
return( shift->_set_get_class( 'transfer_data', |
65
|
|
|
|
|
|
|
{ |
66
|
0
|
|
|
0
|
1
|
|
amount_percent => { type => 'number' }, |
67
|
|
|
|
|
|
|
destination => { type => 'object', class => 'Net::API::Stripe::Connect::Account' }, |
68
|
0
|
|
|
0
|
1
|
|
}, @_ ) ); |
69
|
|
|
|
|
|
|
} |
70
|
0
|
|
|
0
|
1
|
|
|
71
|
|
|
|
|
|
|
## Undocumented but appears in data returned |
72
|
0
|
|
|
0
|
1
|
|
|
73
|
|
|
|
|
|
|
|
74
|
0
|
|
|
0
|
1
|
|
1; |
75
|
|
|
|
|
|
|
|
76
|
0
|
|
|
0
|
1
|
|
|
77
|
|
|
|
|
|
|
=encoding utf8 |
78
|
0
|
|
|
0
|
1
|
|
|
79
|
|
|
|
|
|
|
=head1 NAME |
80
|
0
|
|
|
0
|
1
|
|
|
81
|
|
|
|
|
|
|
Net::API::Stripe::Billing::Subscription::Schedule - A Stripe Subscription Schedule Object |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=head1 SYNOPSIS |
84
|
0
|
|
|
0
|
1
|
|
|
85
|
|
|
|
|
|
|
my $sched = $stripe->schedule({ |
86
|
|
|
|
|
|
|
customer => $customer_object, |
87
|
|
|
|
|
|
|
invoice_now => 1, |
88
|
0
|
|
|
0
|
1
|
|
end_behavior => 'release', |
89
|
|
|
|
|
|
|
}); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=head1 VERSION |
92
|
0
|
|
|
0
|
1
|
|
|
93
|
|
|
|
|
|
|
v0.101.0 |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=head1 DESCRIPTION |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
A subscription schedule allows you to create and manage the lifecycle of a subscription by predefining expected changes. |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
100
|
|
|
|
|
|
|
|
101
|
0
|
|
|
0
|
1
|
|
=head2 new( %ARG ) |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
Creates a new L<Net::API::Stripe::Billing::Subscription::Schedule> object. |
104
|
|
|
|
|
|
|
It may also take an hash like arguments, that also are method of the same name. |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head1 METHODS |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head2 id string |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
Unique identifier for the object. |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head2 object string, value is C<subscription_schedule> |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
String representing the object’s type. Objects of the same type share the same value. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=head2 application expandable |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
ID of the Connect Application that created the schedule. |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
When expanded this is an L<Net::API::Stripe::Connect::Account> object. |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=head2 canceled_at timestamp |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
Time at which the subscription schedule was canceled. Measured in seconds since the Unix epoch. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
=head2 completed_at timestamp |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
Time at which the subscription schedule was completed. Measured in seconds since the Unix epoch. |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=head2 created timestamp |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
Time at which the object was created. Measured in seconds since the Unix epoch. |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=head2 current_phase hash |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
Object representing the start and end dates for the current phase of the subscription schedule, if it is active. |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=over 4 |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=item I<end_date> timestamp |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=item I<start_date> timestamp |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=back |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=head2 customer string expandable |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
ID of the customer who owns the subscription schedule. When expanded, this is a L<Net::API::Stripe::Customer> object. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=head2 default_settings object |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
Object representing the subscription schedule's default settings. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
This is a L<Net::API::Stripe::Billing::Subscription> object. |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=head2 end_behavior string |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
Configures how the subscription schedule behaves when it ends. Possible values are I<release> or I<cancel> with the default being release. release will end the subscription schedule and keep the underlying subscription running.cancel will end the subscription schedule and cancel the underlying subscription. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head2 from_subscription string |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
Migrate an existing subscription to be managed by a subscription schedule. If this parameter is set, a subscription schedule will be created using the subscription’s plan(s), set to auto-renew using the subscription’s interval. When using this parameter, other parameters (such as phase values) cannot be set. To create a subscription schedule with other modifications, Stripe recommends making two separate API calls. |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
This is used only when creating a subscription schedule. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head2 invoice_now boolean |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
If the subscription schedule is active, indicates whether or not to generate a final invoice that contains any un-invoiced metered usage and new/pending proration invoice items. Defaults to true. |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
This is used only when cancelling a subscription schedule. |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head2 livemode boolean |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Has the value true if the object exists in live mode or the value false if the object exists in test mode. |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=head2 metadata hash |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=head2 phases array of objects |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Configuration for the subscription schedule's phases. |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
This is a L<Net::API::Stripe::Billing::Subscription> object. |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=head2 preserve_cancel_date boolean |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
Keep any cancellation on the subscription that the schedule has set. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
This is used only when making a Stripe api call to release a subscription schedule. |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head2 prorate boolean |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
This is only used when making B<update> or B<cancel>. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
When doing an update and if the update changes the current phase, indicates if the changes should be prorated. Defaults to true. |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
When cancelling the subscription schedule, if the subscription schedule is active, this indicates if the cancellation should be prorated. Defaults to true. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=head2 proration_behavior string |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
Determines how to handle prorations resulting from the billing_cycle_anchor. Valid values are I<create_prorations> or I<none>. |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
Passing I<create_prorations> will cause proration invoice items to be created when applicable. Prorations can be disabled by passing I<none>. If no value is passed, the default is create_prorations. |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
This property is not documented on Stripe api documentation, but appears in data returned as of 2020-12-02. |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=head2 released_at timestamp |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
Time at which the subscription schedule was released. Measured in seconds since the Unix epoch. |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=head2 released_subscription string |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
ID of the subscription once managed by the subscription schedule (if it is released). |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=head2 renewal_interval |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
This property was found in the data returned from Stripe, but is not documented yet as of 2020-12-03. |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=head2 start_date unix timestamp |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
When the subscription schedule starts. Stripe recommends using now so that it starts the subscription immediately. You can also use a Unix timestamp to backdate the subscription so that it starts on a past date, or set a future date for the subscription to start on. When you backdate, the billing_cycle_anchor of the subscription is equivalent to the start_date. |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
This is used only when creating a subscription schedule. |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
=head2 status string |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
The present status of the subscription schedule. Possible values are not_started, active, completed, released, and canceled. You can read more about the different states in Stripe behavior guide. |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=head2 subscription string expandable |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
ID of the subscription managed by the subscription schedule. When expanded, this is a L<Net::API::Stripe::Billing::Subscription> object. |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head2 tax_percent decimal (deprecated) |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
A non-negative decimal (with at most four decimal places) between 0 and 100. This represents the percentage of the subscription invoice subtotal that will be calculated and added as tax to the final amount in each billing period. For example, a plan which charges $10/month with a tax_percent of 20.0 will charge $12 per invoice. To unset a previously-set value, pass an empty string. This field has been deprecated and will be removed in a future API version, for further information view the migration docs for tax_rates. |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
This is an undocumented property for Subscription Schedule that usually belonging to L<Subscription|Net::API::Stripe::Billing::Subscription>, but that appears in data returned by Stripe. |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
=head2 test_clock expandable |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
ID of the test clock this subscription schedule belongs to. |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
When expanded this is an L<Net::API::Stripe::Billing::TestHelpersTestClock> object. |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
=head2 transfer_data hash |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
This is for Connect only. |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
The account (if any) the subscription’s payments will be attributed to for tax reporting, and where funds from each payment will be transferred to for each of the subscription’s invoices. |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
This is an undocumented property for Subscription Schedule that usually belonging to L<Subscription|Net::API::Stripe::Billing::Subscription>, but that appears in data returned by Stripe. |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
=over 4 |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=item I<amount_percent> decimal |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
A non-negative decimal between 0 and 100, with at most two decimal places. This represents the percentage of the subscription invoice subtotal that will be transferred to the destination account. By default, the entire amount is transferred to the destination. |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=item I<destination> string expandable |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
The account where funds from the payment will be transferred to upon payment success. |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
=back |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head2 trial_end timestamp |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
If the subscription has a trial, the end of that trial. |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
This is an undocumented property for Subscription Schedule that usually belonging to L<Subscription|Net::API::Stripe::Billing::Subscription>, but that appears in data returned by Stripe. |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=head1 API SAMPLE |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
{ |
275
|
|
|
|
|
|
|
"id": "sub_sched_fake123456789", |
276
|
|
|
|
|
|
|
"object": "subscription_schedule", |
277
|
|
|
|
|
|
|
"canceled_at": null, |
278
|
|
|
|
|
|
|
"completed_at": null, |
279
|
|
|
|
|
|
|
"created": 1577193148, |
280
|
|
|
|
|
|
|
"current_phase": null, |
281
|
|
|
|
|
|
|
"customer": "cus_fake123456789", |
282
|
|
|
|
|
|
|
"default_settings": { |
283
|
|
|
|
|
|
|
"billing_thresholds": null, |
284
|
|
|
|
|
|
|
"collection_method": "charge_automatically", |
285
|
|
|
|
|
|
|
"default_payment_method": null, |
286
|
|
|
|
|
|
|
"invoice_settings": null |
287
|
|
|
|
|
|
|
}, |
288
|
|
|
|
|
|
|
"end_behavior": "cancel", |
289
|
|
|
|
|
|
|
"livemode": false, |
290
|
|
|
|
|
|
|
"metadata": {}, |
291
|
|
|
|
|
|
|
"phases": [ |
292
|
|
|
|
|
|
|
{ |
293
|
|
|
|
|
|
|
"application_fee_percent": null, |
294
|
|
|
|
|
|
|
"billing_thresholds": null, |
295
|
|
|
|
|
|
|
"collection_method": null, |
296
|
|
|
|
|
|
|
"coupon": null, |
297
|
|
|
|
|
|
|
"default_payment_method": null, |
298
|
|
|
|
|
|
|
"default_tax_rates": [], |
299
|
|
|
|
|
|
|
"end_date": 1572481590, |
300
|
|
|
|
|
|
|
"invoice_settings": null, |
301
|
|
|
|
|
|
|
"plans": [ |
302
|
|
|
|
|
|
|
{ |
303
|
|
|
|
|
|
|
"billing_thresholds": null, |
304
|
|
|
|
|
|
|
"plan": "gold", |
305
|
|
|
|
|
|
|
"quantity": 1, |
306
|
|
|
|
|
|
|
"tax_rates": [] |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
], |
309
|
|
|
|
|
|
|
"start_date": 1541031990, |
310
|
|
|
|
|
|
|
"tax_percent": null, |
311
|
|
|
|
|
|
|
"trial_end": null |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
], |
314
|
|
|
|
|
|
|
"released_at": null, |
315
|
|
|
|
|
|
|
"released_subscription": null, |
316
|
|
|
|
|
|
|
"status": "not_started", |
317
|
|
|
|
|
|
|
"subscription": null |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=head1 HISTORY |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=head2 v0.1 |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
Initial version |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=head1 AUTHOR |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
Jacques Deguest E<lt>F<jack@deguest.jp>E<gt> |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=head1 SEE ALSO |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
Stripe API documentation: |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
L<https://stripe.com/docs/api>, L<https://stripe.com/docs/api/subscription_schedules/object>, L<https://stripe.com/docs/billing/subscriptions/subscription-schedules#managing> |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
See also L<use cases|https://stripe.com/docs/billing/subscriptions/subscription-schedules/use-cases> |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
Copyright (c) 2019-2020 DEGUEST Pte. Ltd. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
You can use, copy, modify and redistribute this package and associated |
343
|
|
|
|
|
|
|
files under the same terms as Perl itself. |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=cut |