Test Failed
Pull Request — master (#2077)
by
unknown
05:53
created

misc-functions.php ➔ give_is_zero_based_currency()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 26
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 20
nc 2
nop 0
dl 0
loc 26
ccs 0
cts 0
cp 0
crap 6
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * Misc Functions
4
 *
5
 * @package     Give
6
 * @subpackage  Functions
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Is Test Mode Enabled.
19
 *
20
 * @since 1.0
21
 *
22
 * @return bool $ret True if return mode is enabled, false otherwise
23
 */
24
function give_is_test_mode() {
25 52
26
	$ret = give_is_setting_enabled( give_get_option( 'test_mode' ) );
27 52
28
	return (bool) apply_filters( 'give_is_test_mode', $ret );
29 52
30
}
31
32
/**
33
 * Get the set currency
34
 *
35
 * @since 1.0
36
 * @return string The currency code
37
 */
38
function give_get_currency() {
39 55
40 55
	$currency = give_get_option( 'currency', 'USD' );
41
42 55
	return apply_filters( 'give_currency', $currency );
43
}
44
45
/**
46
 * Get the set currency position
47
 *
48
 * @since 1.3.6
49
 *
50
 * @return string The currency code
51
 */
52
function give_get_currency_position() {
53 1
54 1
	$currency_pos = give_get_option( 'currency_position', 'before' );
55
56 1
	return apply_filters( 'give_currency_position', $currency_pos );
57
}
58
59
60
/**
61
 * Get Currencies
62
 *
63
 * @since 1.0
64
 * @return array $currencies A list of the available currencies
65
 */
66
67
function give_get_currencies() {
68
	$currencies = array(
69
		'USD'  => __( 'US Dollars ($)', 'give' ),
70
		'EUR'  => __( 'Euros (€)', 'give' ),
71
		'GBP'  => __( 'Pounds Sterling (£)', 'give' ),
72
		'AUD'  => __( 'Australian Dollars ($)', 'give' ),
73
		'BRL'  => __( 'Brazilian Real (R$)', 'give' ),
74
		'CAD'  => __( 'Canadian Dollars ($)', 'give' ),
75
		'CZK'  => __( 'Czech Koruna (Kč)', 'give' ),
76
		'DKK'  => __( 'Danish Krone (kr.)', 'give' ),
77
		'HKD'  => __( 'Hong Kong Dollar ($)', 'give' ),
78
		'HUF'  => __( 'Hungarian Forint (Ft)', 'give' ),
79
		'ILS'  => __( 'Israeli Shekel (₪)', 'give' ),
80
		'JPY'  => __( 'Japanese Yen (¥)', 'give' ),
81
		'MYR'  => __( 'Malaysian Ringgits (RM)', 'give' ),
82
		'MXN'  => __( 'Mexican Peso ($)', 'give' ),
83
		'MAD'  => __( 'Moroccan Dirham (&#x2e;&#x62f;&#x2e;&#x645;)', 'give' ),
84
		'NZD'  => __( 'New Zealand Dollar ($)', 'give' ),
85
		'NOK'  => __( 'Norwegian Krone (Kr.)', 'give' ),
86
		'PHP'  => __( 'Philippine Pesos (₱)', 'give' ),
87
		'PLN'  => __( 'Polish Zloty (zł)', 'give' ),
88
		'SGD'  => __( 'Singapore Dollar ($)', 'give' ),
89
		'KRW'  => __( 'South Korean Won (₩)', 'give' ),
90
		'ZAR'  => __( 'South African Rand (R)', 'give' ),
91
		'SEK'  => __( 'Swedish Krona (kr)', 'give' ),
92
		'CHF'  => __( 'Swiss Franc (CHF)', 'give' ),
93
		'TWD'  => __( 'Taiwan New Dollars (NT$)', 'give' ),
94
		'THB'  => __( 'Thai Baht (฿)', 'give' ),
95
		'INR'  => __( 'Indian Rupee (₹)', 'give' ),
96
		'TRY'  => __( 'Turkish Lira (₺)', 'give' ),
97
		'RIAL' => __( 'Iranian Rial (﷼)', 'give' ),
98
		'RUB'  => __( 'Russian Rubles (руб)', 'give' ),
99
	);
100
101
	return apply_filters( 'give_currencies', $currencies );
102
}
103
104
105
/**
106
 * Give Currency Symbol
107
 *
108
 * Given a currency determine the symbol to use. If no currency given, site default is used. If no symbol is determine,
109
 * the currency string is returned.
110
 *
111
 * @since      1.0
112
 *
113
 * @param  string $currency The currency string.
114
 * @param  bool $decode_currency Option to HTML decode the currency symbol.
115
 *
116
 * @return string           The symbol to use for the currency
117
 */
118 45
function give_currency_symbol( $currency = '', $decode_currency = false ) {
119
120
	if ( empty( $currency ) ) {
121
		$currency = give_get_currency();
122 45
	}
123
	switch ( $currency ) :
124
		case 'GBP' :
125 45
			$symbol = '&pound;';
126
			break;
127
		case 'BRL' :
128 45
			$symbol = '&#82;&#36;';
129
			break;
130
		case 'EUR' :
131 45
			$symbol = '&euro;';
132
			break;
133
		case 'NOK' :
134 45
			$symbol = '&#107;&#114;.';
135
			break;
136
		case 'INR' :
137 45
			$symbol = '&#8377;';
138 45
			break;
139 45
		case 'USD' :
140 45
		case 'AUD' :
141 45
		case 'CAD' :
142 45
		case 'HKD' :
143 45
		case 'MXN' :
144 45
		case 'SGD' :
145
			$symbol = '&#36;';
146
			break;
147
		case 'JPY' :
148
			$symbol = '&yen;';
149
			break;
150
		case 'THB' :
151
			$symbol = '&#3647;';
152
			break;
153
		case 'TRY' :
154
			$symbol = '&#8378;';
155
			break;
156
		case 'TWD' :
157
			$symbol = '&#78;&#84;&#36;';
158
			break;
159
		case 'ILS' :
160
			$symbol = '&#8362;';
161
			break;
162
		case 'RIAL' :
163
			$symbol = '&#xfdfc;';
164
			break;
165
		case 'RUB' :
166
			$symbol = '&#8381;';
167
			break;
168
		case 'DKK' :
169
		case 'SEK' :
170
			$symbol = '&nbsp;kr.&nbsp;';
171
			break;
172
		case 'PLN' :
173
			$symbol = '&#122;&#322;';
174
			break;
175
		case 'PHP' :
176
			$symbol = '&#8369;';
177
			break;
178
		case 'MYR' :
179
			$symbol = '&#82;&#77;';
180
			break;
181
		case 'HUF' :
182
			$symbol = '&#70;&#116;';
183
			break;
184
		case 'CZK' :
185
			$symbol = '&#75;&#269;';
186
			break;
187
		case 'KRW' :
188
			$symbol = '&#8361;';
189
			break;
190
		case 'ZAR' :
191
			$symbol = '&#82;';
192
			break;
193
		case 'MAD' :
194
			$symbol = '&#x2e;&#x62f;&#x2e;&#x645;';
195
			break;
196
		default :
197
			$symbol = $currency;
198
			break;
199
	endswitch;
200 45
201
	$symbol = ( ! $decode_currency ? $symbol : html_entity_decode( $symbol ) );
202
203
	return apply_filters( 'give_currency_symbol', $symbol, $currency );
204
}
205
206
207
/**
208
 * Get currency name.
209
 *
210
 * @since 1.8.8
211
 *
212 6
 * @param string $currency_code
213
 *
214
 * @return string
215 6
 */
216
function give_get_currency_name( $currency_code ) {
217
	$currency_name  = '';
218 6
	$currency_names = give_get_currencies();
219
220
	if ( $currency_code && array_key_exists( $currency_code, $currency_names ) ) {
221
		$currency_name = explode( '(', $currency_names[ $currency_code ] );
222
		$currency_name = trim( current( $currency_name ) );
223
	}
224
225
	return apply_filters( 'give_currency_name', $currency_name, $currency_code );
226
}
227
228
229
/**
230
 * Get the current page URL.
231
 *
232
 * @since 1.0
233
 * @return string $current_url Current page URL.
234
 */
235
function give_get_current_page_url() {
236
237
	global $wp;
238
239
	if ( get_option( 'permalink_structure' ) ) {
240
		$base = trailingslashit( home_url( $wp->request ) );
241
	} else {
242
		$base = add_query_arg( $wp->query_string, '', trailingslashit( home_url( $wp->request ) ) );
243
		$base = remove_query_arg( array( 'post_type', 'name' ), $base );
244
	}
245
246
	$scheme      = is_ssl() ? 'https' : 'http';
247
	$current_uri = set_url_scheme( $base, $scheme );
248
249
	if ( is_front_page() ) {
250
		$current_uri = home_url( '/' );
251
	}
252
253
	return apply_filters( 'give_get_current_page_url', $current_uri );
254
255
}
256
257
258
/**
259
 * Verify credit card numbers live?
260
 *
261
 * @since 1.0
262
 *
263
 * @return bool $ret True is verify credit cards is live
264
 */
265
function give_is_cc_verify_enabled() {
266
267
	$ret = true;
268
269
	/**
270
	 * Enable if use a single gateway other than PayPal or Manual. We have to assume it accepts credit cards.
271
	 * Enable if using more than one gateway if they are not both PayPal and manual, again assuming credit card usage.
272
	 */
273
	$gateways = give_get_enabled_payment_gateways();
274
275
	if ( count( $gateways ) == 1 && ! isset( $gateways['paypal'] ) && ! isset( $gateways['manual'] ) ) {
0 ignored issues
show
introduced by
Found "== 1". Use Yoda Condition checks, you must
Loading history...
276
		$ret = true;
277
	} elseif ( count( $gateways ) == 1 ) {
0 ignored issues
show
introduced by
Found "== 1". Use Yoda Condition checks, you must
Loading history...
278
		$ret = false;
279
	} elseif ( count( $gateways ) == 2 && isset( $gateways['paypal'] ) && isset( $gateways['manual'] ) ) {
0 ignored issues
show
introduced by
Found "== 2". Use Yoda Condition checks, you must
Loading history...
280
		$ret = false;
281
	}
282
283
	return (bool) apply_filters( 'give_verify_credit_cards', $ret );
284
}
285
286
/**
287
 * Retrieve timezone.
288
 *
289
 * @since 1.0
290
 * @return string $timezone The timezone ID.
291
 */
292
function give_get_timezone_id() {
293
294
	// if site timezone string exists, return it.
295
	if ( $timezone = get_option( 'timezone_string' ) ) {
296
		return $timezone;
297
	}
298
299
	// get UTC offset, if it isn't set return UTC.
300 52
	if ( ! ( $utc_offset = 3600 * get_option( 'gmt_offset', 0 ) ) ) {
301
		return 'UTC';
302 52
	}
303
304
	// attempt to guess the timezone string from the UTC offset.
305 52
	$timezone = timezone_name_from_abbr( '', $utc_offset );
306
307
	// last try, guess timezone string manually.
308 52
	if ( $timezone === false ) {
0 ignored issues
show
introduced by
Found "=== false". Use Yoda Condition checks, you must
Loading history...
309 52
310 52
		$is_dst = date( 'I' );
311
312 52
		foreach ( timezone_abbreviations_list() as $abbr ) {
313
			foreach ( $abbr as $city ) {
314
				if ( $city['dst'] == $is_dst && $city['offset'] == $utc_offset ) {
315
					return $city['timezone_id'];
316
				}
317
			}
318
		}
319
	}
320
321
	// Fallback.
322
	return 'UTC';
323
}
324
325
326
/**
327
 * Get User IP
328
 *
329
 * Returns the IP address of the current visitor
330
 *
331
 * @since 1.0
332
 * @return string $ip User's IP address
333
 */
334
function give_get_ip() {
335
336
	$ip = '127.0.0.1';
337
338
	if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
339
		// check ip from share internet
340
		$ip = $_SERVER['HTTP_CLIENT_IP'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
341
	} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
342
		// to check ip is pass from proxy
343
		$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
344
	} elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) {
0 ignored issues
show
introduced by
Due to using Batcache, server side based client related logic will not work, use JS instead.
Loading history...
345
		$ip = $_SERVER['REMOTE_ADDR'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
introduced by
Due to using Batcache, server side based client related logic will not work, use JS instead.
Loading history...
346
	}
347
348
	return apply_filters( 'give_get_ip', $ip );
349
}
350
351
352
/**
353
 * Store Donation Data in Sessions
354
 *
355
 * Used for storing info about donation
356
 *
357
 * @since 1.0
358
 *
359
 * @param $purchase_data
360
 *
361
 * @uses  Give()->session->set()
362
 */
363
function give_set_purchase_session( $purchase_data = array() ) {
364
	Give()->session->set( 'give_purchase', $purchase_data );
0 ignored issues
show
Documentation introduced by
$purchase_data is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
365
	Give()->session->set( 'give_email', $purchase_data['user_email'] );
366
}
367
368
/**
369
 * Retrieve Donation Data from Session
370
 *
371
 * Used for retrieving info about donation
372
 * after completing a donation
373
 *
374
 * @since 1.0
375
 * @uses  Give()->session->get()
376
 * @return mixed array | false
377
 */
378
function give_get_purchase_session() {
379
	return Give()->session->get( 'give_purchase' );
380
}
381
382
/**
383
 * Get Donation Summary
384
 *
385
 * Creates a donation summary for payment gateways from the donation data before the payment is created in the database.
386
 *
387
 * @since       1.8.12
388
 *
389
 * @param array $donation_data
390
 * @param bool $name_and_email
391
 * @param int $length
392
 *
393
 * @return string
394
 */
