This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||||||
2 | /** |
||||||
3 | * Bank transfer payment gateway |
||||||
4 | * |
||||||
5 | */ |
||||||
6 | |||||||
7 | defined( 'ABSPATH' ) || exit; |
||||||
8 | |||||||
9 | /** |
||||||
10 | * Bank transfer Payment Gateway class. |
||||||
11 | * |
||||||
12 | */ |
||||||
13 | class GetPaid_Bank_Transfer_Gateway extends GetPaid_Payment_Gateway { |
||||||
14 | |||||||
15 | /** |
||||||
16 | * Payment method id. |
||||||
17 | * |
||||||
18 | * @var string |
||||||
19 | */ |
||||||
20 | public $id = 'bank_transfer'; |
||||||
21 | |||||||
22 | /** |
||||||
23 | * An array of features that this gateway supports. |
||||||
24 | * |
||||||
25 | * @var array |
||||||
26 | */ |
||||||
27 | protected $supports = array( |
||||||
28 | 'subscription', |
||||||
29 | 'addons', |
||||||
30 | 'single_subscription_group', |
||||||
31 | 'multiple_subscription_groups', |
||||||
32 | 'subscription_date_change', |
||||||
33 | 'subscription_bill_times_change', |
||||||
34 | ); |
||||||
35 | |||||||
36 | /** |
||||||
37 | * Payment method order. |
||||||
38 | * |
||||||
39 | * @var int |
||||||
40 | */ |
||||||
41 | public $order = 8; |
||||||
42 | |||||||
43 | /** |
||||||
44 | * Bank transfer instructions. |
||||||
45 | */ |
||||||
46 | public $instructions; |
||||||
47 | |||||||
48 | /** |
||||||
49 | * Locale array. |
||||||
50 | */ |
||||||
51 | public $locale; |
||||||
52 | |||||||
53 | /** |
||||||
54 | * Class constructor. |
||||||
55 | */ |
||||||
56 | public function __construct() { |
||||||
57 | parent::__construct(); |
||||||
58 | |||||||
59 | $this->title = __( 'Direct bank transfer', 'invoicing' ); |
||||||
60 | $this->method_title = __( 'Bank transfer', 'invoicing' ); |
||||||
61 | $this->checkout_button_text = __( 'Proceed', 'invoicing' ); |
||||||
62 | $this->instructions = apply_filters( 'wpinv_bank_instructions', $this->get_option( 'info' ) ); |
||||||
63 | |||||||
64 | add_action( 'wpinv_receipt_end', array( $this, 'thankyou_page' ) ); |
||||||
65 | add_action( 'getpaid_invoice_line_items', array( $this, 'thankyou_page' ), 40 ); |
||||||
66 | add_action( 'wpinv_pdf_content_billing', array( $this, 'thankyou_page' ), 11 ); |
||||||
67 | add_action( 'wpinv_email_invoice_details', array( $this, 'email_instructions' ), 10, 3 ); |
||||||
68 | add_action( 'getpaid_should_renew_subscription', array( $this, 'maybe_renew_subscription' ), 12, 2 ); |
||||||
69 | add_action( 'getpaid_invoice_status_publish', array( $this, 'invoice_paid' ), 20 ); |
||||||
70 | |||||||
71 | add_filter( 'wpinv_' . $this->id . '_support_subscription', array( $this, 'supports_subscription' ), 20, 1 ); |
||||||
72 | add_filter( 'getpaid_' . $this->id . '_support_subscription', array( $this, 'supports_subscription' ), 20, 1 ); |
||||||
73 | add_filter( 'getpaid_' . $this->id . '_supports_subscription', array( $this, 'supports_subscription' ), 20, 1 ); |
||||||
74 | } |
||||||
75 | |||||||
76 | /** |
||||||
77 | * Check gateway supports for subscription. |
||||||
78 | * |
||||||
79 | * @since 2.8.24 |
||||||
80 | * |
||||||
81 | * @param bool $supports True if supports else False. |
||||||
82 | * @return bool True if supports else False. |
||||||
83 | */ |
||||||
84 | public function supports_subscription( $supports ) { |
||||||
85 | if ( $supports && (int) $this->get_option( 'no_subscription' ) ) { |
||||||
86 | $supports = false; |
||||||
87 | } |
||||||
88 | |||||||
89 | return $supports; |
||||||
90 | } |
||||||
91 | |||||||
92 | /** |
||||||
93 | * Process Payment. |
||||||
94 | * |
||||||
95 | * @param WPInv_Invoice $invoice Invoice. |
||||||
96 | * @param array $submission_data Posted checkout fields. |
||||||
97 | * @param GetPaid_Payment_Form_Submission $submission Checkout submission. |
||||||
98 | * @return array |
||||||
99 | */ |
||||||
100 | public function process_payment( $invoice, $submission_data, $submission ) { |
||||||
101 | |||||||
102 | // Add a transaction id. |
||||||
103 | $invoice->set_transaction_id( $invoice->generate_key( 'bt_' ) ); |
||||||
104 | |||||||
105 | // Set it as pending payment. |
||||||
106 | if ( ! $invoice->needs_payment() ) { |
||||||
107 | $invoice->mark_paid(); |
||||||
108 | } elseif ( ! $invoice->is_paid() ) { |
||||||
109 | $invoice->set_status( 'wpi-onhold' ); |
||||||
110 | } |
||||||
111 | |||||||
112 | // Save it. |
||||||
113 | $invoice->save(); |
||||||
114 | |||||||
115 | // Send to the success page. |
||||||
116 | wpinv_send_to_success_page( array( 'invoice_key' => $invoice->get_key() ) ); |
||||||
117 | |||||||
118 | } |
||||||
119 | |||||||
120 | /** |
||||||
121 | * Output for the order received page. |
||||||
122 | * |
||||||
123 | * @param WPInv_Invoice $invoice Invoice. |
||||||
124 | */ |
||||||
125 | public function thankyou_page( $invoice ) { |
||||||
126 | |||||||
127 | if ( 'bank_transfer' === $invoice->get_gateway() && $invoice->needs_payment() ) { |
||||||
128 | |||||||
129 | echo '<div class="mt-4 mb-2 getpaid-bank-transfer-details">' . PHP_EOL; |
||||||
130 | |||||||
131 | if ( ! empty( $this->instructions ) ) { |
||||||
132 | echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) ); |
||||||
133 | } |
||||||
134 | |||||||
135 | $this->bank_details( $invoice ); |
||||||
136 | |||||||
137 | echo '</div>'; |
||||||
138 | |||||||
139 | } |
||||||
140 | |||||||
141 | } |
||||||
142 | |||||||
143 | /** |
||||||
144 | * Add content to the WPI emails. |
||||||
145 | * |
||||||
146 | * @param WPInv_Invoice $invoice Invoice. |
||||||
147 | * @param string $email_type Email format: plain text or HTML. |
||||||
148 | * @param bool $sent_to_admin Sent to admin. |
||||||
149 | */ |
||||||
150 | public function email_instructions( $invoice, $email_type, $sent_to_admin ) { |
||||||
151 | |||||||
152 | if ( ! $sent_to_admin && 'bank_transfer' === $invoice->get_gateway() && $invoice->needs_payment() ) { |
||||||
153 | |||||||
154 | echo '<div class="wpi-email-row getpaid-bank-transfer-details">'; |
||||||
155 | |||||||
156 | if ( $this->instructions ) { |
||||||
157 | echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) . PHP_EOL ); |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
158 | } |
||||||
159 | |||||||
160 | $this->bank_details( $invoice ); |
||||||
161 | |||||||
162 | echo '</div>'; |
||||||
163 | |||||||
164 | } |
||||||
165 | |||||||
166 | } |
||||||
167 | |||||||
168 | /** |
||||||
169 | * Get bank details and place into a list format. |
||||||
170 | * |
||||||
171 | * @param WPInv_Invoice $invoice Invoice. |
||||||
172 | */ |
||||||
173 | protected function bank_details( $invoice ) { |
||||||
174 | |||||||
175 | // Get the invoice country and country $locale. |
||||||
176 | $country = $invoice->get_country(); |
||||||
177 | $locale = $this->get_country_locale(); |
||||||
178 | |||||||
179 | // Get shortcode label in the $locale array and use appropriate one. |
||||||
180 | $sortcode = isset( $locale[ $country ]['sortcode']['label'] ) ? $locale[ $country ]['sortcode']['label'] : __( 'Sort code', 'invoicing' ); |
||||||
181 | |||||||
182 | $bank_fields = array( |
||||||
183 | 'ac_name' => __( 'Account Name', 'invoicing' ), |
||||||
184 | 'ac_no' => __( 'Account Number', 'invoicing' ), |
||||||
185 | 'bank_name' => __( 'Bank Name', 'invoicing' ), |
||||||
186 | 'ifsc' => __( 'IFSC code', 'invoicing' ), |
||||||
187 | 'iban' => __( 'IBAN', 'invoicing' ), |
||||||
188 | 'bic' => __( 'BIC/Swift code', 'invoicing' ), |
||||||
189 | 'sort_code' => $sortcode, |
||||||
190 | ); |
||||||
191 | |||||||
192 | $bank_info = array(); |
||||||
193 | |||||||
194 | foreach ( $bank_fields as $field => $label ) { |
||||||
195 | $value = $this->get_option( $field ); |
||||||
196 | |||||||
197 | if ( ! empty( $value ) ) { |
||||||
198 | $bank_info[ $field ] = array( |
||||||
199 | 'label' => $label, |
||||||
200 | 'value' => $value, |
||||||
201 | ); |
||||||
202 | } |
||||||
203 | } |
||||||
204 | |||||||
205 | $bank_info = apply_filters( 'wpinv_bank_info', $bank_info, $invoice ); |
||||||
206 | |||||||
207 | if ( empty( $bank_info ) ) { |
||||||
208 | return; |
||||||
209 | } |
||||||
210 | |||||||
211 | echo '<h3 class="getpaid-bank-transfer-title"> ' . esc_html( apply_filters( 'wpinv_receipt_bank_details_title', __( 'Bank Details', 'invoicing' ), $invoice ) ) . '</h3>' . PHP_EOL; |
||||||
212 | |||||||
213 | echo '<table class="table table-bordered getpaid-bank-transfer-details">' . PHP_EOL; |
||||||
214 | |||||||
215 | foreach ( $bank_info as $key => $data ) { |
||||||
216 | echo "<tr class='getpaid-bank-transfer-" . esc_attr( $key ) . "'><th class='font-weight-bold'>" . wp_kses_post( $data['label'] ) . "</th><td class='w-75'>" . wp_kses_post( wptexturize( $data['value'] ) ) . '</td></tr>' . PHP_EOL; |
||||||
217 | } |
||||||
218 | |||||||
219 | echo '</table>'; |
||||||
220 | |||||||
221 | } |
||||||
222 | |||||||
223 | /** |
||||||
224 | * Get country locale if localized. |
||||||
225 | * |
||||||
226 | * @return array |
||||||
227 | */ |
||||||
228 | public function get_country_locale() { |
||||||
229 | |||||||
230 | if ( empty( $this->locale ) ) { |
||||||
231 | |||||||
232 | // Locale information to be used - only those that are not 'Sort Code'. |
||||||
233 | $this->locale = apply_filters( |
||||||
234 | 'getpaid_get_bank_transfer_locale', |
||||||
235 | array( |
||||||
236 | 'AU' => array( |
||||||
237 | 'sortcode' => array( |
||||||
238 | 'label' => __( 'BSB', 'invoicing' ), |
||||||
239 | ), |
||||||
240 | ), |
||||||
241 | 'CA' => array( |
||||||
242 | 'sortcode' => array( |
||||||
243 | 'label' => __( 'Bank transit number', 'invoicing' ), |
||||||
244 | ), |
||||||
245 | ), |
||||||
246 | 'IN' => array( |
||||||
247 | 'sortcode' => array( |
||||||
248 | 'label' => __( 'IFSC', 'invoicing' ), |
||||||
249 | ), |
||||||
250 | ), |
||||||
251 | 'IT' => array( |
||||||
252 | 'sortcode' => array( |
||||||
253 | 'label' => __( 'Branch sort', 'invoicing' ), |
||||||
254 | ), |
||||||
255 | ), |
||||||
256 | 'NZ' => array( |
||||||
257 | 'sortcode' => array( |
||||||
258 | 'label' => __( 'Bank code', 'invoicing' ), |
||||||
259 | ), |
||||||
260 | ), |
||||||
261 | 'SE' => array( |
||||||
262 | 'sortcode' => array( |
||||||
263 | 'label' => __( 'Bank code', 'invoicing' ), |
||||||
264 | ), |
||||||
265 | ), |
||||||
266 | 'US' => array( |
||||||
267 | 'sortcode' => array( |
||||||
268 | 'label' => __( 'Routing number', 'invoicing' ), |
||||||
269 | ), |
||||||
270 | ), |
||||||
271 | 'ZA' => array( |
||||||
272 | 'sortcode' => array( |
||||||
273 | 'label' => __( 'Branch code', 'invoicing' ), |
||||||
274 | ), |
||||||
275 | ), |
||||||
276 | ) |
||||||
277 | ); |
||||||
278 | |||||||
279 | } |
||||||
280 | |||||||
281 | return $this->locale; |
||||||
282 | |||||||
283 | } |
||||||
284 | |||||||
285 | /** |
||||||
286 | * Filters the gateway settings. |
||||||
287 | * |
||||||
288 | * @param array $admin_settings |
||||||
289 | */ |
||||||
290 | public function admin_settings( $admin_settings ) { |
||||||
291 | $admin_settings['bank_transfer_desc']['std'] = __( "Make your payment directly into our bank account. Please use your Invoice Number as the payment reference. Your invoice won't be processed until the funds have cleared in our account.", 'invoicing' ); |
||||||
292 | $admin_settings['bank_transfer_active']['desc'] = __( 'Enable bank transfer', 'invoicing' ); |
||||||
293 | |||||||
294 | $_settings = array(); |
||||||
295 | |||||||
296 | foreach ( $admin_settings as $key => $setting ) { |
||||||
297 | $_settings[ $key ] = $setting; |
||||||
298 | |||||||
299 | if ( $key == 'bank_transfer_active' ) { |
||||||
300 | // Enable/disable subscriptions setting. |
||||||
301 | $_settings['bank_transfer_no_subscription'] = array( |
||||||
302 | 'id' => 'bank_transfer_no_subscription', |
||||||
303 | 'type' => 'checkbox', |
||||||
304 | 'name' => __( 'Disable Subscriptions', 'invoicing' ), |
||||||
305 | 'desc' => __( 'Tick to disable support for recurring items.', 'invoicing' ), |
||||||
306 | 'std' => 0 |
||||||
307 | ); |
||||||
308 | } |
||||||
309 | } |
||||||
310 | |||||||
311 | $admin_settings = $_settings; |
||||||
312 | |||||||
313 | $locale = $this->get_country_locale(); |
||||||
314 | |||||||
315 | // Get sortcode label in the $locale array and use appropriate one. |
||||||
316 | $country = wpinv_default_billing_country(); |
||||||
317 | $sortcode = isset( $locale[ $country ]['sortcode']['label'] ) ? $locale[ $country ]['sortcode']['label'] : __( 'Sort code', 'invoicing' ); |
||||||
318 | |||||||
319 | $admin_settings['bank_transfer_ac_name'] = array( |
||||||
320 | 'type' => 'text', |
||||||
321 | 'id' => 'bank_transfer_ac_name', |
||||||
322 | 'name' => __( 'Account Name', 'invoicing' ), |
||||||
323 | ); |
||||||
324 | |||||||
325 | $admin_settings['bank_transfer_ac_no'] = array( |
||||||
326 | 'type' => 'text', |
||||||
327 | 'id' => 'bank_transfer_ac_no', |
||||||
328 | 'name' => __( 'Account Number', 'invoicing' ), |
||||||
329 | ); |
||||||
330 | |||||||
331 | $admin_settings['bank_transfer_bank_name'] = array( |
||||||
332 | 'type' => 'text', |
||||||
333 | 'id' => 'bank_transfer_bank_name', |
||||||
334 | 'name' => __( 'Bank Name', 'invoicing' ), |
||||||
335 | ); |
||||||
336 | |||||||
337 | $admin_settings['bank_transfer_ifsc'] = array( |
||||||
338 | 'type' => 'text', |
||||||
339 | 'id' => 'bank_transfer_ifsc', |
||||||
340 | 'name' => __( 'IFSC Code', 'invoicing' ), |
||||||
341 | ); |
||||||
342 | |||||||
343 | $admin_settings['bank_transfer_iban'] = array( |
||||||
344 | 'type' => 'text', |
||||||
345 | 'id' => 'bank_transfer_iban', |
||||||
346 | 'name' => __( 'IBAN', 'invoicing' ), |
||||||
347 | ); |
||||||
348 | |||||||
349 | $admin_settings['bank_transfer_bic'] = array( |
||||||
350 | 'type' => 'text', |
||||||
351 | 'id' => 'bank_transfer_bic', |
||||||
352 | 'name' => __( 'BIC/Swift Code', 'invoicing' ), |
||||||
353 | ); |
||||||
354 | |||||||
355 | $admin_settings['bank_transfer_sort_code'] = array( |
||||||
356 | 'type' => 'text', |
||||||
357 | 'id' => 'bank_transfer_sort_code', |
||||||
358 | 'name' => $sortcode, |
||||||
359 | ); |
||||||
360 | |||||||
361 | $admin_settings['bank_transfer_info'] = array( |
||||||
362 | 'id' => 'bank_transfer_info', |
||||||
363 | 'name' => __( 'Instructions', 'invoicing' ), |
||||||
364 | 'desc' => __( 'Instructions that will be added to the thank you page and emails.', 'invoicing' ), |
||||||
365 | 'type' => 'textarea', |
||||||
366 | 'std' => __( "Make your payment directly into our bank account. Please use your Invoice Number as the payment reference. Your invoice won't be processed until the funds have cleared in our account.", 'invoicing' ), |
||||||
367 | 'cols' => 50, |
||||||
368 | 'rows' => 5, |
||||||
369 | ); |
||||||
370 | |||||||
371 | return $admin_settings; |
||||||
372 | } |
||||||
373 | |||||||
374 | /** |
||||||
375 | * Processes invoice addons. |
||||||
376 | * |
||||||
377 | * @param WPInv_Invoice $invoice |
||||||
378 | * @param GetPaid_Form_Item[] $items |
||||||
379 | * @return WPInv_Invoice |
||||||
380 | */ |
||||||
381 | public function process_addons( $invoice, $items ) { |
||||||
382 | |||||||
383 | foreach ( $items as $item ) { |
||||||
384 | $invoice->add_item( $item ); |
||||||
385 | } |
||||||
386 | |||||||
387 | $invoice->recalculate_total(); |
||||||
388 | $invoice->save(); |
||||||
389 | } |
||||||
390 | |||||||
391 | /** |
||||||
392 | * (Maybe) renews a bank transfer subscription profile. |
||||||
393 | * |
||||||
394 | * |
||||||
395 | * @param WPInv_Subscription $subscription |
||||||
396 | */ |
||||||
397 | public function maybe_renew_subscription( $subscription, $parent_invoice ) { |
||||||
398 | // Ensure its our subscription && it's active. |
||||||
399 | if ( ! empty( $parent_invoice ) && $this->id === $parent_invoice->get_gateway() && $subscription->has_status( 'active trialling' ) ) { |
||||||
400 | add_filter( 'getpaid_invoice_notifications_is_payment_form_invoice', array( $this, 'force_is_payment_form_invoice' ), 10, 2 ); |
||||||
401 | |||||||
402 | $invoice = $subscription->create_payment(); |
||||||
403 | |||||||
404 | if ( ! empty( $invoice ) ) { |
||||||
405 | $is_logged_in = is_user_logged_in(); |
||||||
406 | |||||||
407 | // Cron run. |
||||||
408 | if ( ! $is_logged_in ) { |
||||||
409 | $note = wp_sprintf( __( 'Renewal %1$s created with the status "%2$s".', 'invoicing' ), $invoice->get_invoice_quote_type(), wpinv_status_nicename( $invoice->get_status(), $invoice ) ); |
||||||
410 | |||||||
411 | $invoice->add_note( $note, false, $is_logged_in, ! $is_logged_in ); |
||||||
412 | } |
||||||
413 | } |
||||||
414 | |||||||
415 | remove_filter( 'getpaid_invoice_notifications_is_payment_form_invoice', array( $this, 'force_is_payment_form_invoice' ), 10, 2 ); |
||||||
0 ignored issues
–
show
The call to
remove_filter() has too many arguments starting with 2 .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
416 | } |
||||||
417 | } |
||||||
418 | |||||||
419 | /** |
||||||
420 | * Process a bank transfer payment. |
||||||
421 | * |
||||||
422 | * |
||||||
423 | * @param WPInv_Invoice $invoice |
||||||
424 | */ |
||||||
425 | public function invoice_paid( $invoice ) { |
||||||
426 | |||||||
427 | // Abort if not paid by bank transfer. |
||||||
428 | if ( $this->id !== $invoice->get_gateway() || ! $invoice->is_recurring() ) { |
||||||
429 | return; |
||||||
430 | } |
||||||
431 | |||||||
432 | // Is it a parent payment? |
||||||
433 | if ( 0 == $invoice->get_parent_id() ) { |
||||||
434 | |||||||
435 | // (Maybe) activate subscriptions. |
||||||
436 | $subscriptions = getpaid_get_invoice_subscriptions( $invoice ); |
||||||
437 | |||||||
438 | if ( ! empty( $subscriptions ) ) { |
||||||
439 | $subscriptions = is_array( $subscriptions ) ? $subscriptions : array( $subscriptions ); |
||||||
0 ignored issues
–
show
|
|||||||
440 | |||||||
441 | foreach ( $subscriptions as $subscription ) { |
||||||
442 | if ( $subscription->exists() ) { |
||||||
443 | $duration = strtotime( $subscription->get_expiration() ) - strtotime( $subscription->get_date_created() ); |
||||||
444 | $expiry = gmdate( 'Y-m-d H:i:s', ( current_time( 'timestamp' ) + $duration ) ); |
||||||
445 | |||||||
446 | $subscription->set_next_renewal_date( $expiry ); |
||||||
447 | $subscription->set_date_created( current_time( 'mysql' ) ); |
||||||
448 | $subscription->set_profile_id( 'bt_sub_' . $invoice->get_id() . '_' . $subscription->get_id() ); |
||||||
449 | $subscription->activate(); |
||||||
450 | } |
||||||
451 | } |
||||||
452 | } |
||||||
453 | } else { |
||||||
454 | |||||||
455 | $subscription = getpaid_get_subscription( $invoice->get_subscription_id() ); |
||||||
456 | |||||||
457 | // Renew the subscription. |
||||||
458 | if ( $subscription && $subscription->exists() ) { |
||||||
459 | $subscription->add_payment( array(), $invoice ); |
||||||
460 | $subscription->renew( strtotime( $invoice->get_date_created() ) ); |
||||||
461 | } |
||||||
462 | } |
||||||
463 | |||||||
464 | } |
||||||
465 | |||||||
466 | /** |
||||||
467 | * Force created from payment false to allow email for auto renewal generation invoice. |
||||||
468 | * |
||||||
469 | * @since 2.8.11 |
||||||
470 | * |
||||||
471 | * @param bool $is_payment_form_invoice True when invoice created via payment form else false. |
||||||
472 | * @param int $invoice Invoice ID. |
||||||
473 | * @return bool True when invoice created via payment form else false. |
||||||
474 | */ |
||||||
475 | public function force_is_payment_form_invoice( $is_payment_form_invoice, $invoice ) { |
||||||
0 ignored issues
–
show
The parameter
$invoice is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
476 | if ( $is_payment_form_invoice ) { |
||||||
477 | $is_payment_form_invoice = false; |
||||||
478 | } |
||||||
479 | |||||||
480 | return $is_payment_form_invoice; |
||||||
481 | } |
||||||
482 | |||||||
483 | } |
||||||
484 |