395
function give_payment_gateway_donation_summary( $donation_data, $name_and_email = true, $length = 255 ) {
396
397
	$form_id = isset( $donation_data['post_data']['give-form-id'] ) ? $donation_data['post_data']['give-form-id'] : '';
398
399
	// Form title.
400
	$summary = ( -! empty( $donation_data['post_data']['give-form-title'] ) ? $donation_data['post_data']['give-form-title'] : __( 'Untitled donation form', 'give' ) );
0 ignored issues
show
introduced by
Expected 1 space before "!"; 0 found
Loading history...
401
402
	// Form multilevel if applicable.
403
	if ( isset( $donation_data['post_data']['give-price-id'] ) ) {
404
		$summary .= ': ' . give_get_price_option_name( $form_id, $donation_data['post_data']['give-price-id'] );
405
	}
406
407
	// Add Donor's name + email if requested.
408
	if ( $name_and_email ) {
409
410
		// First name
411 View Code Duplication
		if ( isset( $donation_data['user_info']['first_name'] ) && ! empty( $donation_data['user_info']['first_name'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
412
			$summary .= ' - ' . $donation_data['user_info']['first_name'];
413
		}
414
415 View Code Duplication
		if ( isset( $donation_data['user_info']['last_name'] ) && ! empty( $donation_data['user_info']['last_name'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
416
			$summary .= ' ' . $donation_data['user_info']['last_name'];
417
		}
418
419
		$summary .= ' (' . $donation_data['user_email'] . ')';
420
	}
421
422
	// Cut the length
423
	$summary = substr( $summary, 0, $length );
424
425
	return apply_filters( 'give_payment_gateway_donation_summary', $summary );
426
}
427
428
429
/**
430
 * Get user host
431
 *
432
 * Returns the webhost this site is using if possible
433
 *
434
 * @since 1.0
435
 * @return string $host if detected, false otherwise
436
 */
437
function give_get_host() {
438
	$host = false;
0 ignored issues
show
Unused Code introduced by
$host is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
439
440
	if ( defined( 'WPE_APIKEY' ) ) {
441
		$host = 'WP Engine';
442
	} elseif ( defined( 'PAGELYBIN' ) ) {
443
		$host = 'Pagely';
444
	} elseif ( DB_HOST == 'localhost:/tmp/mysql5.sock' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
445
		$host = 'ICDSoft';
446
	} elseif ( DB_HOST == 'mysqlv5' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
447
		$host = 'NetworkSolutions';
448
	} elseif ( strpos( DB_HOST, 'ipagemysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
449
		$host = 'iPage';
450
	} elseif ( strpos( DB_HOST, 'ipowermysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
451
		$host = 'IPower';
452
	} elseif ( strpos( DB_HOST, '.gridserver.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
453
		$host = 'MediaTemple Grid';
454
	} elseif ( strpos( DB_HOST, '.pair.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
455
		$host = 'pair Networks';
456
	} elseif ( strpos( DB_HOST, '.stabletransit.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
457
		$host = 'Rackspace Cloud';
458
	} elseif ( strpos( DB_HOST, '.sysfix.eu' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
459
		$host = 'SysFix.eu Power Hosting';
460
	} elseif ( strpos( $_SERVER['SERVER_NAME'], 'Flywheel' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
461
		$host = 'Flywheel';
462
	} else {
463
		// Adding a general fallback for data gathering
464
		$host = 'DBH: ' . DB_HOST . ', SRV: ' . $_SERVER['SERVER_NAME'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
465
	}
466
467
	return $host;
468
}
469
470
471
/**
472
 * Check site host
473
 *
474
 * @since 1.0
475
 *
476
 * @param bool /string $host The host to check
477
 *
478
 * @return bool true if host matches, false if not
479
 */
480
function give_is_host( $host = false ) {
481
482
	$return = false;
483
484
	if ( $host ) {
485
		$host = str_replace( ' ', '', strtolower( $host ) );
486
487
		switch ( $host ) {
488
			case 'wpengine':
489
				if ( defined( 'WPE_APIKEY' ) ) {
490
					$return = true;
491
				}
492
				break;
493
			case 'pagely':
494
				if ( defined( 'PAGELYBIN' ) ) {
495
					$return = true;
496
				}
497
				break;
498
			case 'icdsoft':
499
				if ( DB_HOST == 'localhost:/tmp/mysql5.sock' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
500
					$return = true;
501
				}
502
				break;
503
			case 'networksolutions':
504
				if ( DB_HOST == 'mysqlv5' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
505
					$return = true;
506
				}
507
				break;
508
			case 'ipage':
509
				if ( strpos( DB_HOST, 'ipagemysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
510
					$return = true;
511
				}
512
				break;
513
			case 'ipower':
514
				if ( strpos( DB_HOST, 'ipowermysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
515
					$return = true;
516 1
				}
517
				break;
518 1
			case 'mediatemplegrid':
519
				if ( strpos( DB_HOST, '.gridserver.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
520
					$return = true;
521 1
				}
522
				break;
523
			case 'pairnetworks':
524
				if ( strpos( DB_HOST, '.pair.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
525
					$return = true;
526
				}
527
				break;
528
			case 'rackspacecloud':
529
				if ( strpos( DB_HOST, '.stabletransit.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
530
					$return = true;
531
				}
532 1
				break;
533
			case 'sysfix.eu':
534
			case 'sysfix.eupowerhosting':
535
				if ( strpos( DB_HOST, '.sysfix.eu' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
536
					$return = true;
537
				}
538
				break;
539
			case 'flywheel':
540
				if ( strpos( $_SERVER['SERVER_NAME'], 'Flywheel' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
541
					$return = true;
542
				}
543
				break;
544
			default:
545
				$return = false;
546
		}// End switch().
547
	}// End if().
548
549
	return $return;
550
}
551
552
/**
553
 * Marks a function as deprecated and informs when it has been used.
554
 *
555
 * There is a hook give_deprecated_function_run that will be called that can be used
556
 * to get the backtrace up to what file and function called the deprecated
557
 * function.
558
 *
559
 * The current behavior is to trigger a user error if WP_DEBUG is true.
560
 *
561
 * This function is to be used in every function that is deprecated.
562
 *
563
 * @uses do_action() Calls 'give_deprecated_function_run' and passes the function name, what to use instead,
564
 *   and the version the function was deprecated in.
565
 * @uses apply_filters() Calls 'give_deprecated_function_trigger_error' and expects boolean value of true to do
566
 *   trigger or false to not trigger error.
567
 *
568
 * @param string $function The function that was called.
569
 * @param string $version The plugin version that deprecated the function.
570
 * @param string $replacement Optional. The function that should have been called.
571
 * @param array $backtrace Optional. Contains stack backtrace of deprecated function.
572
 */
573
function _give_deprecated_function( $function, $version, $replacement = null, $backtrace = null ) {
574
575
	/**
576
	 * Fires while give deprecated function call occurs.
577
	 *
578
	 * Allow you to hook to deprecated function call.
579
	 *
580
	 * @since 1.0
581
	 *
582
	 * @param string $function The function that was called.
583
	 * @param string $replacement Optional. The function that should have been called.
584
	 * @param string $version The plugin version that deprecated the function.
585
	 */
586
	do_action( 'give_deprecated_function_run', $function, $replacement, $version );
587
588
	$show_errors = current_user_can( 'manage_options' );
589
590
	// Allow plugin to filter the output error trigger.
591
	if ( WP_DEBUG && apply_filters( 'give_deprecated_function_trigger_error', $show_errors ) ) {
592
		if ( ! is_null( $replacement ) ) {
593
			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Give version %2$s! Use %3$s instead.', 'give' ), $function, $version, $replacement ) );
594
			trigger_error( print_r( $backtrace, 1 ) ); // Limited to previous 1028 characters, but since we only need to move back 1 in stack that should be fine.
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
595
			// Alternatively we could dump this to a file.
596
		} else {
597
			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Give version %2$s with no alternative available.', 'give' ), $function, $version ) );
598
			trigger_error( print_r( $backtrace, 1 ) );// Limited to previous 1028 characters, but since we only need to move back 1 in stack that should be fine.
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
599
			// Alternatively we could dump this to a file.
600
		}
601
	}
602
}
603
604
/**
605
 * Give Get Admin ID
606
 *
607
 * Helper function to return the ID of the post for admin usage
608
 *
609
 * @return string $post_id
610
 */
611
function give_get_admin_post_id() {
612
	$post_id = isset( $_GET['post'] ) ? $_GET['post'] : null;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
613
	if ( ! $post_id && isset( $_POST['post_id'] ) ) {
614
		$post_id = $_POST['post_id'];
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
615
	}
616
617
	return $post_id;
618
}
619
620
/**
621
 * Get PHP Arg Separator Output
622
 *
623
 * @since 1.0
624
 * @return string Arg separator output
625
 */
626
function give_get_php_arg_separator_output() {
627
	return ini_get( 'arg_separator.output' );
628
}
629
630
631
/**
632
 * Month Num To Name
633
 *
634
 * Takes a month number and returns the name three letter name of it.
635
 *
636
 * @since 1.0
637
 *
638
 * @param int $n
639
 *
640
 * @return string Short month name
641
 */
642
function give_month_num_to_name( $n ) {
643
	$timestamp = mktime( 0, 0, 0, $n, 1, 2005 );
644
645
	return date_i18n( 'M', $timestamp );
646
}
647
648
649
/**
650
 * Checks whether function is disabled.
651
 *
652
 * @since 1.0
653
 *
654
 * @param string $function Name of the function.
655
 *
656
 * @return bool Whether or not function is disabled.
657
 */
658
function give_is_func_disabled( $function ) {
659
	$disabled = explode( ',', ini_get( 'disable_functions' ) );
660
661
	return in_array( $function, $disabled );
662
}
663
664
665
/**
666
 * Give Newsletter
667
 *
668
 * Returns the main Give newsletter form
669
 */
670
function give_get_newsletter() {
671
	?>
672
673
	<p class="newsletter-intro"><?php esc_html_e( 'Be sure to sign up for the Give newsletter below to stay informed of important updates and news.', 'give' ); ?></p>
674
675
	<div class="give-newsletter-form-wrap">
676
677
		<form action="//givewp.us3.list-manage.com/subscribe/post?u=3ccb75d68bda4381e2f45794c&amp;id=12a081aa13"
678
		      method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate"
679
		      target="_blank" novalidate>
680
			<div class="give-newsletter-confirmation">
681
				<p><?php esc_html_e( 'Thanks for Subscribing!', 'give' ); ?> :)</p>
682
			</div>
683
684
			<table class="form-table give-newsletter-form">
685
				<tr valign="middle">
686
					<td>
687
						<label for="mce-EMAIL"
688
						       class="screen-reader-text"><?php esc_html_e( 'Email Address (required)', 'give' ); ?></label>
689
						<input type="email" name="EMAIL" id="mce-EMAIL"
690
						       placeholder="<?php esc_attr_e( 'Email Address (required)', 'give' ); ?>"
691
						       class="required email" value="">
692
					</td>
693
					<td>
694
						<label for="mce-FNAME"
695
						       class="screen-reader-text"><?php esc_html_e( 'First Name', 'give' ); ?></label>
696
						<input type="text" name="FNAME" id="mce-FNAME"
697
						       placeholder="<?php esc_attr_e( 'First Name', 'give' ); ?>" class="" value="">
698
					</td>
699
					<td>
700
						<label for="mce-LNAME"
701
						       class="screen-reader-text"><?php esc_html_e( 'Last Name', 'give' ); ?></label>
702
						<input type="text" name="LNAME" id="mce-LNAME"
703
						       placeholder="<?php esc_attr_e( 'Last Name', 'give' ); ?>" class="" value="">
704
					</td>
705
					<td>
706
						<input type="submit" name="subscribe" id="mc-embedded-subscribe" class="button"
707
						       value="<?php esc_attr_e( 'Subscribe', 'give' ); ?>">
708
					</td>
709
				</tr>
710
			</table>
711
		</form>
712
713
		<div style="position: absolute; left: -5000px;">
714
			<input type="text" name="b_3ccb75d68bda4381e2f45794c_12a081aa13" tabindex="-1" value="">
715
		</div>
716
717
	</div>
718
719
	<script type='text/javascript' src='//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js'></script>
0 ignored issues
show
introduced by
Scripts must be registered/enqueued via wp_enqueue_script
Loading history...
720
	<script type='text/javascript'>(function ($) {
721
			window.fnames = new Array();
722
			window.ftypes = new Array();
723
			fnames[0] = 'EMAIL';
724
			ftypes[0] = 'email';
725
			fnames[1] = 'FNAME';
726
			ftypes[1] = 'text';
727
			fnames[2] = 'LNAME';
728
			ftypes[2] = 'text';
729
730
			//Successful submission
731
			$('form[name="mc-embedded-subscribe-form"]').on('submit', function () {
732
733
				var email_field = $(this).find('#mce-EMAIL').val();
734
				if (!email_field) {
735
					return false;
736
				}
737
				$(this).find('.give-newsletter-confirmation').show().delay(5000).slideUp();
738
				$(this).find('.give-newsletter-form').hide();
739
740
			});
741
742
		}(jQuery));
743
		var $mcj = jQuery.noConflict(true);
744
745
746
	</script>
747
	<!--End mc_embed_signup-->
748
749
<?php }
750
751
752
/**
753
 * Create SVG library function
754
 *
755
 * @param string $icon
756
 *
757
 * @return string
758
 */
759
function give_svg_icons( $icon ) {
760
761
	// Store your SVGs in an associative array
762
	$svgs = array(
763
		'microphone'    => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjY0cHgiIGhlaWdodD0iMTAwcHgiIHZpZXdCb3g9IjAgLTIwIDY0IDEyMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNjQgMTAwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8Zz4NCgk8Zz4NCgkJPHBhdGggZD0iTTYyLDM2LjIxNWgtM2MtMS4xLDAtMiwwLjktMiwyVjUyYzAsNi42ODYtNS4yNjYsMTgtMjUsMThTNyw1OC42ODYsNyw1MlYzOC4yMTVjMC0xLjEtMC45LTItMi0ySDJjLTEuMSwwLTIsMC45LTIsMlY1Mg0KCQkJYzAsMTEuMTg0LDguMjE1LDIzLjE1MiwyNywyNC44MDFWOTBIMTRjLTEuMSwwLTIsMC44OTgtMiwydjZjMCwxLjEsMC45LDIsMiwyaDM2YzEuMSwwLDItMC45LDItMnYtNmMwLTEuMTAyLTAuOS0yLTItMkgzN1Y3Ni44MDENCgkJCUM1NS43ODUsNzUuMTUyLDY0LDYzLjE4NCw2NCw1MlYzOC4yMTVDNjQsMzcuMTE1LDYzLjEsMzYuMjE1LDYyLDM2LjIxNXoiLz4NCgkJPHBhdGggZD0iTTMyLDYwYzExLjczMiwwLDE1LTQuODE4LDE1LThWMzYuMjE1SDE3VjUyQzE3LDU1LjE4MiwyMC4yNjYsNjAsMzIsNjB6Ii8+DQoJCTxwYXRoIGQ9Ik00Nyw4YzAtMy4xODQtMy4yNjgtOC0xNS04QzIwLjI2NiwwLDE3LDQuODE2LDE3LDh2MjEuMjE1aDMwVjh6Ii8+DQoJPC9nPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPC9zdmc+DQo=',
764
		'alert'         => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjI4LjkzOHB4IiBoZWlnaHQ9IjI1LjAwNXB4IiB2aWV3Qm94PSIwIDAgMjguOTM4IDI1LjAwNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjguOTM4IDI1LjAwNTsiDQoJIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggc3R5bGU9ImZpbGw6IzAwMDAwMDsiIGQ9Ik0yOC44NTksMjQuMTU4TDE0Ljk1NywwLjI3OUMxNC44NTYsMC4xMDYsMTQuNjcsMCwxNC40NjgsMGMtMC4xOTgsMC0wLjM4MywwLjEwNi0wLjQ4MSwwLjI3OQ0KCUwwLjA3OSwyNC4xNThjLTAuMTAyLDAuMTc1LTAuMTA2LDAuMzg5LTAuMDA2LDAuNTY1YzAuMTAzLDAuMTc0LDAuMjg3LDAuMjgyLDAuNDg4LDAuMjgyaDI3LjgxNGMwLjIwMSwwLDAuMzg5LTAuMTA4LDAuNDg4LTAuMjgyDQoJYzAuMDQ3LTAuMDg4LDAuMDc0LTAuMTg2LDAuMDc0LTAuMjgxQzI4LjkzOCwyNC4zNDMsMjguOTExLDI0LjI0NSwyOC44NTksMjQuMTU4eiBNMTYuMzY5LDguNDc1bC0wLjQ2Miw5LjQ5M2gtMi4zODlsLTAuNDYxLTkuNDkzDQoJSDE2LjM2OXogTTE0LjcxMSwyMi44MjhoLTAuMDQyYy0xLjA4OSwwLTEuODQzLTAuODE3LTEuODQzLTEuOTA3YzAtMS4xMzEsMC43NzQtMS45MDcsMS44ODUtMS45MDdzMS44NDYsMC43NzUsMS44NjcsMS45MDcNCglDMTYuNTc5LDIyLjAxMSwxNS44NDQsMjIuODI4LDE0LjcxMSwyMi44Mjh6Ii8+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8L3N2Zz4NCg==',
765
		'placemark'     => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iMTAwcHgiIGhlaWdodD0iMTAwcHgiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik01MC40MzQsMjAuMjcxYy0xMi40OTksMC0yMi42NjgsMTAuMTY5LTIyLjY2OCwyMi42NjhjMCwxMS44MTQsMTguODE1LDMyLjE1NSwyMC45NiwzNC40MzdsMS43MDgsMS44MTZsMS43MDgtMS44MTYNCgkJYzIuMTQ1LTIuMjgxLDIwLjk2LTIyLjYyMywyMC45Ni0zNC40MzdDNzMuMTAzLDMwLjQ0LDYyLjkzNCwyMC4yNzEsNTAuNDM0LDIwLjI3MXogTTUwLjQzNCw1Mi4zMmMtNS4xNzIsMC05LjM4LTQuMjA4LTkuMzgtOS4zOA0KCQlzNC4yMDgtOS4zOCw5LjM4LTkuMzhjNS4xNzMsMCw5LjM4LDQuMjA4LDkuMzgsOS4zOFM1NS42MDcsNTIuMzIsNTAuNDM0LDUyLjMyeiIvPg0KPC9nPg0KPC9zdmc+DQo=',
766
		'give_grey'     => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjEwMC4xIDAgNDAwIDQwMCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAxMDAuMSAwIDQwMCA0MDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnIGlkPSJMYXllcl8xXzFfIj48Y2lyY2xlIGZpbGw9IiM2NkJCNkEiIGN4PSItNDA3LjMiIGN5PSIzNDYuMyIgcj0iNDIuMiIvPjxnPjxnPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNzg2LjQsMTMzLjh2LTEyLjVoNC44YzMuOCwwLDYuNiwyLjUsNi42LDYuNHMtMi44LDYuNC02LjYsNi40aC00LjhWMTMzLjh6IE0tNzc3LjUsMTI3LjVjMC0yLjMtMS4zLTMuOC0zLjgtMy44aC0yLjN2Ny45aDIuM0MtNzc5LDEzMS42LTc3Ny41LDEyOS44LTc3Ny41LDEyNy41eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNzcxLjYsMTMzLjh2LTEyLjVoOC45djIuM2gtNi4xdjIuNWg2LjF2Mi4zaC02LjF2Mi44aDYuMXYyLjNoLTguOVYxMzMuOHoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTc0OC41LDEzMy44di04LjdsLTMuNiw4LjdoLTEuM2wtMy42LTguN3Y4LjdoLTIuNXYtMTIuNWgzLjhsMy4xLDcuNmwzLjEtNy42aDMuOHYxMi41SC03NDguNXoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTc0Mi40LDEyNy41YzAtMy44LDIuOC02LjQsNi42LTYuNHM2LjYsMi44LDYuNiw2LjRjMCwzLjgtMi44LDYuNC02LjYsNi40Qy03MzkuOCwxMzQuMS03NDIuNCwxMzEuMy03NDIuNCwxMjcuNXogTS03MzIuMiwxMjcuNWMwLTIuMy0xLjUtNC4xLTMuOC00LjFjLTIuMywwLTMuOCwxLjgtMy44LDQuMWMwLDIuMywxLjUsNC4xLDMuOCw0LjFDLTczMy43LDEzMS42LTczMi4yLDEyOS44LTczMi4yLDEyNy41eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNzI2LjgsMTI3LjVjMC0zLjgsMi44LTYuNCw2LjYtNi40YzIuOCwwLDQuMywxLjUsNS4zLDMuMWwtMi4zLDFjLTAuNS0xLTEuNS0xLjgtMy4xLTEuOGMtMi4zLDAtMy44LDEuOC0zLjgsNC4xYzAsMi4zLDEuNSw0LjEsMy44LDQuMWMxLjMsMCwyLjMtMC44LDMuMS0xLjhsMi4zLDFjLTEsMS41LTIuNSwzLjEtNS4zLDMuMUMtNzIzLjgsMTM0LjEtNzI2LjgsMTMxLjMtNzI2LjgsMTI3LjV6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS03MDQuNywxMzMuOGwtMi41LTQuM2gtMnY0LjNoLTIuNXYtMTIuNWg1LjljMi41LDAsNC4xLDEuOCw0LjEsNC4xYzAsMi4zLTEuMywzLjMtMi44LDMuOGwyLjgsNC44aC0yLjhWMTMzLjh6IE0tNzA0LjUsMTI1LjJjMC0xLTAuOC0xLjgtMS44LTEuOGgtMi44djMuM2gyLjhDLTcwNS41LDEyNy03MDQuNSwxMjYuNS03MDQuNSwxMjUuMnoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTY4OS43LDEzMy44bC0wLjgtMmgtNS4zbC0wLjgsMmgtMy4xbDQuOC0xMi41aDMuM2w0LjgsMTIuNUgtNjg5Ljd6IE0tNjkzLjMsMTIzLjlsLTIsNS4zaDMuOEwtNjkzLjMsMTIzLjl6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS02ODIuNiwxMzMuOHYtMTAuMmgtMy42di0yLjNoOS45djIuM2gtMy42djEwLjJILTY4Mi42eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNjczLjIsMTMzLjh2LTEyLjVoMi41djEyLjVILTY3My4yeiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNjY3LDEzMy44di0ybDUuOS03LjloLTUuOXYtMi4zaDkuNHYybC01LjksOC4xaDYuMXYyLjNoLTkuN1YxMzMuOHoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTY1NC4xLDEzMy44di0xMi41aDIuNXYxMi41SC02NTQuMXoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTYzOS4xLDEzMy44bC01LjktOC4xdjguMWgtMi41di0xMi41aDIuOGw1LjksNy45di03LjloMi41djEyLjVILTYzOS4xeiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNjMzLjIsMTI3LjVjMC00LjEsMy4xLTYuNCw2LjYtNi40YzIuNSwwLDQuMywxLjMsNS4xLDIuOGwtMi4zLDEuM2MtMC41LTAuOC0xLjUtMS41LTMuMS0xLjVjLTIuMywwLTMuOCwxLjgtMy44LDQuMWMwLDIuMywxLjUsNC4xLDMuOCw0LjFjMSwwLDItMC41LDIuNS0xdi0xLjVoLTMuM1YxMjdoNS45djQuOGMtMS4zLDEuNS0zLjEsMi4zLTUuMywyLjNDLTYzMC4yLDEzNC4xLTYzMy4yLDEzMS42LTYzMy4yLDEyNy41eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNjEyLjEsMTI3LjVjMC00LjEsMy4xLTYuNCw2LjYtNi40YzIuNSwwLDQuMywxLjMsNS4xLDIuOGwtMi4zLDEuM2MtMC41LTAuOC0xLjUtMS41LTMuMS0xLjVjLTIuMywwLTMuOCwxLjgtMy44LDQuMWMwLDIuMywxLjUsNC4xLDMuOCw0LjFjMSwwLDItMC41LDIuNS0xdi0xLjVoLTMuM1YxMjdoNS45djQuOGMtMS4zLDEuNS0zLjEsMi4zLTUuMywyLjNDLTYwOSwxMzQuMS02MTIuMSwxMzEuNi02MTIuMSwxMjcuNXoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTU5Ni42LDEzMy44di0xMi41aDguOXYyLjNoLTYuMXYyLjVoNi4xdjIuM2gtNi4xdjIuOGg2LjF2Mi4zaC04LjlWMTMzLjh6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS01NzUuNywxMzMuOGwtNS45LTguMXY4LjFoLTIuNXYtMTIuNWgyLjhsNS45LDcuOXYtNy45aDIuNXYxMi41SC01NzUuN3oiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTU2OS4xLDEzMy44di0xMi41aDguOXYyLjNoLTYuMXYyLjVoNi4xdjIuM2gtNi4xdjIuOGg2LjF2Mi4zaC04LjlWMTMzLjh6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS01NDkuNywxMzMuOGwtMi41LTQuM2gtMnY0LjNoLTIuNXYtMTIuNWg1LjljMi41LDAsNC4xLDEuOCw0LjEsNC4xYzAsMi4zLTEuMywzLjMtMi44LDMuOGwyLjgsNC44aC0yLjhWMTMzLjh6IE0tNTQ5LjUsMTI1LjJjMC0xLTAuOC0xLjgtMS44LTEuOGgtMi44djMuM2gyLjhDLTU1MC4zLDEyNy01NDkuNSwxMjYuNS01NDkuNSwxMjUuMnoiLz48cGF0aCBmaWxsPSIjNTQ2RTdBIiBkPSJNLTU0My45LDEyNy41YzAtMy44LDIuOC02LjQsNi42LTYuNHM2LjYsMi44LDYuNiw2LjRjMCwzLjgtMi44LDYuNC02LjYsNi40Qy01NDEuMywxMzQuMS01NDMuOSwxMzEuMy01NDMuOSwxMjcuNXogTS01MzMuNywxMjcuNWMwLTIuMy0xLjUtNC4xLTMuOC00LjFzLTMuOCwxLjgtMy44LDQuMWMwLDIuMywxLjUsNC4xLDMuOCw0LjFDLTUzNS4yLDEzMS42LTUzMy43LDEyOS44LTUzMy43LDEyNy41eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNTI4LjYsMTMyLjFsMS41LTJjMC44LDEsMi4zLDEuOCw0LjEsMS44YzEuNSwwLDIuMy0wLjgsMi4zLTEuM2MwLTIuMy03LjEtMC44LTcuMS01LjNjMC0yLDEuOC0zLjgsNC44LTMuOGMyLDAsMy42LDAuNSw0LjgsMS44bC0xLjUsMmMtMS0xLTIuMy0xLjMtMy42LTEuM2MtMSwwLTEuOCwwLjUtMS44LDEuM2MwLDIsNy4xLDAuOCw3LjEsNS4zYzAsMi4zLTEuNSw0LjEtNS4xLDQuMUMtNTI1LjYsMTM0LjEtNTI3LjQsMTMzLjEtNTI4LjYsMTMyLjF6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS01MTUuMSwxMzMuOHYtMTIuNWgyLjV2MTIuNUgtNTE1LjF6Ii8+PHBhdGggZmlsbD0iIzU0NkU3QSIgZD0iTS01MDUuNywxMzMuOHYtMTAuMmgtMy42di0yLjNoOS45djIuM2gtMy42djEwLjJILTUwNS43eiIvPjxwYXRoIGZpbGw9IiM1NDZFN0EiIGQ9Ik0tNDkyLjcsMTMzLjh2LTUuMWwtNC44LTcuNGgzLjFsMy4xLDUuMWwzLjEtNS4xaDMuMWwtNC44LDcuNHY1LjFILTQ5Mi43eiIvPjwvZz48Zz48Zz48cGF0aCBmaWxsPSIjNjZCQjZBIiBkPSJNLTQ4NS45LDQ0LjNoLTEuM2wwLjMsMS4zYzIsOS45LDAuMywyNC43LTcuNCwzMy44Yy00LjMsNS4zLTkuOSw4LjEtMTYuOCw4LjFjLTEwLjksMC0xNS0xMy0xNS41LTI3LjdjMTcuOC00LjMsMjkuOC0xNS41LDI5LjgtMjguNWMwLTkuNC0yLjgtMjQuOS0yMS40LTI0LjljLTE3LjYsMC0yNi41LDI2LjItMjguMiw0NC41Yy04LjktMC4zLTE1LjUtNC4zLTE5LjYtOC4xYzEuNS02LjQsMi4zLTEyLjIsMi4zLTE3LjZjMC03LjQtNS4xLTEwLjctOS45LTEwLjdjLTYuOSwwLTE0LDYuNi0xNCwxOS4zYzAsNy42LDIuOCwxNCw4LjcsMTguNmMtNS4xLDEyLTEzLjcsMjIuMS0xNi41LDI1LjRjLTIuMy00LjgtOS43LTIyLjQtMTItNDEuNWMyLjgtNy42LDQuMy0xNCw0LjMtMTdjMC00LjgtMy4xLTcuNi04LjEtNy42Yy02LjksMC0xNy44LDQuMy0xOC4xLDQuNmwtMC41LDAuM3YwLjhjMCwwLjMsMy4zLDE1LjUsNi42LDMyLjNjLTYuNCwxMC40LTE3LjYsMjcuNy0yMy4yLDI3LjdjLTEwLjIsMCw2LjYtNTIuMi0wLjgtNTMuOWMtMC4zLDAtMC41LDAtMC44LDAuM2MtMy42LDIuMy00My41LDI0LjQtOTYuNywyNC40YzAsMCwwLDEsMC41LDJjMC4zLDAuOCwxLDEuNSwxLDEuNWMxNSwxLjgsMzYuNC0wLjMsNTIuNy0yLjVjLTkuNCwyMC4xLTI2LDMzLjMtNDEuMiwzMy4zYy0yOC44LDAtNTAuOS0zNC45LTUwLjktMzQuOWM4LjktNy45LDIzLjQtMzMuMyw0NC44LTMzLjNjMjEuMSwwLDMwLjMsMTEuNywzMC4zLDExLjdsMi4zLTMuOGMwLDAtOS45LTM0LjYtMzcuOS0zNC42cy01Ny44LDQ1LjgtNzUuMSw1Ni41YzAsMCwyMy45LDU2LjUsNzYuMSw1Ni41YzQzLjgsMCw1NS00Miw1Ny01Mi4yYzEwLjctMS41LDE4LjEtMy4xLDE4LjEtMy4xcy0yLjgsMjEuNC0yLjgsMzAuM3M5LjksMTguMywxOC4xLDE4LjNjNi45LDAsMjAuOS0xNC4yLDMxLTMxLjZsMC41LDJjNS4zLDE5LjYsMTIsMjkuOCwxOS44LDI5LjhjNy45LDAsMjAuOS0xNi4zLDI5LjMtMzYuOWM4LjQsMy42LDE4LjMsNC42LDI0LjIsNC44YzIuMywzNS40LDMxLjgsMzYuNCwzNS40LDM2LjRjMjEuOSwwLDQwLjUtMTUuOCw0MC41LTM0LjRDLTQ3MC42LDQ0LjUtNDg1LjYsNDQuMy00ODUuOSw0NC4zeiBNLTUxMi42LDI5LjVjMCwwLTAuMywxMS43LTEzLjUsMTcuNmMxLjMtMTUuNSw1LjEtMjkuNSw3LjYtMjkuNUMtNTE1LjYsMTcuOC01MTIuNiwyMi4xLTUxMi42LDI5LjV6Ii8+PHBhdGggZmlsbD0iIzY2QkI2QSIgZD0iTS02NjUsMTUuNWMwLDAuNSwwLjMsMC44LDAuOCwxYzEwLjQsMS41LDE3LjMtMS44LDE3LjMtMTguNmMwLTE1LjgtMTYuMy0zLjMtMTkuMy0xYy0wLjMsMC4zLTAuMywwLjUtMC4zLDFDLTY2My43LDQuMS02NjQuOCwxMy02NjUsMTUuNXoiLz48L2c+PGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMjg5LjU4NjQiIHkxPSIzNzMuMjM3OSIgeDI9Ii0yODIuODg0MiIgeTI9IjM3NS40NzE5IiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xXykiIGQ9Ik0tNjIzLDQ5LjRjLTQuMSw2LjktMTAuMiwxNi4zLTE1LjUsMjIuMWMxLjMsMy4xLDIuOCw2LjksNC4zLDkuOWM0LjgtNS4zLDkuNy0xMi4yLDE0LTE5LjNMLTYyMyw0OS40eiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMl8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI2OS4wNTc3IiB5MT0iMzcxLjU0NDEiIHgyPSItMjY1LjE3MDUiIHkyPSIzNzguMzgwMiIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfMl8pIiBkPSJNLTU3NC43LDU0LjdjLTItMS0zLjgtMi41LTMuOC0yLjVjLTMuNiw3LjktOC40LDE1LjMtMTIuMiwyMC4xYzEuOCwyLjUsNC44LDUuOSw3LjEsOC40YzQuNi02LjQsOS40LTE0LjgsMTMtMjMuN0MtNTcwLjQsNTYuNy01NzIuNiw1Ni01NzQuNyw1NC43eiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfM18iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI0OC42NDE2IiB5MT0iMzY4LjM4MzUiIHgyPSItMjQ5LjQ0NTkiIHkyPSIzNzUuNTMyMyIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfM18pIiBkPSJNLTUyNi4zLDU5LjhjMCwwLTUuMSwxLTEwLjIsMS41cy05LjksMC4zLTkuOSwwLjNjMC44LDEwLjIsMy42LDE3LjMsNy40LDIyLjZsMTguNi0xLjVDLTUyNC4zLDc3LjYtNTI2LjEsNjktNTI2LjMsNTkuOHoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzRfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0yNDkuOCIgeTE9IjM4My41ODEiIHgyPSItMjQ5LjgiIHkyPSIzNzYuMzc2MyIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfNF8pIiBkPSJNLTU0MS4xLDI4LjhMLTU0MS4xLDI4LjhjLTAuNSwxLjUtMS4zLDMuMy0xLjgsNS4xYzAsMC41LTAuMywwLjgtMC4zLDEuM2MtMSwzLjMtMS44LDYuNi0yLjMsOS45YzAsMC41LTAuMywwLjgtMC4zLDEuM2MtMC4zLDEuNS0wLjUsMy4xLTAuNSw0LjZjMTIsMCwyMC4xLTMuNiwyMC4xLTMuNmMwLTEuMywwLjMtMi4zLDAuMy0zLjZjMC0wLjMsMC0wLjUsMC0wLjhjMC0xLDAuMy0xLjgsMC4zLTIuOGMwLTAuMywwLTAuNSwwLTAuOGMwLjMtMi4zLDAuOC00LjYsMS02LjZMLTU0MS4xLDI4Ljh6IE0tNTQ2LjQsNTAuNkwtNTQ2LjQsNTAuNkwtNTQ2LjQsNTAuNkwtNTQ2LjQsNTAuNnoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzVfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zMTMiIHkxPSIzNzEuNzcyMiIgeDI9Ii0zMTMiIHkyPSIzODAuNzA4MyIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfNV8pIiBkPSJNLTcwOC4zLDcyLjhsMTEuMiw0LjhjNS4zLTcuNiw4LjctMTUuNSwxMC43LTIxLjZsMi04LjFsLTUuMywwLjhDLTY5NC41LDU4LjgtNzAxLjEsNjYuOS03MDguMyw3Mi44eiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfNl8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI3Ny41MjU1IiB5MT0iMzkwLjIxMyIgeDI9Ii0yNzguNjQ3OSIgeTI9IjM4OC40MjU0IiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF82XykiIGQ9Ik0tNjA3LDM2LjFjMi44LTcuNiw0LjMtMTQsNC4zLTE3YzAtMC4zLDAtMC41LDAtMC44bC02LjYsMkMtNjA5LjMsMjAuNC02MDksMjQuNy02MDcsMzYuMXoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzdfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0yNjIuNTgxMyIgeTE9IjM4Ni40ODI3IiB4Mj0iLTI2My4yMTUiIHkyPSIzODQuMDc0OSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfN18pIiBkPSJNLTU3MS40LDMwLjVjMCwwLTEuOCw1LjMsNS42LDEyYzEuMy01LjMsMi0xMC43LDIuMy0xNS4zTC01NzEuNCwzMC41eiIvPjwvZz48L2c+PGc+PGc+PHBhdGggZmlsbD0iIzY2QkI2QSIgZD0iTS04MDcuOCwzNDYuNmgtMC41djAuNWMwLjgsNC4zLDAsMTAuNC0zLjEsMTQuNWMtMS44LDIuMy00LjMsMy42LTcuMSwzLjZjLTQuNiwwLTYuNC01LjYtNi42LTExLjdjNy42LTEuOCwxMi43LTYuNiwxMi43LTEyLjJjMC00LjEtMS4zLTEwLjctOS4yLTEwLjdjLTcuNCwwLTExLjIsMTEuMi0xMiwxOC44Yy0zLjgsMC02LjYtMS44LTguNC0zLjZjMC44LTIuOCwxLTUuMSwxLTcuNGMwLTMuMS0yLjMtNC42LTQuMS00LjZjLTMuMSwwLTUuOSwyLjgtNS45LDguMWMwLDMuMywxLjMsNS45LDMuOCw3LjljLTIuMyw1LjEtNS45LDkuNC03LjEsMTAuN2MtMS0yLTQuMS05LjctNS4xLTE3LjZjMS4zLTMuMywxLjgtNS45LDEuOC03LjFjMC0yLTEuMy0zLjMtMy42LTMuM2MtMy4xLDAtNy42LDEuOC03LjYsMmwtMC4zLDAuM3YwLjNjMCwwLDEuMyw2LjYsMi44LDEzLjdjLTIuOCw0LjMtNy40LDExLjctOS45LDExLjdjLTQuMywwLDIuOC0yMi4xLTAuMy0yMi45aC0wLjNjLTEuNSwxLTE4LjYsMTAuNC00MSwxMC40YzAsMCwwLDAuNSwwLjMsMC44YzAuMywwLjMsMC41LDAuNSwwLjUsMC41YzYuNCwwLjgsMTUuNSwwLDIyLjQtMWMtNC4xLDguNC0xMC45LDE0LjItMTcuNiwxNC4yYy0xMi4yLDAtMjEuNi0xNC44LTIxLjYtMTQuOGMzLjgtMy4zLDkuOS0xNC4yLDE5LjEtMTQuMmM4LjksMCwxMyw0LjgsMTMsNC44bDEtMS41YzAsMC00LjMtMTQuOC0xNi0xNC44cy0yNC40LDE5LjYtMzEuOCwyMy45YzAsMCwxMC4yLDI0LjIsMzIuMywyNC4yYzE4LjYsMCwyMy40LTE3LjgsMjQuMi0yMi4xYzQuNi0wLjgsNy42LTEuMyw3LjYtMS4zcy0xLDkuMi0xLDEzYzAsMy44LDQuMSw3LjksNy42LDcuOWMzLjEsMCw4LjktNi4xLDEzLjItMTMuNWwwLjMsMC44YzIuMyw4LjQsNS4xLDEyLjcsOC40LDEyLjdzOC45LTYuOSwxMi41LTE1LjVjMy42LDEuNSw3LjksMiwxMC4yLDJjMSwxNSwxMy41LDE1LjUsMTUsMTUuNWM5LjQsMCwxNy4zLTYuNiwxNy4zLTE0LjVDLTgwMS40LDM0Ni44LTgwNy44LDM0Ni42LTgwNy44LDM0Ni42eiBNLTgxOSwzNDAuMmMwLDAsMCw1LjEtNS45LDcuNmMwLjUtNi42LDItMTIuNSwzLjMtMTIuNUMtODIwLjUsMzM1LjQtODE5LDMzNy4yLTgxOSwzNDAuMnoiLz48cGF0aCBmaWxsPSIjNjZCQjZBIiBkPSJNLTg4My44LDMzNC40YzAsMC4zLDAsMC4zLDAuMywwLjVjNC4zLDAuNSw3LjQtMC44LDcuNC03LjljMC02LjYtNi45LTEuNS04LjEtMC41YzAsMC0wLjMsMC4zLDAsMC41Qy04ODMuMywzMjkuNS04ODMuOCwzMzMuMS04ODMuOCwzMzQuNHoiLz48L2c+PGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF84XyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzgyLjAwNzQiIHkxPSIyNTkuODQ3NSIgeDI9Ii0zNzkuMTU4NSIgeTI9IjI2MC43OTcyIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF84XykiIGQ9Ik0tODY2LDM0OC42Yy0xLjgsMi44LTQuMyw2LjktNi42LDkuNGMwLjUsMS4zLDEuMywyLjgsMS44LDQuM2MyLTIuMyw0LjEtNS4xLDYuMS04LjFMLTg2NiwzNDguNnoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzlfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zNzMuMTYyNiIgeTE9IjI1OS4wNDIzIiB4Mj0iLTM3MS41MTAyIiB5Mj0iMjYxLjk0ODIiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMi41NDQ1IDAgMCAtMi41NDQ1IDEwMC4xMjcyIDEwMTcuODExNykiPjxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz48c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+PC9saW5lYXJHcmFkaWVudD48cGF0aCBmaWxsPSJ1cmwoI1NWR0lEXzlfKSIgZD0iTS04NDUuNCwzNTAuOWMtMC44LTAuNS0xLjUtMS0xLjUtMWMtMS41LDMuMy0zLjYsNi40LTUuMSw4LjdjMC44LDEsMiwyLjUsMy4xLDMuNmMyLTIuOCw0LjEtNi4xLDUuNi0xMC4yQy04NDMuNiwzNTEuOS04NDQuNywzNTEuNC04NDUuNCwzNTAuOXoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzEwXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzY0LjY5OTYiIHkxPSIyNTcuNzUwMyIgeDI9Ii0zNjUuMDQxNCIgeTI9IjI2MC43ODkyIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xMF8pIiBkPSJNLTgyNS4xLDM1My4yYzAsMC0yLDAuNS00LjMsMC44Yy0yLDAuMy00LjMsMC00LjMsMGMwLjMsNC4zLDEuNSw3LjQsMy4xLDkuN2w3LjktMC44Qy04MjQsMzYwLjgtODI0LjgsMzU3LTgyNS4xLDM1My4yeiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMTFfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zNjUiIHkxPSIyNjQuMjIyMyIgeDI9Ii0zNjUiIHkyPSIyNjEuMTU5NyIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfMTFfKSIgZD0iTS04MzEuMiwzMzkuOUwtODMxLjIsMzM5LjljLTAuMywwLjgtMC41LDEuNS0wLjgsMmMwLDAuMywwLDAuMy0wLjMsMC41Yy0wLjUsMS41LTAuOCwyLjgtMSw0LjNjMCwwLjMsMCwwLjMsMCwwLjVjMCwwLjgtMC4zLDEuMy0wLjMsMmM1LjEsMCw4LjctMS41LDguNy0xLjVjMC0wLjUsMC0xLDAuMy0xLjV2LTAuM2MwLTAuNSwwLTAuOCwwLjMtMXYtMC4zYzAuMy0xLDAuMy0yLDAuNS0yLjhMLTgzMS4yLDMzOS45eiBNLTgzMy41LDM0OS40TC04MzMuNSwzNDkuNEwtODMzLjUsMzQ5LjRMLTgzMy41LDM0OS40eiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMTJfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zOTIiIHkxPSIyNTkuMjAyNSIgeDI9Ii0zOTIiIHkyPSIyNjMuMDAxMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgyLjU0NDUgMCAwIC0yLjU0NDUgMTAwLjEyNzIgMTAxNy44MTE3KSI+PHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPjxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGZpbGw9InVybCgjU1ZHSURfMTJfKSIgZD0iTS05MDIuNCwzNTguOGw0LjgsMmMyLjMtMy4zLDMuNi02LjYsNC42LTkuMmwwLjgtMy42bC0yLjMsMC4zQy04OTYuNiwzNTIuNy04OTkuMSwzNTYuMi05MDIuNCwzNTguOHoiLz48bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzEzXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzc2Ljg2MzciIHkxPSIyNjcuMDM1NSIgeDI9Ii0zNzcuMzQwOSIgeTI9IjI2Ni4yNzU1IiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xM18pIiBkPSJNLTg1OS4yLDM0M2MxLjMtMy4zLDEuOC01LjksMS44LTcuMXYtMC4zbC0yLjgsMC44Qy04NjAuMiwzMzYuNC04NjAuMiwzMzguMi04NTkuMiwzNDN6Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xNF8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTM3MC41NTQzIiB5MT0iMjY1LjQ2NDUiIHgyPSItMzcwLjgyMzYiIHkyPSIyNjQuNDQxIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xNF8pIiBkPSJNLTg0NC4xLDM0MC43YzAsMC0wLjgsMi4zLDIuMyw1LjFjMC41LTIuMywxLTQuNiwxLTYuNkwtODQ0LjEsMzQwLjd6Ii8+PC9nPjxnPjxyZWN0IHg9Ii02OTcuMyIgeT0iMjkyLjkiIGZpbGw9IiNGRkZGRkYiIHdpZHRoPSIxMDYuOSIgaGVpZ2h0PSIxMDYuOSIvPjxnPjxwYXRoIGZpbGw9IiM2NkJCNkEiIGQ9Ik0tNjQ0LjQsMzQ5LjljMC4zLDAuNSwwLjUsMC44LDAuNSwwLjhjOC43LDEsMjEuMSwwLDMwLjUtMS41Yy01LjMsMTEuNy0xNSwxOS4zLTIzLjksMTkuM2MtMTYuNSwwLTI5LjUtMjAuMS0yOS41LTIwLjFjNS4xLTQuNiwxMy43LTE5LjMsMjYtMTkuM2MxMi4yLDAsMTcuNiw2LjYsMTcuNiw2LjZsMS4zLTIuM2MwLDAtNS45LTIwLjEtMjEuOS0yMC4xYy0xNi4zLDAtMzMuMywyNi41LTQzLjUsMzIuNmMwLDAsMTMuNywzMi44LDQ0LDMyLjhjMjUuNCwwLDMxLjgtMjQuMiwzMy4xLTMwLjNjMy4zLTAuNSw2LjEtMSw4LjEtMS4zYzAuNS0xLjMsMS4zLTMuOCwwLjgtNy4xYy0xMC4yLDMuOC0yNS40LDguNC00My41LDguNEMtNjQ0LjcsMzQ4LjYtNjQ0LjcsMzQ5LjEtNjQ0LjQsMzQ5Ljl6Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xNV8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI4MS44NSIgeTE9IjI1Ny41MTg3IiB4Mj0iLTI4MS44NSIgeTI9IjI2Mi42NTExIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDIuNTQ0NSAwIDAgLTIuNTQ0NSAxMDAuMTI3MiAxMDE3LjgxMTcpIj48c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+PHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNTVkdJRF8xNV8pIiBkPSJNLTYxMC4xLDM0OC45bC0zLjEsMC4zYzAsMC4zLTAuMywwLjUtMC41LDAuOGMtMC41LDEtMSwxLjgtMS41LDIuOGMtMC4zLDAuNS0wLjUsMC44LTAuOCwxLjNjLTAuNSwxLTEuMywyLTIsMi44Yy0wLjMsMC4zLTAuMywwLjMtMC41LDAuNWMtMS44LDIuMy0zLjYsNC4zLTUuNiw1LjlsNi40LDIuOEMtNjEyLjYsMzU5LjMtNjEwLjYsMzUxLjctNjEwLjEsMzQ4Ljl6Ii8+PC9nPjwvZz48Zz48Zz48ZGVmcz48Y2lyY2xlIGlkPSJTVkdJRF8xNl8iIGN4PSItNDA3LjMiIGN5PSIzNDYuMyIgcj0iNDIuMiIvPjwvZGVmcz48Y2xpcFBhdGggaWQ9IlNWR0lEXzE3XyI+PHVzZSB4bGluazpocmVmPSIjU1ZHSURfMTZfIiAgb3ZlcmZsb3c9InZpc2libGUiLz48L2NsaXBQYXRoPjxwYXRoIGNsaXAtcGF0aD0idXJsKCNTVkdJRF8xN18pIiBmaWxsPSIjRkZGRkZGIiBkPSJNLTQwMS4xLDM0OS40YzAuMywwLjMsMC41LDAuOCwwLjUsMC44YzcuNCwxLDE4LjEsMCwyNi4yLTEuM2MtNC42LDkuOS0xMywxNi41LTIwLjQsMTYuNWMtMTQuMiwwLTI1LjItMTcuMy0yNS4yLTE3LjNjNC4zLTMuOCwxMS43LTE2LjUsMjIuMS0xNi41czE1LDUuOSwxNSw1LjlsMS4zLTEuOGMwLDAtNC44LTE3LTE4LjgtMTdzLTI4LjUsMjIuNi0zNy4yLDI4YzAsMCwxMiwyOCwzNy43LDI4YzIxLjYsMCwyNy4yLTIwLjksMjguMi0yNmMyLjgtMC41LDUuMy0wLjgsNi45LTFjMC41LTEuMywxLTMuMywwLjgtNi4xYy04LjcsMy4zLTIxLjYsNy4xLTM3LjIsNy4xQy00MDEuNCwzNDguMy00MDEuNCwzNDguOS00MDEuMSwzNDkuNHoiLz48L2c+PC9nPjwvZz48ZyBpZD0iTGF5ZXJfMiI+PHBhdGggZmlsbD0iIzg4ODg4OCIgZD0iTTQ2Ny4zLDIwOS45Yy00LjgsMjQuNC0zMC44LDEyMi42LTEzMy42LDEyMi42Yy0xMjIuNiwwLTE3OC42LTEzMi44LTE3OC42LTEzMi44YzQxLTI0LjksMTEwLjQtMTMyLjMsMTc2LjEtMTMyLjNzODguOCw4MS4yLDg4LjgsODEuMmwtNS42LDguOWMwLDAtMjEuNi0yNy4yLTcxLjItMjcuMnMtODMuNyw1OS44LTEwNC42LDc4LjRjMCwwLDUyLjIsODEuNywxMTkuMyw4MS43YzM2LjEsMCw3NS4xLTMxLjMsOTYuOS03OC40Yy0zOC4yLDUuMy04OC4zLDEwLjItMTIzLjcsNS42YzAsMC0xLjgtMS41LTIuNS0zLjNjLTEtMi4zLTEuMy00LjYtMS4zLTQuNmM3MC4yLDAsMTMwLjUtMTYuNSwxNzEuNS0zMS44QzQ4Ny43LDc3LjYsNDAyLjksMCwzMDAuMSwwYy0xMTAuNCwwLTIwMCw4OS42LTIwMCwyMDBzODkuNiwyMDAsMjAwLDIwMGMxMDguOSwwLDE5Ny41LTg3LDIwMC0xOTUuNEM0OTIuNSwyMDUuOSw0ODEsMjA3LjksNDY3LjMsMjA5Ljl6Ii8+PC9nPjwvc3ZnPg==',
767
		'give_cpt_icon' => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOC4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAxNTcuMSAxNTcuMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTU3LjEgMTU3LjI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoJLnN0MHtmaWxsOiM2NkJCNkE7fQ0KCS5zdDF7ZmlsbDojNTQ2RTdBO30NCgkuc3Qye2ZpbGw6dXJsKCNTVkdJRF8xXyk7fQ0KCS5zdDN7ZmlsbDp1cmwoI1NWR0lEXzJfKTt9DQoJLnN0NHtmaWxsOnVybCgjU1ZHSURfM18pO30NCgkuc3Q1e2ZpbGw6dXJsKCNTVkdJRF80Xyk7fQ0KCS5zdDZ7ZmlsbDp1cmwoI1NWR0lEXzVfKTt9DQoJLnN0N3tmaWxsOnVybCgjU1ZHSURfNl8pO30NCgkuc3Q4e2ZpbGw6dXJsKCNTVkdJRF83Xyk7fQ0KCS5zdDl7ZmlsbDp1cmwoI1NWR0lEXzhfKTt9DQoJLnN0MTB7ZmlsbDp1cmwoI1NWR0lEXzlfKTt9DQoJLnN0MTF7ZmlsbDp1cmwoI1NWR0lEXzEwXyk7fQ0KCS5zdDEye2ZpbGw6dXJsKCNTVkdJRF8xMV8pO30NCgkuc3QxM3tmaWxsOnVybCgjU1ZHSURfMTJfKTt9DQoJLnN0MTR7ZmlsbDp1cmwoI1NWR0lEXzEzXyk7fQ0KCS5zdDE1e2ZpbGw6dXJsKCNTVkdJRF8xNF8pO30NCgkuc3QxNntmaWxsOiNGRkZGRkY7fQ0KCS5zdDE3e2ZpbGw6dXJsKCNTVkdJRF8xNV8pO30NCgkuc3QxOHtjbGlwLXBhdGg6dXJsKCNTVkdJRF8xN18pO2ZpbGw6I0ZGRkZGRjt9DQoJLnN0MTl7ZmlsbDojRjFGMkYyO30NCjwvc3R5bGU+DQo8ZyBpZD0iTGF5ZXJfMSI+DQoJPGNpcmNsZSBjbGFzcz0ic3QwIiBjeD0iLTE5OS40IiBjeT0iMTM2LjEiIHI9IjE2LjYiLz4NCgk8Zz4NCgkJPGc+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTM0OC40LDUyLjZ2LTQuOWgxLjljMS41LDAsMi42LDEsMi42LDIuNWMwLDEuNS0xLjEsMi41LTIuNiwyLjVILTM0OC40eiBNLTM0NC45LDUwLjENCgkJCQljMC0wLjktMC41LTEuNS0xLjUtMS41aC0wLjl2My4xaDAuOUMtMzQ1LjUsNTEuNy0zNDQuOSw1MS0zNDQuOSw1MC4xeiIvPg0KCQkJPHBhdGggY2xhc3M9InN0MSIgZD0iTS0zNDIuNiw1Mi42di00LjloMy41djAuOWgtMi40djFoMi40djAuOWgtMi40djEuMWgyLjR2MC45SC0zNDIuNnoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzMzLjUsNTIuNnYtMy40bC0xLjQsMy40aC0wLjVsLTEuNC0zLjR2My40aC0xdi00LjloMS41bDEuMiwzbDEuMi0zaDEuNXY0LjlILTMzMy41eiIvPg0KCQkJPHBhdGggY2xhc3M9InN0MSIgZD0iTS0zMzEuMSw1MC4xYzAtMS41LDEuMS0yLjUsMi42LTIuNWMxLjUsMCwyLjYsMS4xLDIuNiwyLjVjMCwxLjUtMS4xLDIuNS0yLjYsMi41DQoJCQkJQy0zMzAuMSw1Mi43LTMzMS4xLDUxLjYtMzMxLjEsNTAuMXogTS0zMjcuMSw1MC4xYzAtMC45LTAuNi0xLjYtMS41LTEuNnMtMS41LDAuNy0xLjUsMS42YzAsMC45LDAuNiwxLjYsMS41LDEuNg0KCQkJCVMtMzI3LjEsNTEtMzI3LjEsNTAuMXoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzI1LDUwLjFjMC0xLjUsMS4xLTIuNSwyLjYtMi41YzEuMSwwLDEuNywwLjYsMi4xLDEuMmwtMC45LDAuNGMtMC4yLTAuNC0wLjYtMC43LTEuMi0wLjcNCgkJCQljLTAuOSwwLTEuNSwwLjctMS41LDEuNmMwLDAuOSwwLjYsMS42LDEuNSwxLjZjMC41LDAsMC45LTAuMywxLjItMC43bDAuOSwwLjRjLTAuNCwwLjYtMSwxLjItMi4xLDEuMg0KCQkJCUMtMzIzLjgsNTIuNy0zMjUsNTEuNi0zMjUsNTAuMXoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzE2LjMsNTIuNmwtMS0xLjdoLTAuOHYxLjdoLTF2LTQuOWgyLjNjMSwwLDEuNiwwLjcsMS42LDEuNmMwLDAuOS0wLjUsMS4zLTEuMSwxLjVsMS4xLDEuOUgtMzE2LjN6DQoJCQkJIE0tMzE2LjIsNDkuMmMwLTAuNC0wLjMtMC43LTAuNy0wLjdoLTEuMXYxLjNoMS4xQy0zMTYuNiw0OS45LTMxNi4yLDQ5LjctMzE2LjIsNDkuMnoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzEwLjQsNTIuNmwtMC4zLTAuOGgtMi4xbC0wLjMsMC44aC0xLjJsMS45LTQuOWgxLjNsMS45LDQuOUgtMzEwLjR6IE0tMzExLjgsNDguN2wtMC44LDIuMWgxLjUNCgkJCQlMLTMxMS44LDQ4Ljd6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTMwNy42LDUyLjZ2LTRoLTEuNHYtMC45aDMuOXYwLjloLTEuNHY0SC0zMDcuNnoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzAzLjksNTIuNnYtNC45aDF2NC45SC0zMDMuOXoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMzAxLjUsNTIuNnYtMC44bDIuMy0zLjFoLTIuM3YtMC45aDMuN3YwLjhsLTIuMywzLjJoMi40djAuOUgtMzAxLjV6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI5Ni40LDUyLjZ2LTQuOWgxdjQuOUgtMjk2LjR6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI5MC41LDUyLjZsLTIuMy0zLjJ2My4yaC0xdi00LjloMS4xbDIuMywzLjF2LTMuMWgxdjQuOUgtMjkwLjV6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI4OC4yLDUwLjFjMC0xLjYsMS4yLTIuNSwyLjYtMi41YzEsMCwxLjcsMC41LDIsMS4xbC0wLjksMC41Yy0wLjItMC4zLTAuNi0wLjYtMS4yLTAuNg0KCQkJCWMtMC45LDAtMS41LDAuNy0xLjUsMS42YzAsMC45LDAuNiwxLjYsMS41LDEuNmMwLjQsMCwwLjgtMC4yLDEtMC40di0wLjZoLTEuM3YtMC45aDIuM3YxLjljLTAuNSwwLjYtMS4yLDAuOS0yLjEsMC45DQoJCQkJQy0yODcsNTIuNy0yODguMiw1MS43LTI4OC4yLDUwLjF6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI3OS45LDUwLjFjMC0xLjYsMS4yLTIuNSwyLjYtMi41YzEsMCwxLjcsMC41LDIsMS4xbC0wLjksMC41Yy0wLjItMC4zLTAuNi0wLjYtMS4yLTAuNg0KCQkJCWMtMC45LDAtMS41LDAuNy0xLjUsMS42YzAsMC45LDAuNiwxLjYsMS41LDEuNmMwLjQsMCwwLjgtMC4yLDEtMC40di0wLjZoLTEuM3YtMC45aDIuM3YxLjljLTAuNSwwLjYtMS4yLDAuOS0yLjEsMC45DQoJCQkJQy0yNzguNyw1Mi43LTI3OS45LDUxLjctMjc5LjksNTAuMXoiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0tMjczLjgsNTIuNnYtNC45aDMuNXYwLjloLTIuNHYxaDIuNHYwLjloLTIuNHYxLjFoMi40djAuOUgtMjczLjh6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI2NS42LDUyLjZsLTIuMy0zLjJ2My4yaC0xdi00LjloMS4xbDIuMywzLjF2LTMuMWgxdjQuOUgtMjY1LjZ6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI2Myw1Mi42di00LjloMy41djAuOWgtMi40djFoMi40djAuOWgtMi40djEuMWgyLjR2MC45SC0yNjN6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI1NS40LDUyLjZsLTEtMS43aC0wLjh2MS43aC0xdi00LjloMi4zYzEsMCwxLjYsMC43LDEuNiwxLjZjMCwwLjktMC41LDEuMy0xLjEsMS41bDEuMSwxLjlILTI1NS40eg0KCQkJCSBNLTI1NS4zLDQ5LjJjMC0wLjQtMC4zLTAuNy0wLjctMC43aC0xLjF2MS4zaDEuMUMtMjU1LjYsNDkuOS0yNTUuMyw0OS43LTI1NS4zLDQ5LjJ6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI1My4xLDUwLjFjMC0xLjUsMS4xLTIuNSwyLjYtMi41YzEuNSwwLDIuNiwxLjEsMi42LDIuNWMwLDEuNS0xLjEsMi41LTIuNiwyLjUNCgkJCQlDLTI1Mi4xLDUyLjctMjUzLjEsNTEuNi0yNTMuMSw1MC4xeiBNLTI0OS4xLDUwLjFjMC0wLjktMC42LTEuNi0xLjUtMS42Yy0wLjksMC0xLjUsMC43LTEuNSwxLjZjMCwwLjksMC42LDEuNiwxLjUsMS42DQoJCQkJQy0yNDkuNyw1MS43LTI0OS4xLDUxLTI0OS4xLDUwLjF6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTI0Ny4xLDUxLjlsMC42LTAuOGMwLjMsMC40LDAuOSwwLjcsMS42LDAuN2MwLjYsMCwwLjktMC4zLDAuOS0wLjVjMC0wLjktMi44LTAuMy0yLjgtMi4xDQoJCQkJYzAtMC44LDAuNy0xLjUsMS45LTEuNWMwLjgsMCwxLjQsMC4yLDEuOSwwLjdsLTAuNiwwLjhjLTAuNC0wLjQtMC45LTAuNS0xLjQtMC41Yy0wLjQsMC0wLjcsMC4yLTAuNywwLjVjMCwwLjgsMi44LDAuMywyLjgsMi4xDQoJCQkJYzAsMC45LTAuNiwxLjYtMiwxLjZDLTI0NS45LDUyLjctMjQ2LjYsNTIuMy0yNDcuMSw1MS45eiIvPg0KCQkJPHBhdGggY2xhc3M9InN0MSIgZD0iTS0yNDEuOCw1Mi42di00LjloMXY0LjlILTI0MS44eiIvPg0KCQkJPHBhdGggY2xhc3M9InN0MSIgZD0iTS0yMzguMSw1Mi42di00aC0xLjR2LTAuOWgzLjl2MC45aC0xLjR2NEgtMjM4LjF6Ii8+DQoJCQk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNLTIzMyw1Mi42di0ybC0xLjktMi45aDEuMmwxLjIsMmwxLjItMmgxLjJsLTEuOSwyLjl2MkgtMjMzeiIvPg0KCQk8L2c+DQoJCTxnPg0KCQkJPGc+DQoJCQkJPHBhdGggY2xhc3M9InN0MCIgZD0iTS0yMzAuMywxNy40bC0wLjUsMGwwLjEsMC41YzAuOCwzLjksMC4xLDkuNy0yLjksMTMuM2MtMS43LDIuMS0zLjksMy4yLTYuNiwzLjJjLTQuMywwLTUuOS01LjEtNi4xLTEwLjkNCgkJCQkJYzctMS43LDExLjctNi4xLDExLjctMTEuMmMwLTMuNy0xLjEtOS44LTguNC05LjhjLTYuOSwwLTEwLjQsMTAuMy0xMS4xLDE3LjVjLTMuNS0wLjEtNi4xLTEuNy03LjctMy4yYzAuNi0yLjUsMC45LTQuOCwwLjktNi45DQoJCQkJCWMwLTIuOS0yLTQuMi0zLjktNC4yYy0yLjcsMC01LjUsMi42LTUuNSw3LjZjMCwzLDEuMSw1LjUsMy40LDcuM2MtMiw0LjctNS40LDguNy02LjUsMTBjLTAuOS0xLjktMy44LTguOC00LjctMTYuMw0KCQkJCQljMS4xLTMsMS43LTUuNSwxLjctNi43YzAtMS45LTEuMi0zLTMuMi0zYy0yLjcsMC03LDEuNy03LjEsMS44bC0wLjIsMC4xbDAsMC4zYzAsMC4xLDEuMyw2LjEsMi42LDEyLjcNCgkJCQkJYy0yLjUsNC4xLTYuOSwxMC45LTkuMSwxMC45Yy00LDAsMi42LTIwLjUtMC4zLTIxLjJjLTAuMSwwLTAuMiwwLTAuMywwLjFjLTEuNCwwLjktMTcuMSw5LjYtMzgsOS42YzAsMCwwLDAuNCwwLjIsMC44DQoJCQkJCWMwLjEsMC4zLDAuNCwwLjYsMC40LDAuNmM1LjksMC43LDE0LjMtMC4xLDIwLjctMWMtMy43LDcuOS0xMC4yLDEzLjEtMTYuMiwxMy4xYy0xMS4zLDAtMjAtMTMuNy0yMC0xMy43DQoJCQkJCWMzLjUtMy4xLDkuMi0xMy4xLDE3LjYtMTMuMWM4LjMsMCwxMS45LDQuNiwxMS45LDQuNmwwLjktMS41YzAsMC0zLjktMTMuNi0xNC45LTEzLjZjLTExLDAtMjIuNywxOC0yOS41LDIyLjINCgkJCQkJYzAsMCw5LjQsMjIuMiwyOS45LDIyLjJjMTcuMiwwLDIxLjYtMTYuNSwyMi40LTIwLjVjNC4yLTAuNiw3LjEtMS4yLDcuMS0xLjJzLTEuMSw4LjQtMS4xLDExLjljMCwzLjUsMy45LDcuMiw3LjEsNy4yDQoJCQkJCWMyLjcsMCw4LjItNS42LDEyLjItMTIuNGwwLjIsMC44YzIuMSw3LjcsNC43LDExLjcsNy44LDExLjdjMy4xLDAsOC4yLTYuNCwxMS41LTE0LjVjMy4zLDEuNCw3LjIsMS44LDkuNSwxLjkNCgkJCQkJYzAuOSwxMy45LDEyLjUsMTQuMywxMy45LDE0LjNjOC42LDAsMTUuOS02LjIsMTUuOS0xMy41Qy0yMjQuMywxNy41LTIzMC4yLDE3LjQtMjMwLjMsMTcuNHogTS0yNDAuOCwxMS42YzAsMC0wLjEsNC42LTUuMyw2LjkNCgkJCQkJYzAuNS02LjEsMi0xMS42LDMtMTEuNkMtMjQyLDctMjQwLjgsOC43LTI0MC44LDExLjZ6Ii8+DQoJCQkJPHBhdGggY2xhc3M9InN0MCIgZD0iTS0zMDAuNyw2LjFjMCwwLjIsMC4xLDAuMywwLjMsMC40YzQuMSwwLjYsNi44LTAuNyw2LjgtNy4zYzAtNi4yLTYuNC0xLjMtNy42LTAuNA0KCQkJCQljLTAuMSwwLjEtMC4xLDAuMi0wLjEsMC40Qy0zMDAuMiwxLjYtMzAwLjYsNS4xLTMwMC43LDYuMXoiLz4NCgkJCTwvZz4NCgkJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMV8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI4OS41ODQ0IiB5MT0iMjYuNzY4IiB4Mj0iLTI4Mi44ODIzIiB5Mj0iMjQuNTM0Ij4NCgkJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQkJPHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPg0KCQkJPC9saW5lYXJHcmFkaWVudD4NCgkJCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0tMjg0LjIsMTkuNGMtMS42LDIuNy00LDYuNC02LjEsOC43YzAuNSwxLjIsMS4xLDIuNywxLjcsMy45YzEuOS0yLjEsMy44LTQuOCw1LjUtNy42TC0yODQuMiwxOS40eiIvPg0KCQkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8yXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMjY5LjAxOTQiIHkxPSIyOC40Nzc3IiB4Mj0iLTI2NS4xMzIyIiB5Mj0iMjEuNjQxNiI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3QzIiBkPSJNLTI2NS4yLDIxLjVjLTAuOC0wLjQtMS41LTEtMS41LTFjLTEuNCwzLjEtMy4zLDYtNC44LDcuOWMwLjcsMSwxLjksMi4zLDIuOCwzLjNjMS44LTIuNSwzLjctNS44LDUuMS05LjMNCgkJCQlDLTI2My41LDIyLjMtMjY0LjQsMjItMjY1LjIsMjEuNXoiLz4NCgkJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfM18iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI0OC42MjU0IiB5MT0iMzEuNjE0NyIgeDI9Ii0yNDkuNDI5NyIgeTI9IjI0LjQ2NTkiPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz4NCgkJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCQk8L2xpbmVhckdyYWRpZW50Pg0KCQkJPHBhdGggY2xhc3M9InN0NCIgZD0iTS0yNDYuMiwyMy41YzAsMC0yLDAuNC00LDAuNmMtMiwwLjItMy45LDAuMS0zLjksMC4xYzAuMyw0LDEuNCw2LjgsMi45LDguOWw3LjMtMC42DQoJCQkJQy0yNDUuNCwzMC41LTI0Ni4xLDI3LjEtMjQ2LjIsMjMuNXoiLz4NCgkJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfNF8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTI0OS43MjY3IiB5MT0iMTYuNDE5IiB4Mj0iLTI0OS43MjY3IiB5Mj0iMjMuNjIzNyI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3Q1IiBkPSJNLTI1MiwxMS4zTC0yNTIsMTEuM2MtMC4yLDAuNi0wLjUsMS4zLTAuNywyYzAsMC4yLTAuMSwwLjMtMC4xLDAuNWMtMC40LDEuMy0wLjcsMi42LTAuOSwzLjkNCgkJCQljMCwwLjItMC4xLDAuMy0wLjEsMC41Yy0wLjEsMC42LTAuMiwxLjItMC4yLDEuOGM0LjcsMCw3LjktMS40LDcuOS0xLjRjMC0wLjUsMC4xLTAuOSwwLjEtMS40YzAtMC4xLDAtMC4yLDAtMC4zDQoJCQkJYzAtMC40LDAuMS0wLjcsMC4xLTEuMWMwLTAuMSwwLTAuMiwwLTAuM2MwLjEtMC45LDAuMy0xLjgsMC40LTIuNkwtMjUyLDExLjN6IE0tMjU0LjEsMTkuOUMtMjU0LjEsMTkuOS0yNTQuMSwxOS45LTI1NC4xLDE5LjkNCgkJCQlMLTI1NC4xLDE5LjlDLTI1NC4xLDE5LjktMjU0LjEsMTkuOS0yNTQuMSwxOS45eiIvPg0KCQkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF81XyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzEzLjAyNzIiIHkxPSIyOC4yMjc4IiB4Mj0iLTMxMy4wMjcyIiB5Mj0iMTkuMjkxNyI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3Q2IiBkPSJNLTMxNy43LDI4LjZsNC40LDEuOWMyLjEtMywzLjQtNi4xLDQuMi04LjVsMC44LTMuMmwtMi4xLDAuM0MtMzEyLjMsMjMuMS0zMTQuOSwyNi4zLTMxNy43LDI4LjZ6Ii8+DQoJCQk8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzZfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0yNzcuNTIzOSIgeTE9IjkuNzg4IiB4Mj0iLTI3OC42NDYzIiB5Mj0iMTEuNTc1NiI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3Q3IiBkPSJNLTI3Ny45LDE0LjJjMS4xLTMsMS43LTUuNSwxLjctNi43YzAtMC4xLDAtMC4yLDAtMC4zbC0yLjYsMC44Qy0yNzguOCw4LTI3OC43LDkuNy0yNzcuOSwxNC4yeiIvPg0KCQkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF83XyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMjYyLjU1MjkiIHkxPSIxMy41MjQ4IiB4Mj0iLTI2My4xODY2IiB5Mj0iMTUuOTMyNiI+DQoJCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJCTwvbGluZWFyR3JhZGllbnQ+DQoJCQk8cGF0aCBjbGFzcz0ic3Q4IiBkPSJNLTI2My45LDEyYzAsMC0wLjcsMi4xLDIuMiw0LjdjMC41LTIuMSwwLjgtNC4yLDAuOS02TC0yNjMuOSwxMnoiLz4NCgkJPC9nPg0KCTwvZz4NCgk8Zz4NCgkJPGc+DQoJCQk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNLTM1Ni44LDEzNi4ybC0wLjIsMGwwLDAuMmMwLjMsMS43LDAsNC4xLTEuMiw1LjdjLTAuNywwLjktMS43LDEuNC0yLjgsMS40Yy0xLjgsMC0yLjUtMi4yLTIuNi00LjYNCgkJCQljMy0wLjcsNS0yLjYsNS00LjhjMC0xLjYtMC41LTQuMi0zLjYtNC4yYy0yLjksMC00LjQsNC40LTQuNyw3LjRjLTEuNSwwLTIuNi0wLjctMy4zLTEuNGMwLjMtMS4xLDAuNC0yLDAuNC0yLjkNCgkJCQljMC0xLjItMC45LTEuOC0xLjYtMS44Yy0xLjIsMC0yLjMsMS4xLTIuMywzLjJjMCwxLjMsMC41LDIuMywxLjUsMy4xYy0wLjksMi0yLjMsMy43LTIuOCw0LjJjLTAuNC0wLjgtMS42LTMuOC0yLTYuOQ0KCQkJCWMwLjUtMS4zLDAuNy0yLjMsMC43LTIuOGMwLTAuOC0wLjUtMS4zLTEuNC0xLjNjLTEuMiwwLTMsMC43LTMsMC44bC0wLjEsMC4xbDAsMC4xYzAsMCwwLjUsMi42LDEuMSw1LjQNCgkJCQljLTEuMSwxLjctMi45LDQuNi0zLjksNC42Yy0xLjcsMCwxLjEtOC43LTAuMS05YzAsMC0wLjEsMC0wLjEsMGMtMC42LDAuNC03LjMsNC4xLTE2LjEsNC4xYzAsMCwwLDAuMiwwLjEsMC4zDQoJCQkJYzAuMSwwLjEsMC4yLDAuMiwwLjIsMC4yYzIuNSwwLjMsNi4xLDAsOC44LTAuNGMtMS42LDMuMy00LjMsNS42LTYuOSw1LjZjLTQuOCwwLTguNS01LjgtOC41LTUuOGMxLjUtMS4zLDMuOS01LjYsNy41LTUuNg0KCQkJCWMzLjUsMCw1LjEsMS45LDUuMSwxLjlsMC40LTAuNmMwLDAtMS43LTUuOC02LjMtNS44cy05LjYsNy43LTEyLjUsOS40YzAsMCw0LDkuNSwxMi43LDkuNWM3LjMsMCw5LjItNyw5LjUtOC43DQoJCQkJYzEuOC0wLjMsMy0wLjUsMy0wLjVzLTAuNCwzLjYtMC40LDUuMXMxLjYsMy4xLDMsMy4xYzEuMiwwLDMuNS0yLjQsNS4yLTUuM2wwLjEsMC4zYzAuOSwzLjMsMiw1LDMuMyw1YzEuMywwLDMuNS0yLjcsNC45LTYuMQ0KCQkJCWMxLjQsMC42LDMuMSwwLjgsNCwwLjhjMC40LDUuOSw1LjMsNi4xLDUuOSw2LjFjMy43LDAsNi44LTIuNiw2LjgtNS43Qy0zNTQuMywxMzYuMy0zNTYuOCwxMzYuMi0zNTYuOCwxMzYuMnogTS0zNjEuMiwxMzMuNw0KCQkJCWMwLDAsMCwyLTIuMywzYzAuMi0yLjYsMC44LTQuOSwxLjMtNC45Qy0zNjEuOCwxMzEuOC0zNjEuMiwxMzIuNS0zNjEuMiwxMzMuN3oiLz4NCgkJCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0tMzg2LjcsMTMxLjRjMCwwLjEsMCwwLjEsMC4xLDAuMmMxLjcsMC4yLDIuOS0wLjMsMi45LTMuMWMwLTIuNi0yLjctMC42LTMuMi0wLjJjMCwwLTAuMSwwLjEsMCwwLjINCgkJCQlDLTM4Ni41LDEyOS41LTM4Ni43LDEzMC45LTM4Ni43LDEzMS40eiIvPg0KCQk8L2c+DQoJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfOF8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTM4MS45OTkzIiB5MT0iMTQwLjE3NjkiIHgyPSItMzc5LjE1MDQiIHkyPSIxMzkuMjI3MiI+DQoJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCTwvbGluZWFyR3JhZGllbnQ+DQoJCTxwYXRoIGNsYXNzPSJzdDkiIGQ9Ik0tMzc5LjcsMTM3Yy0wLjcsMS4xLTEuNywyLjctMi42LDMuN2MwLjIsMC41LDAuNSwxLjEsMC43LDEuN2MwLjgtMC45LDEuNi0yLDIuNC0zLjJMLTM3OS43LDEzN3oiLz4NCgkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF85XyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzczLjI1NzUiIHkxPSIxNDAuOTAzNyIgeDI9Ii0zNzEuNjA1MSIgeTI9IjEzNy45OTc4Ij4NCgkJCTxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz4NCgkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJPC9saW5lYXJHcmFkaWVudD4NCgkJPHBhdGggY2xhc3M9InN0MTAiIGQ9Ik0tMzcxLjYsMTM3LjljLTAuMy0wLjItMC42LTAuNC0wLjYtMC40Yy0wLjYsMS4zLTEuNCwyLjUtMiwzLjRjMC4zLDAuNCwwLjgsMSwxLjIsMS40DQoJCQljMC44LTEuMSwxLjYtMi40LDIuMi00Qy0zNzAuOSwxMzguMy0zNzEuMywxMzguMS0zNzEuNiwxMzcuOXoiLz4NCgkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xMF8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTM2NC41ODg0IiB5MT0iMTQyLjIzNzIiIHgyPSItMzY0LjkzMDMiIHkyPSIxMzkuMTk4MyI+DQoJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCTwvbGluZWFyR3JhZGllbnQ+DQoJCTxwYXRoIGNsYXNzPSJzdDExIiBkPSJNLTM2My42LDEzOC44YzAsMC0wLjgsMC4yLTEuNywwLjNjLTAuOCwwLjEtMS43LDAtMS43LDBjMC4xLDEuNywwLjYsMi45LDEuMiwzLjhsMy4xLTAuMw0KCQkJQy0zNjMuMiwxNDEuOC0zNjMuNSwxNDAuMy0zNjMuNiwxMzguOHoiLz4NCgkJPGxpbmVhckdyYWRpZW50IGlkPSJTVkdJRF8xMV8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iLTM2NS4wNTY2IiB5MT0iMTM1Ljc3NzciIHgyPSItMzY1LjA1NjYiIHkyPSIxMzguODQwMyI+DQoJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCTwvbGluZWFyR3JhZGllbnQ+DQoJCTxwYXRoIGNsYXNzPSJzdDEyIiBkPSJNLTM2NiwxMzMuNkwtMzY2LDEzMy42Yy0wLjEsMC4zLTAuMiwwLjYtMC4zLDAuOGMwLDAuMSwwLDAuMS0wLjEsMC4yYy0wLjIsMC42LTAuMywxLjEtMC40LDEuNw0KCQkJYzAsMC4xLDAsMC4xLDAsMC4yYzAsMC4zLTAuMSwwLjUtMC4xLDAuOGMyLDAsMy40LTAuNiwzLjQtMC42YzAtMC4yLDAtMC40LDAuMS0wLjZjMCwwLDAtMC4xLDAtMC4xYzAtMC4yLDAtMC4zLDAuMS0wLjQNCgkJCWMwLDAsMC0wLjEsMC0wLjFjMC4xLTAuNCwwLjEtMC44LDAuMi0xLjFMLTM2NiwxMzMuNnogTS0zNjYuOSwxMzcuM0MtMzY2LjksMTM3LjMtMzY2LjksMTM3LjMtMzY2LjksMTM3LjNMLTM2Ni45LDEzNy4zDQoJCQlDLTM2Ni45LDEzNy4zLTM2Ni45LDEzNy4zLTM2Ni45LDEzNy4zeiIvPg0KCQk8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzEyXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzkxLjk2NDQiIHkxPSIxNDAuNzk3NSIgeDI9Ii0zOTEuOTY0NCIgeTI9IjEzNi45OTg5Ij4NCgkJCTxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz4NCgkJCTxzdG9wICBvZmZzZXQ9IjEiIHN0eWxlPSJzdG9wLWNvbG9yOiMzNzhGNDMiLz4NCgkJPC9saW5lYXJHcmFkaWVudD4NCgkJPHBhdGggY2xhc3M9InN0MTMiIGQ9Ik0tMzk0LDE0MWwxLjksMC44YzAuOS0xLjMsMS40LTIuNiwxLjgtMy42bDAuMy0xLjRsLTAuOSwwLjFDLTM5MS43LDEzOC42LTM5Mi43LDE0MC0zOTQsMTQxeiIvPg0KCQk8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzEzXyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSItMzc2Ljg3MjYiIHkxPSIxMzIuOTU5IiB4Mj0iLTM3Ny4zNDk4IiB5Mj0iMTMzLjcxODkiPg0KCQkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6IzY2QkI2QSIvPg0KCQkJPHN0b3AgIG9mZnNldD0iMSIgc3R5bGU9InN0b3AtY29sb3I6IzM3OEY0MyIvPg0KCQk8L2xpbmVhckdyYWRpZW50Pg0KCQk8cGF0aCBjbGFzcz0ic3QxNCIgZD0iTS0zNzcsMTM0LjhjMC41LTEuMywwLjctMi4zLDAuNy0yLjhjMCwwLDAtMC4xLDAtMC4xbC0xLjEsMC4zQy0zNzcuNCwxMzIuMi0zNzcuNCwxMzIuOS0zNzcsMTM0Ljh6Ii8+DQoJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMTRfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0zNzAuNTA4OCIgeTE9IjEzNC41NDc1IiB4Mj0iLTM3MC43NzgxIiB5Mj0iMTM1LjU3MSI+DQoJCQk8c3RvcCAgb2Zmc2V0PSIwIiBzdHlsZT0ic3RvcC1jb2xvcjojNjZCQjZBIi8+DQoJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCTwvbGluZWFyR3JhZGllbnQ+DQoJCTxwYXRoIGNsYXNzPSJzdDE1IiBkPSJNLTM3MS4xLDEzMy45YzAsMC0wLjMsMC45LDAuOSwyYzAuMi0wLjksMC40LTEuOCwwLjQtMi42TC0zNzEuMSwxMzMuOXoiLz4NCgk8L2c+DQoJPGc+DQoJCTxyZWN0IHg9Ii0zMTMuNCIgeT0iMTE1LjEiIGNsYXNzPSJzdDE2IiB3aWR0aD0iNDIiIGhlaWdodD0iNDIiLz4NCgkJPGc+DQoJCQk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNLTI5Mi42LDEzNy41YzAuMSwwLjIsMC4yLDAuMywwLjIsMC4zYzMuNCwwLjQsOC4zLDAsMTItMC42Yy0yLjEsNC42LTUuOSw3LjYtOS40LDcuNg0KCQkJCWMtNi41LDAtMTEuNi03LjktMTEuNi03LjljMi0xLjgsNS40LTcuNiwxMC4yLTcuNnM2LjksMi42LDYuOSwyLjZsMC41LTAuOWMwLDAtMi4zLTcuOS04LjYtNy45Yy02LjQsMC0xMy4xLDEwLjQtMTcuMSwxMi44DQoJCQkJYzAsMCw1LjQsMTIuOSwxNy4zLDEyLjljMTAsMCwxMi41LTkuNSwxMy0xMS45YzEuMy0wLjIsMi40LTAuNCwzLjItMC41YzAuMi0wLjUsMC41LTEuNSwwLjMtMi44Yy00LDEuNS0xMCwzLjMtMTcuMSwzLjMNCgkJCQlDLTI5Mi43LDEzNy0yOTIuNywxMzcuMi0yOTIuNiwxMzcuNXoiLz4NCgkJCTxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMTVfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ii0yODEuNzk2MiIgeTE9IjE0Mi40ODEzIiB4Mj0iLTI4MS43OTYyIiB5Mj0iMTM3LjM0ODkiPg0KCQkJCTxzdG9wICBvZmZzZXQ9IjAiIHN0eWxlPSJzdG9wLWNvbG9yOiM2NkJCNkEiLz4NCgkJCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMzc4RjQzIi8+DQoJCQk8L2xpbmVhckdyYWRpZW50Pg0KCQkJPHBhdGggY2xhc3M9InN0MTciIGQ9Ik0tMjc5LjEsMTM3LjFsLTEuMiwwLjFjMCwwLjEtMC4xLDAuMi0wLjIsMC4zYy0wLjIsMC40LTAuNCwwLjctMC42LDEuMWMtMC4xLDAuMi0wLjIsMC4zLTAuMywwLjUNCgkJCQljLTAuMiwwLjQtMC41LDAuOC0wLjgsMS4xYy0wLjEsMC4xLTAuMSwwLjEtMC4yLDAuMmMtMC43LDAuOS0xLjQsMS43LTIuMiwyLjNsMi41LDEuMUMtMjgwLjEsMTQxLjItMjc5LjMsMTM4LjItMjc5LjEsMTM3LjF6Ii8+DQoJCTwvZz4NCgk8L2c+DQoJPGc+DQoJCTxkZWZzPg0KCQkJPGNpcmNsZSBpZD0iU1ZHSURfMTZfIiBjeD0iLTE5OS40IiBjeT0iMTM2LjEiIHI9IjE2LjYiLz4NCgkJPC9kZWZzPg0KCQk8Y2xpcFBhdGggaWQ9IlNWR0lEXzE3XyI+DQoJCQk8dXNlIHhsaW5rOmhyZWY9IiNTVkdJRF8xNl8iICBzdHlsZT0ib3ZlcmZsb3c6dmlzaWJsZTsiLz4NCgkJPC9jbGlwUGF0aD4NCgkJPHBhdGggY2xhc3M9InN0MTgiIGQ9Ik0tMTk3LDEzNy4zYzAuMSwwLjEsMC4yLDAuMywwLjIsMC4zYzIuOSwwLjQsNy4xLDAsMTAuMy0wLjVjLTEuOCwzLjktNS4xLDYuNS04LDYuNWMtNS42LDAtOS45LTYuOC05LjktNi44DQoJCQljMS43LTEuNSw0LjYtNi41LDguNy02LjVzNS45LDIuMyw1LjksMi4zbDAuNS0wLjdjMCwwLTEuOS02LjctNy40LTYuN3MtMTEuMiw4LjktMTQuNiwxMWMwLDAsNC43LDExLDE0LjgsMTENCgkJCWM4LjUsMCwxMC43LTguMiwxMS4xLTEwLjJjMS4xLTAuMiwyLjEtMC4zLDIuNy0wLjRjMC4yLTAuNSwwLjQtMS4zLDAuMy0yLjRjLTMuNCwxLjMtOC41LDIuOC0xNC42LDIuOA0KCQkJQy0xOTcuMSwxMzYuOS0xOTcuMSwxMzcuMS0xOTcsMTM3LjN6Ii8+DQoJPC9nPg0KPC9nPg0KPGcgaWQ9IkxheWVyXzIiPg0KCTxwYXRoIGNsYXNzPSJzdDE5IiBkPSJNMTQ0LjMsODIuNWMtMS45LDkuNi0xMi4xLDQ4LjItNTIuNSw0OC4yYy00OC4yLDAtNzAuMi01Mi4yLTcwLjItNTIuMmMxNi4xLTkuOCw0My40LTUyLDY5LjItNTINCgkJczM0LjksMzEuOSwzNC45LDMxLjlsLTIuMiwzLjVjMCwwLTguNS0xMC43LTI4LTEwLjdTNjIuNiw3NC43LDU0LjQsODJjMCwwLDIwLjUsMzIuMSw0Ni45LDMyLjFjMTQuMiwwLDI5LjUtMTIuMywzOC4xLTMwLjgNCgkJYy0xNSwyLjEtMzQuNyw0LTQ4LjYsMi4yYzAsMC0wLjctMC42LTEtMS4zYy0wLjQtMC45LTAuNS0xLjgtMC41LTEuOGMyNy42LDAsNTEuMy02LjUsNjcuNC0xMi41QzE1Mi4zLDMwLjUsMTE5LDAsNzguNiwwDQoJCUMzNS4yLDAsMCwzNS4yLDAsNzguNmMwLDQzLjQsMzUuMiw3OC42LDc4LjYsNzguNmM0Mi44LDAsNzcuNi0zNC4yLDc4LjYtNzYuOEMxNTQuMiw4MC45LDE0OS43LDgxLjcsMTQ0LjMsODIuNXoiLz4NCjwvZz4NCjwvc3ZnPg0K',
768
	);
769
770
	// Return the chosen icon's SVG string
771
	return $svgs[ $icon ];
772
}
773
774
/**
775
 * Modify Admin Nav Menu Label
776
 *
777
 * @since 1.3
778
 *
779
 * @param object $post_type The current object to add a menu items meta box for.
780
 *
781
 * @return mixed
782
 */
783
function modify_nav_menu_meta_box_object( $post_type ) {
784
	if ( isset( $post_type->name ) && $post_type->name == 'give_forms' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
785
		$post_type->labels->name = esc_html__( 'Donation Forms', 'give' );
786
	}
787
788
	return $post_type;
789
}
790
791
add_filter( 'nav_menu_meta_box_object', 'modify_nav_menu_meta_box_object' );
792
793
/**
794
 * Enable 'Donation Form' meta enabled by default on Menu page.
795
 *
796
 * @since 1.8.9
797
 */
798
function give_nav_donation_metabox_enabled() {
799
800
	// Return false, if it fails to retrieve hidden meta box list and is not admin.
801
	if ( ( ! $hidden_meta_boxes = get_user_option( 'metaboxhidden_nav-menus' ) ) || ! is_admin() ) {
802
		return false;
803
	}
804
805
	// Return false, In case, we don't find 'Donation Form' in hidden meta box list.
806
	if ( ! in_array( 'add-post-type-give_forms', $hidden_meta_boxes, true ) ) {
807
		return false;
808
	}
809
810
	// Exclude 'Donation Form' value from hidden meta box's list.
811
	$hidden_meta_boxes = array_diff( $hidden_meta_boxes, array( 'add-post-type-give_forms' ) );
812
813
	// Get current user ID.
814
	$user = wp_get_current_user();
815
816
	update_user_option( $user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true );
817
}
818
819
/**
820
 * Array_column backup usage
821
 *
822
 * This file is part of the array_column library.
823
 *
824
 * @since      : 1.3.0.1
825
 *
826
 * @copyright  Copyright (c) Ben Ramsey (http://benramsey.com)
827
 * @license    https://opensource.org/licenses/MIT MIT
828
 */
829
830
if ( ! function_exists( 'array_column' ) ) {
831
	/**
832
	 * Returns the values from a single column of the input array, identified by
833
	 * the $columnKey.
834
	 *
835
	 * Optionally, you may provide an $indexKey to index the values in the returned
836
	 * array by the values from the $indexKey column in the input array.
837
	 *
838
	 * @param array $input A multi-dimensional array (record set) from which to pull
839
	 *                              a column of values.
840
	 * @param int|string $columnKey The column of values to return. This value may be the
841
	 *                              integer key of the column you wish to retrieve, or it
842
	 *                              may be the string key name for an associative array.
843
	 * @param mixed $indexKey (Optional.) The column to use as the index/keys for
844
	 *                              the returned array. This value may be the integer key
845
	 *                              of the column, or it may be the string key name.
846
	 *
847
	 * @return array
848
	 */
849
	function array_column( $input = null, $columnKey = null, $indexKey = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $input is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $columnKey is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $indexKey is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
850
		// Using func_get_args() in order to check for proper number of
851
		// parameters and trigger errors exactly as the built-in array_column()
852
		// does in PHP 5.5.
853
		$argc   = func_num_args();
854
		$params = func_get_args();
855
856
		if ( $argc < 2 ) {
857
			trigger_error( sprintf( esc_html__( 'array_column() expects at least 2 parameters, %s given.', 'give' ), $argc ), E_USER_WARNING );
858
859
			return null;
860
		}
861
862
		if ( ! is_array( $params[0] ) ) {
863
			trigger_error( sprintf( esc_html__( 'array_column() expects parameter 1 to be array, %s given.', 'give' ), gettype( $params[0] ) ), E_USER_WARNING );
864
865
			return null;
866
		}
867
868 View Code Duplication
		if ( ! is_int( $params[1] )
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
869
		     && ! is_float( $params[1] )
870
		     && ! is_string( $params[1] )
871
		     && $params[1] !== null
872
		     && ! ( is_object( $params[1] ) && method_exists( $params[1], '__toString' ) )
873
		) {
874
			trigger_error( esc_html__( 'array_column(): The column key should be either a string or an integer.', 'give' ), E_USER_WARNING );
875
876
			return false;
877
		}
878
879 View Code Duplication
		if ( isset( $params[2] )
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
880
		     && ! is_int( $params[2] )
881
		     && ! is_float( $params[2] )
882
		     && ! is_string( $params[2] )
883
		     && ! ( is_object( $params[2] ) && method_exists( $params[2], '__toString' ) )
884
		) {
885
			trigger_error( esc_html__( 'array_column(): The index key should be either a string or an integer.', 'give' ), E_USER_WARNING );
886
887
			return false;
888
		}
889
890
		$paramsInput     = $params[0];
891
		$paramsColumnKey = ( $params[1] !== null ) ? (string) $params[1] : null;
892
893
		$paramsIndexKey = null;
894
		if ( isset( $params[2] ) ) {
895
			if ( is_float( $params[2] ) || is_int( $params[2] ) ) {
896
				$paramsIndexKey = (int) $params[2];
897
			} else {
898
				$paramsIndexKey = (string) $params[2];
899
			}
900
		}
901
902
		$resultArray = array();
903
904
		foreach ( $paramsInput as $row ) {
905
			$key    = $value = null;
906
			$keySet = $valueSet = false;
907
908
			if ( $paramsIndexKey !== null && array_key_exists( $paramsIndexKey, $row ) ) {
909
				$keySet = true;
910
				$key    = (string) $row[ $paramsIndexKey ];
911
			}
912
913
			if ( $paramsColumnKey === null ) {
914
				$valueSet = true;
915
				$value    = $row;
916
			} elseif ( is_array( $row ) && array_key_exists( $paramsColumnKey, $row ) ) {
917
				$valueSet = true;
918
				$value    = $row[ $paramsColumnKey ];
919
			}
920
921
			if ( $valueSet ) {
922
				if ( $keySet ) {
923
					$resultArray[ $key ] = $value;
924
				} else {
925
					$resultArray[] = $value;
926
				}
927
			}
928
		}
929
930
		return $resultArray;
931
	}
932
}// End if().
933
934
/**
935
 * Determines the receipt visibility status.
936
 *
937
 * @since 1.3.2
938
 *
939
 * @param string $payment_key
940
 *
941
 * @return bool Whether the receipt is visible or not.
942
 */
943
function give_can_view_receipt( $payment_key = '' ) {
944
945
	$return = false;
946
947
	if ( empty( $payment_key ) ) {
948
		return $return;
949
	}
950
951
	global $give_receipt_args;
952
953
	$give_receipt_args['id'] = give_get_purchase_id_by_key( $payment_key );
954
955
	$user_id = (int) give_get_payment_user_id( $give_receipt_args['id'] );
956
957
	$payment_meta = give_get_payment_meta( $give_receipt_args['id'] );
958
959
	if ( is_user_logged_in() ) {
960
		if ( $user_id === (int) get_current_user_id() ) {
961
			$return = true;
962
		} elseif ( wp_get_current_user()->user_email === give_get_payment_user_email( $give_receipt_args['id'] ) ) {
963
			$return = true;
964
		} elseif ( current_user_can( 'view_give_sensitive_data' ) ) {
965
			$return = true;
966
		}
967
	}
968
969
	$session = give_get_purchase_session();
970
	if ( ! empty( $session ) && ! is_user_logged_in() ) {
971
		if ( $session['purchase_key'] === $payment_meta['key'] ) {
972
			$return = true;
973
		}
974
	}
975
976
	return (bool) apply_filters( 'give_can_view_receipt', $return, $payment_key );
977
978
}
979
980
/**
981
 * Fallback for cal_days_in_month
982
 *
983
 * Fallback in case the calendar extension is not loaded in PHP; Only supports Gregorian calendar
984
 */
985
if ( ! function_exists( 'cal_days_in_month' ) ) {
986
	/**
987
	 * cal_days_in_month
988
	 *
989
	 * @param int $calendar
990
	 * @param int $month
991
	 * @param int $year
992
	 *
993
	 * @return bool|string
994
	 */
995
	function cal_days_in_month( $calendar, $month, $year ) {
0 ignored issues
show
Unused Code introduced by
The parameter $calendar is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
996
		return date( 't', mktime( 0, 0, 0, $month, 1, $year ) );
997
	}
998
}
999
1000
/**
1001
 * Get plugin info including status, type, and license validation.
1002
 *
1003
 * This is an enhanced version of get_plugins() that returns the status
1004
 * (`active` or `inactive`) of all plugins, type of plugin (`add-on` or `other`
1005
 * and license validation for Give add-ons (`true` or `false`). Does not include
1006
 * MU plugins.
1007
 *
1008
 * @since 1.8.0
1009
 *
1010
 * @return array Plugin info plus status, type, and license validation if
1011
 *               available.
1012
 */
1013
function give_get_plugins() {
1014
	$plugins             = get_plugins();
1015
	$active_plugin_paths = (array) get_option( 'active_plugins', array() );
1016
1017
	if ( is_multisite() ) {
1018
		$network_activated_plugin_paths = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
1019
		$active_plugin_paths            = array_merge( $active_plugin_paths, $network_activated_plugin_paths );
1020
	}
1021
1022
	foreach ( $plugins as $plugin_path => $plugin_data ) {
1023
		// Is plugin active?
1024
		if ( in_array( $plugin_path, $active_plugin_paths ) ) {
1025
			$plugins[ $plugin_path ]['Status'] = 'active';
1026
		} else {
1027
			$plugins[ $plugin_path ]['Status'] = 'inactive';
1028
		}
1029
1030
		$dirname = strtolower( dirname( $plugin_path ) );
1031
1032
		// Is plugin a Give add-on by WordImpress?
1033
		if ( strstr( $dirname, 'give-' ) && strstr( $plugin_data['AuthorURI'], 'wordimpress.com' ) ) {
1034
			// Plugin is a Give-addon.
1035
			$plugins[ $plugin_path ]['Type'] = 'add-on';
1036
1037
			// Get license info from database.
1038
			$plugin_name    = str_replace( 'Give - ', '', $plugin_data['Name'] );
1039
			$db_option      = 'give_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $plugin_name ) ) ) . '_license_active';
1040
			$license_active = get_option( $db_option );
1041
1042
			// Does a valid license exist?
1043
			if ( ! empty( $license_active ) && 'valid' === $license_active->license ) {
1044
				$plugins[ $plugin_path ]['License'] = true;
1045
			} else {
1046
				$plugins[ $plugin_path ]['License'] = false;
1047
			}
1048
		} else {
1049
			// Plugin is not a Give add-on.
1050
			$plugins[ $plugin_path ]['Type'] = 'other';
1051
		}
1052
	}
1053
1054
	return $plugins;
1055
}
1056
1057
1058
/**
1059
 * Check if terms enabled or not for form.
1060
 *
1061
 * @since 1.8
1062
 *
1063
 * @param $form_id
1064
 *
1065
 * @return bool
1066
 */
1067
function give_is_terms_enabled( $form_id ) {
1068
	$form_option = give_get_meta( $form_id, '_give_terms_option', true );
1069
1070
	if (
1071
		give_is_setting_enabled( $form_option, 'global' )
1072
		&& give_is_setting_enabled( give_get_option( 'terms' ) )
1073
	) {
1074
		return true;
1075
1076
	} elseif ( give_is_setting_enabled( $form_option ) ) {
1077
		return true;
1078
1079
	} else {
1080
		return false;
1081
	}
1082
}
1083
1084
1085
/**
1086
 * Delete donation stats cache.
1087
 *
1088
 * @todo  Resolve stats cache key naming issue. Currently it is difficult to regenerate cache key.
1089
 *
1090
 * @since 1.8.7
1091
 *
1092
 * @param string|array $date_range Date for stats.
1093
 *                                 Date value should be in today, yesterday, this_week, last_week, this_month, last_month, this_quarter, last_quarter, this_year, last_year.
1094
 *                                 For date value other, all cache will be removed.
1095
 *
1096
 * @param array $args
1097
 *
1098
 * @return WP_Error|bool
1099
 */
1100
function give_delete_donation_stats( $date_range = '', $args = array() ) {
1101
	// Delete all cache.
1102
	$status = Give_Cache::delete( Give_Cache::get_options_like( 'give_stats' ) );
1103
1104
	/**
1105
	 * Fire the action when donation stats delete.
1106
	 *
1107
	 * @since 1.8.7
1108
	 *
1109
	 * @param string|array $date_range
1110
	 * @param array $args
1111
	 */
1112
	do_action( 'give_delete_donation_stats', $status, $date_range, $args );
1113
1114
	return $status;
1115
}
1116
1117
1118
/**
1119
 * Get Form/Payment meta.
1120
 *
1121
 * @since 1.8.8
1122
 *
1123
 * @param int $id
1124
 * @param string $meta_key
1125
 * @param bool $single
1126
 * @param bool $default
1127
 *
1128
 * @return mixed
1129
 */
1130
function give_get_meta( $id, $meta_key, $single = false, $default = false ) {
1131
	/**
1132
	 * Filter the meta value
1133
	 *
1134
	 * @since 1.8.8
1135
	 */
1136
	$meta_value = apply_filters(
1137
		'give_get_meta',
1138
		get_post_meta( $id, $meta_key, $single ),
1139
		$id,
1140
		$meta_key,
1141
		$default
1142
	);
1143
1144
	if (
1145
		( empty( $meta_key ) || empty( $meta_value ) )
1146
		&& $default
1147
	) {
1148
		$meta_value = $default;
1149
	}
1150
1151
	return $meta_value;
1152
}
1153
1154
/**
1155
 * Update Form/Payment meta.
1156
 *
1157
 * @since 1.8.8
1158
 *
1159
 * @param int $id
1160
 * @param string $meta_key
1161
 * @param string $meta_value
1162
 * @param string $prev_value
1163
 *
1164
 * @return mixed
1165
 */
1166
function give_update_meta( $id, $meta_key, $meta_value, $prev_value = '' ) {
1167
	$status = update_post_meta( $id, $meta_key, $meta_value, $prev_value );
1168
1169
	/**
1170
	 * Filter the meta value update status
1171
	 *
1172
	 * @since 1.8.8
1173
	 */
1174
	return apply_filters( 'give_update_meta', $status, $id, $meta_key, $meta_value );
1175
}
1176
1177
/**
1178
 * Delete Form/Payment meta.
1179
 *
1180
 * @since 1.8.8
1181
 *
1182
 * @param int $id
1183
 * @param string $meta_key
1184
 * @param string $meta_value
1185
 *
1186
 * @return mixed
1187
 */
1188
function give_delete_meta( $id, $meta_key, $meta_value = '' ) {
1189
	$status = delete_post_meta( $id, $meta_key, $meta_value );
1190
1191
	/**
1192
	 * Filter the meta value delete status
1193
	 *
1194
	 * @since 1.8.8
1195
	 */
1196
	return apply_filters( 'give_delete_meta', $status, $id, $meta_key, $meta_value );
1197
}
1198
1199
/**
1200
 * Check if the upgrade routine has been run for a specific action
1201
 *
1202
 * @since  1.0
1203
 *
1204
 * @param  string $upgrade_action The upgrade action to check completion for
1205
 *
1206
 * @return bool                   If the action has been added to the completed actions array
1207
 */
1208
function give_has_upgrade_completed( $upgrade_action = '' ) {
1209
1210
	if ( empty( $upgrade_action ) ) {
1211
		return false;
1212
	}
1213
1214
	$completed_upgrades = give_get_completed_upgrades();
1215
1216
	return in_array( $upgrade_action, $completed_upgrades );
1217
1218
}
1219
1220
/**
1221
 * For use when doing 'stepped' upgrade routines, to see if we need to start somewhere in the middle
1222
 *
1223
 * @since 1.8
1224
 *
1225
 * @return mixed   When nothing to resume returns false, otherwise starts the upgrade where it left off
1226
 */
1227
function give_maybe_resume_upgrade() {
1228
	$doing_upgrade = get_option( 'give_doing_upgrade', false );
1229
	if ( empty( $doing_upgrade ) ) {
1230
		return false;
1231
	}
1232
1233
	return $doing_upgrade;
1234
}
1235
1236
/**
1237
 * Adds an upgrade action to the completed upgrades array
1238
 *
1239
 * @since  1.0
1240
 *
1241
 * @param  string $upgrade_action The action to add to the completed upgrades array
1242
 *
1243
 * @return bool                   If the function was successfully added
1244
 */
1245
function give_set_upgrade_complete( $upgrade_action = '' ) {
1246
1247
	if ( empty( $upgrade_action ) ) {
1248
		return false;
1249
	}
1250
1251
	$completed_upgrades   = give_get_completed_upgrades();
1252
	$completed_upgrades[] = $upgrade_action;
1253
1254
	// Remove any blanks, and only show uniques.
1255
	$completed_upgrades = array_unique( array_values( $completed_upgrades ) );
1256
1257
	/**
1258
	 * Fire the action when any upgrade set to complete.
1259
	 *
1260
	 * @since 1.8.12
1261
	 */
1262
	do_action( 'give_set_upgrade_completed', $upgrade_action, $completed_upgrades );
1263
1264
	return update_option( 'give_completed_upgrades', $completed_upgrades );
1265
}
1266
1267
/**
1268
 * Get's the array of completed upgrade actions
1269
 *
1270
 * @since  1.0
1271
 * @return array The array of completed upgrades
1272
 */
1273
function give_get_completed_upgrades() {
1274
	return (array) get_option( 'give_completed_upgrades' );
1275
}
1276
1277
1278
/**
1279
 * Return Import Page URL
1280
 *
1281
 * @since 1.8.13
1282
 *
1283
 * @param array $parameter
1284
 *
1285
 * @return string URL
1286
 */
1287
function give_import_page_url( $parameter = array() ) {
1288
	$defalut_query_arg = array(
1289
		'post_type' => 'give_forms',
1290
		'page'      => 'give-tools',
1291
		'tab'       => 'import',
1292
	);
1293
	$import_query_arg  = wp_parse_args( $parameter, $defalut_query_arg );
1294
1295
	return add_query_arg( $import_query_arg, admin_url( 'edit.php' ) );
1296
}
1297
1298
/**
1299
 * Add import Donation forms, donations , donor from CSV to database
1300
 *
1301
 * @since 1.8.13
1302
 *
1303
 * @param array $raw_key Setup bu user at step 2.
1304
 * @param array $row_data Feilds that are being imported from CSV
1305
 * @param array $main_key First row from the CSV
1306
 * @param array $import_setting Contain the global variable.
1307
 */
1308
function give_save_import_donation_to_db( $raw_key, $row_data, $main_key = array(), $import_setting = array() ) {
1309
	$data                          = array_combine( $raw_key, $row_data );
1310
	$price_id                      = false;
0 ignored issues
show
Unused Code introduced by
$price_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1311
	$customer_id                   = 0;
1312
	$import_setting['create_user'] = ( isset( $import_setting['create_user'] ) ? $import_setting['create_user'] : 1 );
1313
1314
	$data = (array) apply_filters( 'give_save_import_donation_to_db', $data );
1315
1316
	if ( ! strpos( $data['amount'], '.' ) ) {
1317
		$data['amount'] = $data['amount'] . '.00';
1318
	}
1319
1320
	// Here come the login function.
1321
	$donor_data = give_import_get_user_from_csv( $data, $import_setting );
1322
	if ( ! empty( $donor_data->id ) ) {
1323
		if ( ! empty( $donor_data->user_id ) ) {
1324
			$customer_id = $donor_data->user_id;
1325
		} elseif ( ! empty( $data['user_id'] ) ) {
1326
			$customer_id = $data['user_id'];
1327
		}
1328
	} else {
1329
		return false;
1330
	}
1331
1332
	// get form data or register a form data.
1333
	$form = give_import_get_form_data_from_csv( $data, $import_setting );
1334
	if ( false == $form ) {
1335
		return false;
1336
	} else {
1337
		$price_id = ( ! empty( $form->price_id ) ) ? $form->price_id : false;
1338
	}
1339
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1340
1341
	$address = array(
1342
		'line1'   => ( ! empty( $data['line1'] ) ? give_clean( $data['line1'] ) : '' ),
1343
		'line2'   => ( ! empty( $data['line1'] ) ? give_clean( $data['line2'] ) : '' ),
1344
		'city'    => ( ! empty( $data['line1'] ) ? give_clean( $data['city'] ) : '' ),
1345
		'zip'     => ( ! empty( $data['zip'] ) ? give_clean( $data['zip'] ) : '' ),
1346
		'state'   => ( ! empty( $data['state'] ) ? give_clean( $data['state'] ) : '' ),
1347
		'country' => ( ! empty( $data['country'] ) ? ( ( $country_code = array_search( $data['country'], give_get_country_list() ) ) ? $country_code : $data['country'] ) : '' ),
1348
	);
1349
1350
	//Create payment_data array
1351
	$payment_data = array(
1352
		'donor_id'        => $donor_data->id,
1353
		'price'           => $data['amount'],
1354
		'status'          => ( ! empty( $data['post_status'] ) ? $data['post_status'] : 'publish' ),
1355
		'currency'        => give_get_currency(),
1356
		'user_info'       => array(
1357
			'id'         => $customer_id,
1358
			'email'      => ( ! empty( $data['email'] ) ? $data['email'] : ( isset( $donor_data->email ) ? $donor_data->email : false ) ),
1359
			'first_name' => ( ! empty( $data['first_name'] ) ? $data['first_name'] : ( ! empty( $customer_id ) && ( $first_name = get_user_meta( $customer_id, 'first_name', true ) ) ? $first_name : $donor_data->name ) ),
0 ignored issues
show
introduced by
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1360
			'last_name'  => ( ! empty( $data['last_name'] ) ? $data['last_name'] : ( ! empty( $customer_id ) && ( $last_name = get_user_meta( $customer_id, 'last_name', true ) ) ? $last_name : $donor_data->name ) ),
0 ignored issues
show
introduced by
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1361
			'address'    => $address,
1362
		),
1363
		'gateway'         => ( ! empty( $data['gateway'] ) && 'offline' != strtolower( $data['gateway'] ) ? strtolower( $data['gateway'] ) : 'manual' ),
1364
		'give_form_title' => ( ! empty( $data['form_title'] ) ? $data['form_title'] : $form->get_name() ),
1365
		'give_form_id'    => (string) $form->get_ID(),
1366
		'give_price_id'   => $price_id,
1367
		'purchase_key'    => strtolower( md5( uniqid() ) ),
1368
		'user_email'      => $data['email'],
1369
		'post_date'       => ( ! empty( $data['post_date'] ) ? mysql2date( 'Y-m-d H:i:s', $data['post_date'] ) : current_time( 'mysql' ) ),
1370
		'mode'            => ( ! empty( $data['mode'] ) ? ( 'true' == (string) $data['mode'] || 'TRUE' == (string) $data['mode'] ? 'test' : 'live' ) : ( isset( $import_setting['mode'] ) ? ( true == (bool) $import_setting['mode'] ? 'test' : 'live' ) : ( give_is_test_mode() ? 'test' : 'live' ) ) ),
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1371
	);
1372
1373
	$payment_data = apply_filters( 'give_import_before_import_payment', $payment_data, $data, $donor_data, $form );
1374
1375
	// Get the report
1376
	$report = give_import_donation_report();
1377
1378
	// Check for duplicate code.
1379
	if ( true === give_check_import_donation_duplicate( $payment_data, $data, $form, $donor_data ) ) {
1380
		$report['duplicate_donation'] = ( ! empty( $report['duplicate_donation'] ) ? ( absint( $report['duplicate_donation'] ) + 1 ) : 1 );
1381
	} else {
1382
		add_action( 'give_update_payment_status', 'give_donation_import_insert_default_payment_note', 1, 1 );
1383
		add_filter( 'give_insert_payment_args', 'give_donation_import_give_insert_payment_args', 11, 2 );
1384
		add_filter( 'give_update_donor_information', 'give_donation_import_update_donor_information', 11, 3 );
1385
		add_action( 'give_insert_payment', 'give_import_donation_insert_payment', 11, 2 );
1386
		$payment = give_insert_payment( $payment_data );
1387
		remove_action( 'give_update_payment_status', 'give_donation_import_insert_default_payment_note', 1 );
1388
		remove_filter( 'give_insert_payment_args', 'give_donation_import_give_insert_payment_args', 11 );
1389
		remove_filter( 'give_update_donor_information', 'give_donation_import_update_donor_information', 11 );
1390
		remove_action( 'give_insert_payment', 'give_import_donation_insert_payment', 11 );
1391
1392
		if ( $payment ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payment of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1393
1394
			$report['create_donation'] = ( ! empty( $report['create_donation'] ) ? ( absint( $report['create_donation'] ) + 1 ) : 1 );
1395
1396
			update_post_meta( $payment, '_give_payment_import', true );
1397
1398
			if ( ! empty( $import_setting['csv'] ) ) {
1399
				update_post_meta( $payment, '_give_payment_import_id', $import_setting['csv'] );
1400
			}
1401
1402
			// Insert Notes.
1403
			if ( ! empty( $data['notes'] ) ) {
1404
				give_insert_payment_note( $payment, $data['notes'] );
1405
			}
1406
1407
			$meta_exists = array_keys( $raw_key, 'post_meta' );
1408
			if ( ! empty( $main_key ) && ! empty( $meta_exists ) ) {
1409
				foreach ( $meta_exists as $meta_exist ) {
1410
					if ( ! empty( $main_key[ $meta_exist ] ) && ! empty( $row_data[ $meta_exist ] ) ) {
1411
						update_post_meta( $payment, $main_key[ $meta_exist ], $row_data[ $meta_exist ] );
1412
					}
1413
				}
1414
			}
1415
		} else {
1416
			$report['failed_donation'] = ( ! empty( $report['failed_donation'] ) ? ( absint( $report['failed_donation'] ) + 1 ) : 1 );
1417
		}
1418
	}
1419
1420
	// update the report
1421
	give_import_donation_report_update( $report );
1422
}
1423
1424
/**
1425
 * Alter donor information when importing donations from CSV
1426
 *
1427
 * @since 1.8.13
1428
 *
1429
 * @param $donor
1430
 * @param $payment_id
1431
 * @param $payment_data
1432
 *
1433
 * @return Give_Donor
1434
 */
1435
function give_donation_import_update_donor_information( $donor, $payment_id, $payment_data ) {
0 ignored issues
show
Unused Code introduced by
The parameter $payment_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1436
	$old_donor = $donor;
1437
	if ( ! empty( $payment_data['donor_id'] ) ) {
1438
		$donor_id = absint( $payment_data['donor_id'] );
1439
		$donor    = new Give_Donor( $donor_id );
1440
		if ( ! empty( $donor->id ) ) {
1441
			return $donor;
1442
		}
1443
	}
1444
1445
	return $old_donor;
1446
}
1447
1448
/*
1449
 * Give update purchase_count of give customer.
1450
 *
1451
 * @since 1.8.13
1452
 */
1453
function give_import_donation_insert_payment( $payment_id, $payment_data ) {
1454
	// Update Give Customers purchase_count
1455
	if ( ! empty( $payment_data['status'] ) && ( 'complete' === (string) $payment_data['status'] || 'publish' === (string) $payment_data['status'] ) ) {
1456
		$donor_id = (int) get_post_meta( $payment_id, '_give_payment_customer_id', true );
1457
		if ( ! empty( $donor_id ) ) {
1458
			$donor = new Give_Donor( $donor_id );
0 ignored issues
show
Documentation introduced by
$donor_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1459
			$donor->increase_purchase_count();
1460
		}
1461
	}
1462
}
1463
1464
/**
1465
 * Add author id in in donation post
1466
 *
1467
 * @since 8.1.13
1468
 */
1469
function give_donation_import_give_insert_payment_args( $args, $payment_data ) {
1470
	if ( ! empty( $payment_data['user_info']['id'] ) ) {
1471
		$args['post_author'] = (int) $payment_data['user_info']['id'];
1472
	}
1473
1474
	return $args;
1475
}
1476
1477
/**
1478
 * Check if Import donation is duplicate
1479
 *
1480
 * @since 1.8.13
1481
 */
1482
function give_check_import_donation_duplicate( $payment_data, $data, $form, $donor_data ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $donor_data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1483
	$return = false;
1484
	if ( ! empty( $data['post_date'] ) ) {
1485
		$post_date = mysql2date( 'Y-m-d-H-i-s', $data['post_date'] );
1486
		$post_date = explode( '-', $post_date );
1487
		$args      = array(
1488
			'post_type'              => 'give_payment',
1489
			'cache_results'          => false,
1490
			'no_found_rows'          => true,
1491
			'update_post_meta_cache' => false,
1492
			'update_post_term_cache' => false,
1493
			'fields'                 => 'ids',
1494
			'date_query'             => array(
1495
				array(
1496
					'year'   => $post_date[0],
1497
					'month'  => $post_date[1],
1498
					'day'    => $post_date[2],
1499
					'hour'   => $post_date[3],
1500
					'minute' => $post_date[4],
1501
					'second' => $post_date[5],
1502
				),
1503
			),
1504
			'meta_query'             => array(
0 ignored issues
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
1505
				array(
1506
					'key'     => '_give_payment_total',
1507
					'value'   => preg_replace( '/[\$,]/', '', $payment_data['price'] ),
1508
					'compare' => 'LIKE',
1509
				),
1510
				array(
1511
					'key'     => '_give_payment_form_id',
1512
					'value'   => $payment_data['give_form_id'],
1513
					'type'    => 'numeric',
1514
					'compare' => '=',
1515
				),
1516
				array(
1517
					'key'     => '_give_payment_gateway',
1518
					'value'   => $payment_data['gateway'],
1519
					'compare' => '=',
1520
				),
1521
			),
1522
		);
1523
1524
		$payments  = new Give_Payments_Query( $args );
1525
		$donations = $payments->get_payments();
1526
		if ( ! empty( $donations ) ) {
1527
			return true;
1528
		}
1529
	}
1530
1531
	return $return;
1532
}
1533
1534
/**
1535
 * Record payment notes that is being imported from CSV.
1536
 *
1537
 * @since  1.8.13
1538
 *
1539
 * @param  int $payment_id The ID number of the payment.
1540
 *
1541
 * @return void
1542
 */
1543
function give_donation_import_insert_default_payment_note( $payment_id ) {
1544
	$current_user = wp_get_current_user();
1545
	give_insert_payment_note( $payment_id, esc_html( wp_sprintf( __( 'This donation was imported by %s', 'give' ), $current_user->user_email ) ) );
1546
}
1547
1548
1549
/**
1550
 * Remove login when user register with give functions.
1551
 *
1552
 * @since 1.8.13
1553
 *
1554
 * @param $value
1555
 *
1556
 * @return bool
1557
 */
1558
function give_log_user_in_on_register_callback( $value ) {
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1559
	return false;
1560
}
1561
1562
/**
1563
 * Import CSV in DB
1564
 *
1565
 * @param int $file_id CSV id
1566
 * @param array $mapto Map csv to meta key.
0 ignored issues
show
Bug introduced by
There is no parameter named $mapto. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1567
 * @param int $start Start from which csv line.
1568
 * @param int $end End from which csv line.
1569
 */
1570
function give_get_donation_data_from_csv( $file_id, $start, $end, $delimiter = ',' ) {
1571
	$raw_data = array();
1572
	$file_dir = get_attached_file( $file_id );
1573
	$count    = 0;
1574
	if ( false !== ( $handle = fopen( $file_dir, 'r' ) ) ) {
1575
		while ( false !== ( $row = fgetcsv( $handle, 0, $delimiter ) ) ) {
1576
			if ( $count >= $start && $count <= $end ) {
1577
				$raw_data[] = $row;
1578
			}
1579
			$count ++;
1580
		}
1581
		fclose( $handle );
1582
	}
1583
1584
	return $raw_data;
1585
}
1586
1587
1588
/**
1589
 * Return the option that are default options.
1590
 *
1591
 * @since 1.8.13
1592
 */
1593
function give_import_default_options() {
1594
	/**
1595
	 * Filter to modify defalut option in the import dropdown
1596
	 *
1597
	 * @since 1.8.13
1598
	 *
1599
	 * @return array
1600
	 */
1601
	return (array) apply_filters( 'give_import_default_options', array(
1602
		'' => __( 'Do not import', 'give' ),
1603
	) );
1604
}
1605
1606
/**
1607
 * Return the option that are related to donations.
1608
 *
1609
 * @since 1.8.13
1610
 */
1611
function give_import_donations_options() {
1612
	/**
1613
	 * Filter to modify donations option in the import dropdown
1614
	 *
1615
	 * @since 1.8.13
1616
	 *
1617
	 * @return array
1618
	 */
1619
	return (array) apply_filters( 'give_import_donations_options', array(
1620
		''            => __( 'Do not import', 'give' ),
1621
		'id'          => __( 'Donation ID', 'give' ),
1622
		'amount'      => __( 'Donation Amount', 'give' ),
1623
		'post_date'   => __( 'Donation Date', 'give' ),
1624
		'first_name'  => __( 'Donor First Name', 'give' ),
1625
		'last_name'   => __( 'Donor Last Name', 'give' ),
1626
		'line1'       => __( 'Address 1', 'give' ),
1627
		'line2'       => __( 'Address 2', 'give' ),
1628
		'city'        => __( 'City', 'give' ),
1629
		'state'       => __( 'State', 'give' ),
1630
		'country'     => __( 'Country', 'give' ),
1631
		'zip'         => __( 'Zip', 'give' ),
1632
		'email'       => __( 'Donor Email', 'give' ),
1633
		'post_status' => __( 'Donation Status', 'give' ),
1634
		'gateway'     => __( 'Payment Method', 'give' ),
1635
		'notes'       => __( 'Notes', 'give' ),
1636
		'mode'        => __( 'Test Mode', 'give' ),
1637
		'post_meta'   => __( 'Import as Meta', 'give' ),
1638
	) );
1639
}
1640
1641
/**
1642
 * Return the option that are related to donations.
1643
 *
1644
 * @since 1.8.13
1645
 */
1646
function give_import_donor_options() {
1647
	/**
1648
	 * Filter to modify donors option in the import dropdown
1649
	 *
1650
	 * @since 1.8.13
1651
	 *
1652
	 * @return array
1653
	 */
1654
	return (array) apply_filters( 'give_import_donor_options', array(
1655
		'donor_id' => __( 'Donor ID', 'give' ),
1656
		'user_id'  => __( 'User ID', 'give' ),
1657
	) );
1658
}
1659
1660
/**
1661
 * Return the option that are related to donations.
1662
 *
1663
 * @since 1.8.13
1664
 */
1665
function give_import_donation_form_options() {
1666
	/**
1667
	 * Filter to modify form option in the import dropdown
1668
	 *
1669
	 * @since 1.8.13
1670
	 *
1671
	 * @return array
1672
	 */
1673
	return (array) apply_filters( 'give_import_donation_form_options', array(
1674
		'form_id'    => __( 'Donation Form ID', 'give' ),
1675
		'form_title' => __( 'Donation Form', 'give' ),
1676
		'form_level' => __( 'Donation Level', 'give' ),
1677
		'form_custom_amount_text' => __( 'Custom Amount Text', 'give' ),
1678
	) );
1679
}
1680
1681
/**
1682
 * Give get user details.
1683
 *
1684
 * @since 1.8.13
1685
 *
1686
 * @param $data
1687
 *
1688
 * @return bool|false|WP_User
1689
 */
1690
function give_import_get_user_from_csv( $data, $import_setting = array() ) {
1691
	$report      = give_import_donation_report();
1692
	$donor_data  = false;
1693
	$customer_id = false;
0 ignored issues
show
Unused Code introduced by
$customer_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1694
1695
	// check if donor id is not empty
1696
	if ( ! empty( $data['donor_id'] ) ) {
1697
		$donor_data = new Give_Donor( (int) $data['donor_id'] );
0 ignored issues
show
Documentation introduced by
(int) $data['donor_id'] is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1698 View Code Duplication
		if ( ! empty( $donor_data->id ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1699
			$report['duplicate_donor'] = ( ! empty( $report['duplicate_donor'] ) ? ( absint( $report['duplicate_donor'] ) + 1 ) : 1 );
1700
		}
1701
	}
1702
1703
	if ( empty( $donor_data->id ) && ! empty( $data['user_id'] ) ) {
1704
		$user_id    = (int) $data['user_id'];
1705
		$donor_data = new Give_Donor( $user_id, true );
0 ignored issues
show
Documentation introduced by
$user_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1706
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1707
1708
		if ( empty( $donor_data->id ) ) {
1709
			$donor_data = get_user_by( 'id', $user_id );
1710
			if ( ! empty( $donor_data->ID ) ) {
1711
				$first_name = ( ! empty( $data['first_name'] ) ? $data['first_name'] : $donor_data->user_nicename );
1712
				$last_name  = ( ! empty( $data['last_name'] ) ? $data['last_name'] : ( ( $lastname = get_user_meta( $donor_data->ID, 'last_name', true ) ) ? $lastname : '' ) );
0 ignored issues
show
introduced by
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1713
				$name       = $first_name . ' ' . $last_name;
1714
				$user_email = $donor_data->user_email;
1715
				$donor_args = array(
1716
					'name'    => $name,
1717
					'email'   => $user_email,
1718
					'user_id' => $user_id,
1719
				);
1720
1721
				$donor_data = new Give_Donor();
1722
				$donor_data->create( $donor_args );
1723
1724
				// Adding notes that donor is being imported from CSV.
1725
				$current_user = wp_get_current_user();
1726
				$donor_data->add_note( esc_html( wp_sprintf( __( 'This donor was imported by %s', 'give' ), $current_user->user_email ) ) );
1727
1728
				// Add is used to ensure duplicate emails are not added
1729 View Code Duplication
				if ( $user_email != $data['email'] && ! empty( $data['email'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1730
					$donor_data->add_meta( 'additional_email', $data['email'] );
1731
				}
1732
1733
				$report['create_donor'] = ( ! empty( $report['create_donor'] ) ? ( absint( $report['create_donor'] ) + 1 ) : 1 );
1734
			} else {
1735
			}
1736
		} else {
1737
			// Add is used to ensure duplicate emails are not added
1738 View Code Duplication
			if ( $donor_data->email != $data['email'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1739
				$donor_data->add_meta( 'additional_email', ( ! empty( $data['email'] ) ? $data['email'] : $donor_data->email ) );
1740
			}
1741
			$report['duplicate_donor'] = ( ! empty( $report['duplicate_donor'] ) ? ( absint( $report['duplicate_donor'] ) + 1 ) : 1 );
1742
		}
1743
	}
1744
1745
	if ( empty( $donor_data->id ) && ! empty( $data['email'] ) ) {
1746
1747
		$donor_data = new Give_Donor( $data['email'] );
1748
		if ( empty( $donor_data->id ) ) {
1749
			$donor_data = get_user_by( 'email', $data['email'] );
1750
1751
			if ( empty( $donor_data->ID ) && ! empty( $data['first_name'] ) && ! empty( $data['last_name'] ) && isset( $import_setting['create_user'] ) && 1 === absint( $import_setting['create_user'] ) ) {
1752
				$give_role  = (array) give_get_option( 'donor_default_user_role', get_option( 'default_role', ( ( $give_donor = wp_roles()->is_role( 'give_donor' ) ) && ! empty( $give_donor ) ? 'give_donor' : 'subscriber' ) ) );
1753
				$donor_args = array(
1754
					'user_login'      => $data['email'],
1755
					'user_email'      => $data['email'],
1756
					'user_registered' => date( 'Y-m-d H:i:s' ),
1757
					'user_first'      => $data['first_name'],
1758
					'user_last'       => $data['last_name'],
1759
					'user_pass'       => wp_generate_password( 8, true ),
1760
					'role'            => $give_role,
1761
				);
1762
1763
				/**
1764
				 * Filter to modify user data before new user id register.
1765
				 *
1766
				 * @since 1.8.13
1767
				 */
1768
				$donor_args = (array) apply_filters( 'give_import_insert_user_args', $donor_args, $data, $import_setting );
1769
1770
				// This action was added to remove the login when using the give register function.
1771
				add_filter( 'give_log_user_in_on_register', 'give_log_user_in_on_register_callback', 11 );
1772
				$customer_id = give_register_and_login_new_user( $donor_args );
1773
				remove_filter( 'give_log_user_in_on_register', 'give_log_user_in_on_register_callback', 11 );
1774
1775
				update_user_meta( $customer_id, '_give_payment_import', true );
0 ignored issues
show
introduced by
update_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1776
				$donor_data = new Give_Donor( $customer_id, true );
0 ignored issues
show
Documentation introduced by
$customer_id is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1777
			} else {
1778
				$customer_id = ( ! empty( $donor_data->ID ) ? $donor_data->ID : false );
1779
			}
1780
1781
			if ( ! empty( $customer_id ) || ( isset( $import_setting['create_user'] ) && 0 === absint( $import_setting['create_user'] ) ) ) {
1782
				$donor_data = new Give_Donor( $customer_id, true );
1783
1784
				if ( empty( $donor_data->id ) ) {
1785
1786
					if ( ! empty( $data['form_id'] ) ) {
1787
						$form = new Give_Donate_Form( $data['form_id'] );
1788
					}
1789
1790
					$payment_title = ( isset( $data['form_title'] ) ? $data['form_title'] : ( isset( $form ) ? $form->get_name() : esc_html__( 'New Form', 'give' ) ) );
1791
					$donor_args    = array(
1792
						'name'  => ! is_email( $payment_title ) ? $data['first_name'] . ' ' . $data['last_name'] : '',
1793
						'email' => $data['email'],
1794
					);
1795
1796
					if ( ! empty( $customer_id ) ) {
1797
						$donor_args['user_id'] = $customer_id;
1798
					}
1799
1800
					$donor_data->create( $donor_args );
1801
1802
					// Adding notes that donor is being imported from CSV.
1803
					$current_user = wp_get_current_user();
1804
					$donor_data->add_note( esc_html( wp_sprintf( __( 'This donor was imported by %s', 'give' ), $current_user->user_email ) ) );
1805
1806
					$report['create_donor'] = ( ! empty( $report['create_donor'] ) ? ( absint( $report['create_donor'] ) + 1 ) : 1 );
1807 View Code Duplication
				} else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1808
					$report['duplicate_donor'] = ( ! empty( $report['duplicate_donor'] ) ? ( absint( $report['duplicate_donor'] ) + 1 ) : 1 );
1809
				}
1810
			}
1811 View Code Duplication
		} else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1812
			$report['duplicate_donor'] = ( ! empty( $report['duplicate_donor'] ) ? ( absint( $report['duplicate_donor'] ) + 1 ) : 1 );
1813
		}
1814
	}
1815
1816
// update the report
1817
	give_import_donation_report_update( $report );
1818
1819
	return $donor_data;
1820
}
1821
1822
/**
1823
 * Give get form data from csv if not then create and form and return the form value.
1824
 *
1825
 * @since 1.8.13.
1826
 *
1827
 * @param $data .
1828
 *
1829
 * @return array|bool|Give_Donate_Form|int|null|WP_Post
1830
 */
1831
function give_import_get_form_data_from_csv( $data, $import_setting = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $import_setting is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1832
	$new_form = false;
1833
1834
	// Get the import report
1835
	$report = give_import_donation_report();
1836
1837
	$form = false;
1838
	$meta = array();
1839
1840
	if ( ! empty( $data['form_id'] ) ) {
1841
		$form = new Give_Donate_Form( $data['form_id'] );
1842
		// Add support to older php version.
1843
		$form_id = $form->get_ID();
1844 View Code Duplication
		if ( empty( $form_id ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1845
			$report['duplicate_form'] = ( ! empty( $report['duplicate_form'] ) ? ( absint( $report['duplicate_form'] ) + 1 ) : 1 );
1846
			$form = false;
1847
		}
1848
	}
1849
1850
	if ( false === $form && ! empty( $data['form_title'] ) ) {
1851
		$form = get_page_by_title( $data['form_title'], OBJECT, 'give_forms' );
1852
1853
		if ( ! empty( $form->ID ) ) {
1854
1855
			$report['duplicate_form'] = ( ! empty( $report['duplicate_form'] ) ? ( absint( $report['duplicate_form'] ) + 1 ) : 1 );
1856
1857
			$form = new Give_Donate_Form( $form->ID );
0 ignored issues
show
Unused Code introduced by
$form is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1858
		} else {
1859
			$form                  = new Give_Donate_Form();
1860
			$args                  = array(
1861
				'post_title'  => $data['form_title'],
1862
				'post_status' => 'publish',
1863
			);
1864
			$form                  = $form->create( $args );
0 ignored issues
show
Unused Code introduced by
$form is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1865
			$report['create_form'] = ( ! empty( $report['create_form'] ) ? ( absint( $report['create_form'] ) + 1 ) : 1 );
1866
			$new_form              = true;
1867
1868
		}
1869
1870
		$form = get_page_by_title( $data['form_title'], OBJECT, 'give_forms' );
1871
		$form = new Give_Donate_Form( $form->ID );
1872
	}
1873
1874
	if ( ! empty( $form ) && $form->get_ID() ) {
1875
		if ( ! empty( $data['form_level'] ) && 'custom' != (string) strtolower( $data['form_level'] ) ) {
1876
			$prices     = (array) $form->get_prices();
1877
			$price_text = array();
1878 View Code Duplication
			foreach ( $prices as $key => $price ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1879
				if ( isset( $price['_give_id']['level_id'] ) ) {
1880
					$price_text[ $price['_give_id']['level_id'] ] = ( ! empty( $price['_give_text'] ) ? $price['_give_text'] : '' );
1881
				}
1882
			}
1883
1884
			if ( ! in_array( $data['form_level'], $price_text ) ) {
1885
1886
				// For generating unquiet level id.
1887
				$count     = 1;
1888
				$new_level = count( $prices ) + $count;
1889
				while ( array_key_exists( $new_level, $price_text ) ) {
1890
					$count ++;
1891
					$new_level = count( $prices ) + $count;
1892
				}
1893
1894
				$multi_level_donations = array(
1895
					array(
1896
						'_give_id'      => array(
1897
							'level_id' => $new_level,
1898
						),
1899
						'_give_amount'  => give_sanitize_amount_for_db( $data['amount'] ),
1900
						'_give_text'    => $data['form_level'],
1901
					),
1902
				);
1903
1904
				$price_text[ $new_level ] = $data['form_level'];
1905
1906
				if ( ! empty( $prices ) && is_array( $prices ) && ! empty( $prices[0] ) ) {
1907
					$prices = wp_parse_args( $multi_level_donations, $prices );
1908
				} else {
1909
					$multi_level_donations[0]['_give_default'] = 'default';
1910
					$prices = $multi_level_donations;
1911
				}
1912
			}
1913
			$form->price_id = array_search( $data['form_level'], $price_text );
1914
1915
			$donation_levels_amounts = wp_list_pluck( $prices, '_give_amount' );
1916
			$min_amount              = min( $donation_levels_amounts );
1917
			$max_amount              = max( $donation_levels_amounts );
1918
1919
			$meta = array(
1920
				'_give_levels_minimum_amount' => $min_amount,
1921
				'_give_levels_maximum_amount' => $max_amount,
1922
				'_give_price_option'          => 'multi',
1923
				'_give_donation_levels'       => array_values( $prices ),
1924
			);
1925
		} else {
1926
			$form->price_id = 'custom';
1927
		}
1928
1929
		$defaults = array(
1930
			'_give_set_price'    => give_sanitize_amount_for_db( $data['amount'] ),
1931
			'_give_price_option' => 'set',
1932
		);
1933
1934
		// If new form is created.
1935
		if ( ! empty( $new_form ) ) {
1936
			$new_form = array(
1937
				'_give_custom_amount_text' => ( ! empty( $data['form_custom_amount_text'] ) ? $data['form_custom_amount_text'] : 'Custom' ),
1938
				'_give_logged_in_only'     => 'enabled',
1939
				'_give_custom_amount'      => 'enabled',
1940
				'_give_payment_import'     => true,
1941
				'_give_display_style'      => 'radios',
1942
				'_give_payment_display'    => 'onpage',
1943
				'give_product_notes'       => 'Donation Notes',
1944
				'_give_product_type'       => 'default',
1945
				'_give_default_gateway'    => 'global',
1946
				'_give_show_register_form' => 'both',
1947
			);
1948
			$defaults = wp_parse_args( $defaults, $new_form );
1949
		}
1950
1951
		$meta = wp_parse_args( $meta, $defaults );
1952
1953
		foreach ( $meta as $key => $value ) {
1954
			give_update_meta( $form->get_ID(), $key, $value );
1955
		}
1956
	}
1957
1958
	// update the report
1959
	give_import_donation_report_update( $report );
1960
1961
	return $form;
1962
}
1963
1964
/**
1965
 * Remove the Give transaction pages from WP search results.
1966
 *
1967
 * @since 1.8.13
1968
 *
1969
 * @param \WP_Query
1970
 *
1971
 */
1972
function give_remove_pages_from_search( $query ) {
1973
	if ( ! $query->is_admin && $query->is_search && $query->is_main_query() ) {
1974
		$transaction_failed = give_get_option( 'failure_page', 0 );
1975
		$success_page       = give_get_option( 'success_page', 0 );
1976
		$args               = apply_filters( 'give_remove_pages_from_search', array(
1977
			$transaction_failed,
1978
			$success_page
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
1979
		), $query );
1980
		$query->set( 'post__not_in', $args );
1981
	}
1982
}
1983
1984
add_action( 'pre_get_posts', 'give_remove_pages_from_search', 10, 1 );
1985
1986
/**
1987
 * Inserts a new key/value before a key in the array.
1988
 *
1989
 * @since 1.8.13
1990
 *
1991
 * @param string $key The key to insert before.
1992
 * @param array $array An array to insert in to.
1993
 * @param string $new_key The key to insert.
1994
 * @param array|string $new_value An value to insert.
1995
 *
1996
 * @return array The new array if the key exists, the passed array otherwise.
1997
 *
1998
 * @see   array_insert_before()
1999
 */
2000 View Code Duplication
function give_array_insert_before( $key, array &$array, $new_key, $new_value ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2001
	if ( array_key_exists( $key, $array ) ) {
2002
		$new = array();
2003
		foreach ( $array as $k => $value ) {
2004
			if ( $k === $key ) {
2005
				$new[ $new_key ] = $new_value;
2006
			}
2007
			$new[ $k ] = $value;
2008
		}
2009
2010
		return $new;
2011
	}
2012
2013
	return $array;
2014
}
2015
2016
/**
2017
 * Inserts a new key/value after a key in the array.
2018
 *
2019
 * @since 1.8.13
2020
 *
2021
 * @param string $key The key to insert after.
2022
 * @param array $array An array to insert in to.
2023
 * @param string $new_key The key to insert.
2024
 * @param array|string $new_value An value to insert.
2025
 *
2026
 * @return array The new array if the key exists, the passed array otherwise.
2027
 *
2028
 * @see   array_insert_before()
2029
 */
2030 View Code Duplication
function give_array_insert_after( $key, array &$array, $new_key, $new_value ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2031
	if ( array_key_exists( $key, $array ) ) {
2032
		$new = array();
2033
		foreach ( $array as $k => $value ) {
2034
			$new[ $k ] = $value;
2035
			if ( $k === $key ) {
2036
				$new[ $new_key ] = $new_value;
2037
			}
2038
		}
2039
2040
		return $new;
2041
	}
2042
2043
	return $array;
2044
}
2045
2046
/**
2047
 * Pluck a certain field out of each object in a list.
2048
 *
2049
 * This has the same functionality and prototype of
2050
 * array_column() (PHP 5.5) but also supports objects.
2051
 *
2052
 * @since 1.8.13
2053
 *
2054
 * @param array $list List of objects or arrays
2055
 * @param int|string $field Field from the object to place instead of the entire object
2056
 * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
2057
 *                              Default null.
2058
 *
2059
 * @return array Array of found values. If `$index_key` is set, an array of found values with keys
2060
 *               corresponding to `$index_key`. If `$index_key` is null, array keys from the original
2061
 *               `$list` will be preserved in the results.
2062
 */
2063
function give_list_pluck( $list, $field, $index_key = null ) {
2064
2065
	if ( ! $index_key ) {
2066
		/*
2067
		 * This is simple. Could at some point wrap array_column()
2068
		 * if we knew we had an array of arrays.
2069
		 */
2070
		foreach ( $list as $key => $value ) {
2071
			if ( is_object( $value ) ) {
2072
				if ( isset( $value->$field ) ) {
2073
					$list[ $key ] = $value->$field;
2074
				}
2075
			} else {
2076
				if ( isset( $value[ $field ] ) ) {
2077
					$list[ $key ] = $value[ $field ];
2078
				}
2079
			}
2080
		}
2081
2082
		return $list;
2083
	}
2084
2085
	/*
2086
	 * When index_key is not set for a particular item, push the value
2087
	 * to the end of the stack. This is how array_column() behaves.
2088
	 */
2089
	$newlist = array();
2090
	foreach ( $list as $value ) {
2091
		if ( is_object( $value ) ) {
2092
			if ( isset( $value->$index_key ) ) {
2093
				$newlist[ $value->$index_key ] = $value->$field;
2094
			} else {
2095
				$newlist[] = $value->$field;
2096
			}
2097
		} else {
2098
			if ( isset( $value[ $index_key ] ) ) {
2099
				$newlist[ $value[ $index_key ] ] = $value[ $field ];
2100
			} else {
2101
				$newlist[] = $value[ $field ];
2102
			}
2103
		}
2104
	}
2105
2106
	$list = $newlist;
2107
2108
	return $list;
2109
}
2110
2111
/**
2112
 * Get the Import report of the donations
2113
 *
2114
 * @since 1.8.13
2115
 */
2116
function give_import_donation_report() {
2117
	return get_option( 'give_import_donation_report', array() );
2118
}
2119
2120
2121
/**
2122
 * Update the Import report of the donations
2123
 *
2124
 * @since 1.8.13
2125
 */
2126
function give_import_donation_report_update( $value = array() ) {
2127
	update_option( 'give_import_donation_report', $value );
2128
}
2129
2130
2131
/**
2132
 * Delete the Import report of the donations
2133
 *
2134
 * @since 1.8.13
2135
 */
2136
function give_import_donation_report_reset() {
2137
	update_option( 'give_import_donation_report', array() );
2138
}
2139
2140
2141
/**
2142
 * Add meta data field to a donor.
2143
 *
2144
 * @since 1.8.13
2145
 *
2146
 * @param int $donor_id Donor ID.
2147
 * @param string $meta_key Metadata name.
2148
 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
2149
 * @param bool $unique Optional. Whether the same key should not be added.
2150
 *                           Default false.
2151
 *
2152
 * @return int|false Meta ID on success, false on failure.
2153
 */
2154
function add_donor_meta( $donor_id, $meta_key, $meta_value, $unique = false ) {
2155
	return add_metadata( 'give_customer', $donor_id, $meta_key, $meta_value, $unique );
2156
}
2157
2158
/**
2159
 * Remove metadata matching criteria from a Donor meta.
2160
 *
2161
 * You can match based on the key, or key and value. Removing based on key and
2162
 * value, will keep from removing duplicate metadata with the same key. It also
2163
 * allows removing all metadata matching key, if needed.
2164
 *
2165
 * @since 1.8.13
2166
 *
2167
 * @param int $donor_id Donor ID
2168
 * @param string $meta_key Metadata name.
2169
 * @param mixed $meta_value Optional. Metadata value.
2170
 *
2171
 * @return bool True on success, false on failure.
2172
 */
2173
function delete_donor_meta( $donor_id, $meta_key, $meta_value = '' ) {
2174
	return delete_metadata( 'give_customer', $donor_id, $meta_key, $meta_value );
2175
}
2176
2177
/**
2178
 * Retrieve donor meta field for a donor meta table.
2179
 *
2180
 * @since 1.8.13
2181
 *
2182
 * @param int $donor_id Donor ID.
2183
 * @param string $key Optional. The meta key to retrieve. By default, returns data for all keys.
2184
 * @param bool $single Whether to return a single value.
2185
 *
2186
 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
2187
 *  is true.
2188
 */
2189
function get_donor_meta( $donor_id, $key = '', $single = false ) {
2190
	return get_metadata( 'give_customer', $donor_id, $key, $single );
2191
}
2192
2193
/**
2194
 * Update customer meta field based on Donor ID.
2195
 *
2196
 * If the meta field for the donor does not exist, it will be added.
2197
 *
2198
 * @since 1.8.13
2199
 *
2200
 * @param int $donor_id Donor ID.
2201
 * @param string $meta_key Metadata key.
2202
 * @param mixed $meta_value Metadata value.
2203
 * @param mixed $prev_value Optional. Previous value to check before removing.
2204
 *
2205
 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
2206
 */
2207
function update_donor_meta( $donor_id, $meta_key, $meta_value, $prev_value = '' ) {
2208
	return update_metadata( 'give_customer', $donor_id, $meta_key, $meta_value, $prev_value );
2209
}
2210
2211
/*
2212
 * Give recalculate income and donation of the donation from ID
2213
 *
2214
 * @since 1.8.13
2215
 *
2216
 * @param int $form_id Form id of which recalculation needs to be done.
2217
 */
2218
function give_recount_form_income_donation( $form_id = false ) {
2219
	// Check if form id is not empty.
2220
	if ( ! empty( $form_id ) ) {
2221
		/**
2222
		 * Filter to modify payment status.
2223
		 *
2224
		 * @since 1.8.13
2225
		 */
2226
		$accepted_statuses = apply_filters( 'give_recount_accepted_statuses', array( 'publish' ) );
2227
2228
		/**
2229
		 * Filter to modify args of payment query before recalculating the form total
2230
		 *
2231
		 * @since 1.8.13
2232
		 */
2233
		$args = apply_filters( 'give_recount_form_stats_args', array(
2234
			'give_forms'     => $form_id,
2235
			'status'         => $accepted_statuses,
2236
			'posts_per_page' => - 1,
2237
			'fields'         => 'ids',
2238
		) );
2239
2240
		$totals = array(
2241
			'sales'    => 0,
2242
			'earnings' => 0,
2243
		);
2244
2245
		$payments = new Give_Payments_Query( $args );
2246
		$payments = $payments->get_payments();
2247
2248
		if ( $payments ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
2249 View Code Duplication
			foreach ( $payments as $payment ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2250
				//Ensure acceptible status only
2251
				if ( ! in_array( $payment->post_status, $accepted_statuses ) ) {
2252
					continue;
2253
				}
2254
2255
				//Ensure only payments for this form are counted
2256
				if ( $payment->form_id != $form_id ) {
2257
					continue;
2258
				}
2259
2260
				$totals['sales'] ++;
2261
				$totals['earnings'] += $payment->total;
2262
2263
			}
2264
		}
2265
		give_update_meta( $form_id, '_give_form_sales', $totals['sales'] );
2266
		give_update_meta( $form_id, '_give_form_earnings', give_sanitize_amount_for_db( $totals['earnings'] ) );
2267
	}
2268
}
2269
2270
/**
2271
 * Zero Decimal based Currency.
2272
 *
2273
 * @since 1.8.14
2274
 *
2275
 * @return bool
2276
 */
2277
function give_is_zero_based_currency() {
2278
	$zero_based_currency = array(
2279
		'PYG', // Paraguayan Guarani.
2280
		'GNF', // Guinean Franc.
2281
		'RWF', // Rwandan Franc.
2282
		'JPY', // Japanese Yen.
2283
		'BIF', // Burundian Franc.
2284
		'KRW', // South Korean Won.
2285
		'MGA', // Malagasy Ariary.
2286
		'XAF', // Central African Cfa Franc.
2287
		'XPF', // Cfp Franc.
2288
		'CLP', // Chilean Peso.
2289
		'KMF', // Comorian Franc.
2290
		'DJF', // Djiboutian Franc.
2291
		'VUV', // Vanuatu Vatu.
2292
		'VND', // Vietnamese Dong.
2293
		'XOF', // West African Cfa Franc.
2294
	);
2295
2296
	// Check for Zero Based Currency.
2297
	if ( in_array( give_get_currency(), $zero_based_currency ) ) {
2298
		return true;
2299
	}
2300
2301
	return false;
2302
}