Test Failed
Push — master ( cdfd8f...fbfe2a )
by Ravinder
06:35
created

misc-functions.php ➔ give_get_safe_asset_url()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 13
ccs 0
cts 0
cp 0
crap 6
rs 9.8333
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 current page URL.
34
 *
35
 * @since 1.0
36
 * @return string $current_url Current page URL.
37
 */
38
function give_get_current_page_url() {
39 55
40 55
	global $wp;
41
42 55
	if ( get_option( 'permalink_structure' ) ) {
43
		$base = trailingslashit( home_url( $wp->request ) );
44
	} else {
45
		$base = add_query_arg( $wp->query_string, '', trailingslashit( home_url( $wp->request ) ) );
46
		$base = remove_query_arg( array( 'post_type', 'name' ), $base );
47
	}
48
49
	$scheme      = is_ssl() ? 'https' : 'http';
50
	$current_uri = set_url_scheme( $base, $scheme );
51
52
	if ( is_front_page() ) {
53 1
		$current_uri = home_url( '/' );
54 1
	}
55
56 1
	/**
57
	 * Filter the current page url
58
	 *
59
	 * @since 1.0
60
	 *
61
	 * @param string $current_uri
62
	 */
63
	return apply_filters( 'give_get_current_page_url', $current_uri );
64
65
}
66
67
68
/**
69
 * Verify credit card numbers live?
70
 *
71
 * @since 1.0
72
 *
73
 * @return bool $ret True is verify credit cards is live
74
 */
75
function give_is_cc_verify_enabled() {
76
77
	$ret = true;
78
79
	/**
80
	 * Enable if use a single gateway other than PayPal or Manual. We have to assume it accepts credit cards.
81
	 * Enable if using more than one gateway if they are not both PayPal and manual, again assuming credit card usage.
82
	 */
83
	$gateways = give_get_enabled_payment_gateways();
84
85
	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...
86
		$ret = true;
87
	} elseif ( count( $gateways ) == 1 ) {
0 ignored issues
show
introduced by
Found "== 1". Use Yoda Condition checks, you must
Loading history...
88
		$ret = false;
89
	} 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...
90
		$ret = false;
91
	}
92
93
	/**
94
	 * Fire the filter
95
	 *
96
	 * @since 1.0
97
	 *
98
	 * @param bool $ret
99
	 */
100
	return (bool) apply_filters( 'give_is_cc_verify_enabled', $ret );
101
}
102
103
/**
104
 * Retrieve timezone.
105
 *
106
 * @since 1.0
107
 * @return string $timezone The timezone ID.
108
 */
109
function give_get_timezone_id() {
110
111
	// if site timezone string exists, return it.
112
	if ( $timezone = get_option( 'timezone_string' ) ) {
113
		return $timezone;
114
	}
115
116
	// get UTC offset, if it isn't set return UTC.
117
	if ( ! ( $utc_offset = 3600 * get_option( 'gmt_offset', 0 ) ) ) {
118 45
		return 'UTC';
119
	}
120
121
	// attempt to guess the timezone string from the UTC offset.
122 45
	$timezone = timezone_name_from_abbr( '', $utc_offset );
123
124
	// last try, guess timezone string manually.
125 45
	if ( $timezone === false ) {
0 ignored issues
show
introduced by
Found "=== false". Use Yoda Condition checks, you must
Loading history...
126
127
		$is_dst = date( 'I' );
128 45
129
		foreach ( timezone_abbreviations_list() as $abbr ) {
130
			foreach ( $abbr as $city ) {
131 45
				if ( $city['dst'] == $is_dst && $city['offset'] == $utc_offset ) {
132
					return $city['timezone_id'];
133
				}
134 45
			}
135
		}
136
	}
137 45
138 45
	// Fallback.
139 45
	return 'UTC';
140 45
}
141 45
142 45
143 45
/**
144 45
 * Get User IP
145
 *
146
 * Returns the IP address of the current visitor
147
 *
148
 * @since 1.0
149
 * @return string $ip User's IP address
150
 */
151
function give_get_ip() {
152
153
	$ip = '127.0.0.1';
154
155
	if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
156
		// check ip from share internet
157
		$ip = $_SERVER['HTTP_CLIENT_IP'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
158
	} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
159
		// to check ip is pass from proxy
160
		$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
161
	} 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...
162
		$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...
163
	}
164
165
	/**
166
	 * Filter the IP
167
	 *
168
	 * @since 1.0
169
	 */
170
	$ip = apply_filters( 'give_get_ip', $ip );
171
172
	// Filter empty values.
173
	if ( false !== strpos( $ip, ',' ) ) {
174
		$ip = give_clean( explode( ',', $ip ) );
175
		$ip = array_filter( $ip );
176
		$ip = implode( ',', $ip );
177
	} else {
178
		$ip = give_clean( $ip );
179
	}
180
181
	return $ip;
182
}
183
184
185
/**
186
 * Store Donation Data in Sessions
187
 *
188
 * Used for storing info about donation
189
 *
190
 * @since 1.0
191
 *
192
 * @param $purchase_data
193
 *
194
 * @uses  Give()->session->set()
195
 */
196
function give_set_purchase_session( $purchase_data = array() ) {
197
	Give()->session->set( 'give_purchase', $purchase_data );
198
	Give()->session->set( 'give_email', $purchase_data['user_email'] );
199
}
200 45
201
/**
202
 * Retrieve Donation Data from Session
203
 *
204
 * Used for retrieving info about donation
205
 * after completing a donation
206
 *
207
 * @since 1.0
208
 * @uses  Give()->session->get()
209
 * @return mixed array | false
210
 */
211
function give_get_purchase_session() {
212 6
	return Give()->session->get( 'give_purchase' );
213
}
214
215 6
/**
216
 * Retrieve Payment Key of the Receipt Access Session.
217
 *
218 6
 * @since 1.8.17
219
 *
220
 * @return array|string
221
 */
222
function give_get_receipt_session() {
223
	return Give()->session->get( 'receipt_access' );
224
}
225
226
/**
227
 * Retrieve Payment Key of the History Access Session.
228
 *
229
 * @since 1.8.17
230
 *
231
 * @return array|string
232
 */
233
function give_get_history_session() {
234
	return (bool) Give()->session->get( 'history_access' );
235
}
236
237
/**
238
 * Generate Item Title for Payment Gateway.
239
 *
240
 * @param array $payment_data Payment Data.
241
 *
242
 * @since 1.8.14
243
 *
244
 * @return string By default, the name of the form. Then the price level text if any is found.
245
 */
246
function give_payment_gateway_item_title( $payment_data ) {
247
248
	$form_id   = intval( $payment_data['post_data']['give-form-id'] );
249
	$item_name = isset( $payment_data['post_data']['give-form-title'] ) ? $payment_data['post_data']['give-form-title'] : '';
250
	$price_id  = isset( $payment_data['post_data']['give-price-id'] ) ? $payment_data['post_data']['give-price-id'] : '';
251
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
252
253
	// Verify has variable prices.
254
	if ( give_has_variable_prices( $form_id ) && ! empty( $price_id ) ) {
255
256
		$item_price_level_text = give_get_price_option_name( $form_id, $price_id, 0, false );
257
258
		/**
259
		 * Output donation level text if:
260
		 *
261
		 * 1. It's not a custom amount
262
		 * 2. The level field has actual text and isn't the amount (which is already displayed on the receipt).
263
		 */
264
		if ( 'custom' !== $price_id && ! empty( $item_price_level_text ) ) {
265
			// Matches a donation level - append level text.
266
			$item_name .= ' - ' . $item_price_level_text;
267
		}
268
	}
269
270
	/**
271
	 * Filter the Item Title of Payment Gateway.
272
	 *
273
	 * @param string $item_name    Item Title of Payment Gateway.
274
	 * @param int    $form_id      Donation Form ID.
275
	 * @param array  $payment_data Payment Data.
276
	 *
277
	 * @since 1.8.14
278
	 *
279
	 * @return string
280
	 */
281
	return apply_filters( 'give_payment_gateway_item_title', $item_name, $form_id, $payment_data );
282
}
283
284
/**
285
 * Get Donation Summary
286
 *
287
 * Creates a donation summary for payment gateways from the donation data before the payment is created in the database.
288
 *
289
 * @since       1.8.12
290
 *
291
 * @param array $donation_data
292
 * @param bool  $name_and_email
293
 * @param int   $length
294
 *
295
 * @return string
296
 */
297
function give_payment_gateway_donation_summary( $donation_data, $name_and_email = true, $length = 255 ) {
298
299
	$form_id  = isset( $donation_data['post_data']['give-form-id'] ) ? $donation_data['post_data']['give-form-id'] : '';
300 52
	$price_id = isset( $donation_data['post_data']['give-price-id'] ) ? $donation_data['post_data']['give-price-id'] : '';
301
302 52
	// Form title.
303
	$summary = ( ! empty( $donation_data['post_data']['give-form-title'] ) ? $donation_data['post_data']['give-form-title'] : ( ! empty( $form_id ) ? wp_sprintf( __( 'Donation Form ID: %d', 'give' ), $form_id ) : __( 'Untitled donation form', 'give' ) ) );
304
305 52
	// Form multilevel if applicable.
306
	if ( ! empty( $price_id ) && 'custom' !== $price_id ) {
307
		$summary .= ': ' . give_get_price_option_name( $form_id, $donation_data['post_data']['give-price-id'] );
308 52
	}
309 52
310 52
	// Add Donor's name + email if requested.
311
	if ( $name_and_email ) {
312 52
313
		// First name
314 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...
315
			$summary .= ' - ' . $donation_data['user_info']['first_name'];
316
		}
317
318 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...
319
			$summary .= ' ' . $donation_data['user_info']['last_name'];
320
		}
321
322
		$summary .= ' (' . $donation_data['user_email'] . ')';
323
	}
324
325
	// Cut the length
326
	$summary = substr( $summary, 0, $length );
327
328
	return apply_filters( 'give_payment_gateway_donation_summary', $summary );
329
}
330
331
332
/**
333
 * Get user host
334
 *
335
 * Returns the webhost this site is using if possible
336
 *
337
 * @since 1.0
338
 * @return string $host if detected, false otherwise
339
 */
340
function give_get_host() {
341
	$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...
342
343
	if ( defined( 'WPE_APIKEY' ) ) {
344
		$host = 'WP Engine';
345
	} elseif ( defined( 'PAGELYBIN' ) ) {
346
		$host = 'Pagely';
347
	} elseif ( DB_HOST == 'localhost:/tmp/mysql5.sock' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
348
		$host = 'ICDSoft';
349
	} elseif ( DB_HOST == 'mysqlv5' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
350
		$host = 'NetworkSolutions';
351
	} elseif ( strpos( DB_HOST, 'ipagemysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
352
		$host = 'iPage';
353
	} elseif ( strpos( DB_HOST, 'ipowermysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
354
		$host = 'IPower';
355
	} elseif ( strpos( DB_HOST, '.gridserver.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
356
		$host = 'MediaTemple Grid';
357
	} elseif ( strpos( DB_HOST, '.pair.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
358
		$host = 'pair Networks';
359
	} elseif ( strpos( DB_HOST, '.stabletransit.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
360
		$host = 'Rackspace Cloud';
361
	} elseif ( strpos( DB_HOST, '.sysfix.eu' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
362
		$host = 'SysFix.eu Power Hosting';
363
	} elseif ( strpos( $_SERVER['SERVER_NAME'], 'Flywheel' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
364
		$host = 'Flywheel';
365
	} else {
366
		// Adding a general fallback for data gathering
367
		$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...
368
	}
369
370
	return $host;
371
}
372
373
374
/**
375
 * Check site host
376
 *
377
 * @since 1.0
378
 *
379
 * @param bool /string $host The host to check
380
 *
381
 * @return bool true if host matches, false if not
382
 */
383
function give_is_host( $host = false ) {
384
385
	$return = false;
386
387
	if ( $host ) {
388
		$host = str_replace( ' ', '', strtolower( $host ) );
389
390
		switch ( $host ) {
391
			case 'wpengine':
392
				if ( defined( 'WPE_APIKEY' ) ) {
393
					$return = true;
394
				}
395
				break;
396
			case 'pagely':
397
				if ( defined( 'PAGELYBIN' ) ) {
398
					$return = true;
399
				}
400
				break;
401
			case 'icdsoft':
402
				if ( DB_HOST == 'localhost:/tmp/mysql5.sock' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
403
					$return = true;
404
				}
405
				break;
406
			case 'networksolutions':
407
				if ( DB_HOST == 'mysqlv5' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
408
					$return = true;
409
				}
410
				break;
411
			case 'ipage':
412
				if ( strpos( DB_HOST, 'ipagemysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
413
					$return = true;
414
				}
415
				break;
416
			case 'ipower':
417
				if ( strpos( DB_HOST, 'ipowermysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
418
					$return = true;
419
				}
420
				break;
421
			case 'mediatemplegrid':
422
				if ( strpos( DB_HOST, '.gridserver.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
423
					$return = true;
424
				}
425
				break;
426
			case 'pairnetworks':
427
				if ( strpos( DB_HOST, '.pair.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
428
					$return = true;
429
				}
430
				break;
431
			case 'rackspacecloud':
432
				if ( strpos( DB_HOST, '.stabletransit.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
433
					$return = true;
434
				}
435
				break;
436
			case 'sysfix.eu':
437
			case 'sysfix.eupowerhosting':
438
				if ( strpos( DB_HOST, '.sysfix.eu' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
439
					$return = true;
440
				}
441
				break;
442
			case 'flywheel':
443
				if ( strpos( $_SERVER['SERVER_NAME'], 'Flywheel' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
444
					$return = true;
445
				}
446
				break;
447
			default:
448
				$return = false;
449
		}// End switch().
450
	}// End if().
451
452
	return $return;
453
}
454
455
/**
456
 * Marks a function as deprecated and informs when it has been used.
457
 *
458
 * There is a hook give_deprecated_function_run that will be called that can be used
459
 * to get the backtrace up to what file and function called the deprecated
460
 * function.
461
 *
462
 * The current behavior is to trigger a user error if WP_DEBUG is true.
463
 *
464
 * This function is to be used in every function that is deprecated.
465
 *
466
 * @uses do_action() Calls 'give_deprecated_function_run' and passes the function name, what to use instead,
467
 *   and the version the function was deprecated in.
468
 * @uses apply_filters() Calls 'give_deprecated_function_trigger_error' and expects boolean value of true to do
469
 *   trigger or false to not trigger error.
470
 *
471
 * @param string $function    The function that was called.
472
 * @param string $version     The plugin version that deprecated the function.
473
 * @param string $replacement Optional. The function that should have been called.
474
 * @param array  $backtrace   Optional. Contains stack backtrace of deprecated function.
475
 */
476
function _give_deprecated_function( $function, $version, $replacement = null, $backtrace = null ) {
477
478
	/**
479
	 * Fires while give deprecated function call occurs.
480
	 *
481
	 * Allow you to hook to deprecated function call.
482
	 *
483
	 * @since 1.0
484
	 *
485
	 * @param string $function    The function that was called.
486
	 * @param string $replacement Optional. The function that should have been called.
487
	 * @param string $version     The plugin version that deprecated the function.
488
	 */
489
	do_action( 'give_deprecated_function_run', $function, $replacement, $version );
490
491
	$show_errors = current_user_can( 'manage_options' );
492
493
	// Allow plugin to filter the output error trigger.
494
	if ( WP_DEBUG && apply_filters( 'give_deprecated_function_trigger_error', $show_errors ) ) {
495
		if ( ! is_null( $replacement ) ) {
496
			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Give version %2$s! Use %3$s instead.', 'give' ), $function, $version, $replacement ) );
497
			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...
498
			// Alternatively we could dump this to a file.
499
		} else {
500
			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Give version %2$s with no alternative available.', 'give' ), $function, $version ) );
501
			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...
502
			// Alternatively we could dump this to a file.
503
		}
504
	}
505
}
506
507
/**
508
 * Give Get Admin ID
509
 *
510
 * Helper function to return the ID of the post for admin usage
511
 *
512
 * @return string $post_id
513
 */
514
function give_get_admin_post_id() {
515
	$post_id = isset( $_REQUEST['post'] ) ? absint( $_REQUEST['post'] ) : null;
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
516 1
517
	$post_id = ! empty( $post_id ) ? $post_id : ( isset( $_REQUEST['post_id'] ) ? absint( $_REQUEST['post_id'] ) : null );
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
518 1
519
	$post_id = ! empty( $post_id ) ? $post_id : ( isset( $_REQUEST['post_ID'] ) ? absint( $_REQUEST['post_ID'] ) : null );
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
520
521 1
	return $post_id;
522
}
523
524
/**
525
 * Get PHP Arg Separator Output
526
 *
527
 * @since 1.0
528
 * @return string Arg separator output
529
 */
530
function give_get_php_arg_separator_output() {
531
	return ini_get( 'arg_separator.output' );
532 1
}
533
534
535
/**
536
 * Month Num To Name
537
 *
538
 * Takes a month number and returns the name three letter name of it.
539
 *
540
 * @since 1.0
541
 *
542
 * @param int $n
543
 *
544
 * @return string Short month name
545
 */
546
function give_month_num_to_name( $n ) {
547
	$timestamp = mktime( 0, 0, 0, $n, 1, 2005 );
548
549
	return date_i18n( 'M', $timestamp );
550
}
551
552
553
/**
554
 * Checks whether function is disabled.
555
 *
556
 * @since 1.0
557
 *
558
 * @param string $function Name of the function.
559
 *
560
 * @return bool Whether or not function is disabled.
561
 */
562
function give_is_func_disabled( $function ) {
563
	$disabled = explode( ',', ini_get( 'disable_functions' ) );
564
565
	return in_array( $function, $disabled );
566
}
567
568
/**
569
 * Give Newsletter
570
 *
571
 * Returns the main Give newsletter form
572
 */
573
function give_get_newsletter() {
574
	?>
575
576
	<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>
577
578
	<div class="give-newsletter-form-wrap">
579
580
		<form action="//givewp.us3.list-manage.com/subscribe/post?u=3ccb75d68bda4381e2f45794c&amp;id=12a081aa13"
581
		      method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate"
582
		      target="_blank">
583
			<div class="give-newsletter-confirmation">
584
				<p><?php esc_html_e( 'To complete your subscription, click the confirmation link in your email. Thank you!', 'give' ); ?></p>
585
			</div>
586
587
			<table class="form-table give-newsletter-form">
588
				<tr valign="middle">
589
					<td>
590
						<label for="mce-EMAIL"
591
						       class="screen-reader-text"><?php esc_html_e( 'Email Address (required)', 'give' ); ?></label>
592
						<input type="email" name="EMAIL" id="mce-EMAIL"
593
						       placeholder="<?php esc_attr_e( 'Email Address (required)', 'give' ); ?>"
594
						       class="required email" value="" required>
595
					</td>
596
					<td>
597
						<label for="mce-FNAME"
598
						       class="screen-reader-text"><?php esc_html_e( 'First Name', 'give' ); ?></label>
599
						<input type="text" name="FNAME" id="mce-FNAME"
600
						       placeholder="<?php esc_attr_e( 'First Name', 'give' ); ?>" class="" value="" required>
601
					</td>
602
					<td>
603
						<label for="mce-LNAME"
604
						       class="screen-reader-text"><?php esc_html_e( 'Last Name', 'give' ); ?></label>
605
						<input type="text" name="LNAME" id="mce-LNAME"
606
						       placeholder="<?php esc_attr_e( 'Last Name', 'give' ); ?>" class="" value="">
607
					</td>
608
					<td>
609
						<input type="submit" name="subscribe" id="mc-embedded-subscribe" class="button"
610
						       value="<?php esc_attr_e( 'Subscribe', 'give' ); ?>">
611
					</td>
612
				</tr>
613
			</table>
614
		</form>
615
616
		<div style="position: absolute; left: -5000px;">
617
			<input type="text" name="b_3ccb75d68bda4381e2f45794c_12a081aa13" tabindex="-1" value="">
618
		</div>
619
620
	</div>
621
622
	<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...
623
	<script type='text/javascript'>(
624
			function ( $ ) {
625
				window.fnames = new Array();
626
				window.ftypes = new Array();
627
				fnames[0] = 'EMAIL';
628
				ftypes[0] = 'email';
629
				fnames[1] = 'FNAME';
630
				ftypes[1] = 'text';
631
				fnames[2] = 'LNAME';
632
				ftypes[2] = 'text';
633
634
				$( 'form[name="mc-embedded-subscribe-form"]' ).removeAttr( 'novalidate' );
635
636
				//Successful submission
637
				$( 'form[name="mc-embedded-subscribe-form"]' ).on( 'submit', function () {
638
639
					var email_field = $( this ).find( '#mce-EMAIL' ).val();
640
					if ( ! email_field ) {
641
						return false;
642
					}
643
					$( this ).find( '.give-newsletter-confirmation' ).show().delay( 5000 ).slideUp();
644
					$( this ).find( '.give-newsletter-form' ).hide();
645
646
				} );
647
648
			}( jQuery )
649
		);
650
		var $mcj = jQuery.noConflict( true );
651
652
653
	</script>
654
	<!--End mc_embed_signup-->
655
656
	<?php
657
}
658
659
660
/**
661
 * Create SVG library function
662
 *
663
 * @param string $icon
664
 *
665
 * @return string
666
 */
667
function give_svg_icons( $icon ) {
668
669
	// Store your SVGs in an associative array
670
	$svgs = array(
671
		'microphone'    => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjY0cHgiIGhlaWdodD0iMTAwcHgiIHZpZXdCb3g9IjAgLTIwIDY0IDEyMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNjQgMTAwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8Zz4NCgk8Zz4NCgkJPHBhdGggZD0iTTYyLDM2LjIxNWgtM2MtMS4xLDAtMiwwLjktMiwyVjUyYzAsNi42ODYtNS4yNjYsMTgtMjUsMThTNyw1OC42ODYsNyw1MlYzOC4yMTVjMC0xLjEtMC45LTItMi0ySDJjLTEuMSwwLTIsMC45LTIsMlY1Mg0KCQkJYzAsMTEuMTg0LDguMjE1LDIzLjE1MiwyNywyNC44MDFWOTBIMTRjLTEuMSwwLTIsMC44OTgtMiwydjZjMCwxLjEsMC45LDIsMiwyaDM2YzEuMSwwLDItMC45LDItMnYtNmMwLTEuMTAyLTAuOS0yLTItMkgzN1Y3Ni44MDENCgkJCUM1NS43ODUsNzUuMTUyLDY0LDYzLjE4NCw2NCw1MlYzOC4yMTVDNjQsMzcuMTE1LDYzLjEsMzYuMjE1LDYyLDM2LjIxNXoiLz4NCgkJPHBhdGggZD0iTTMyLDYwYzExLjczMiwwLDE1LTQuODE4LDE1LThWMzYuMjE1SDE3VjUyQzE3LDU1LjE4MiwyMC4yNjYsNjAsMzIsNjB6Ii8+DQoJCTxwYXRoIGQ9Ik00Nyw4YzAtMy4xODQtMy4yNjgtOC0xNS04QzIwLjI2NiwwLDE3LDQuODE2LDE3LDh2MjEuMjE1aDMwVjh6Ii8+DQoJPC9nPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPC9zdmc+DQo=',
672
		'alert'         => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjI4LjkzOHB4IiBoZWlnaHQ9IjI1LjAwNXB4IiB2aWV3Qm94PSIwIDAgMjguOTM4IDI1LjAwNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjguOTM4IDI1LjAwNTsiDQoJIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggc3R5bGU9ImZpbGw6IzAwMDAwMDsiIGQ9Ik0yOC44NTksMjQuMTU4TDE0Ljk1NywwLjI3OUMxNC44NTYsMC4xMDYsMTQuNjcsMCwxNC40NjgsMGMtMC4xOTgsMC0wLjM4MywwLjEwNi0wLjQ4MSwwLjI3OQ0KCUwwLjA3OSwyNC4xNThjLTAuMTAyLDAuMTc1LTAuMTA2LDAuMzg5LTAuMDA2LDAuNTY1YzAuMTAzLDAuMTc0LDAuMjg3LDAuMjgyLDAuNDg4LDAuMjgyaDI3LjgxNGMwLjIwMSwwLDAuMzg5LTAuMTA4LDAuNDg4LTAuMjgyDQoJYzAuMDQ3LTAuMDg4LDAuMDc0LTAuMTg2LDAuMDc0LTAuMjgxQzI4LjkzOCwyNC4zNDMsMjguOTExLDI0LjI0NSwyOC44NTksMjQuMTU4eiBNMTYuMzY5LDguNDc1bC0wLjQ2Miw5LjQ5M2gtMi4zODlsLTAuNDYxLTkuNDkzDQoJSDE2LjM2OXogTTE0LjcxMSwyMi44MjhoLTAuMDQyYy0xLjA4OSwwLTEuODQzLTAuODE3LTEuODQzLTEuOTA3YzAtMS4xMzEsMC43NzQtMS45MDcsMS44ODUtMS45MDdzMS44NDYsMC43NzUsMS44NjcsMS45MDcNCglDMTYuNTc5LDIyLjAxMSwxNS44NDQsMjIuODI4LDE0LjcxMSwyMi44Mjh6Ii8+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8L3N2Zz4NCg==',
673
		'placemark'     => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iMTAwcHgiIGhlaWdodD0iMTAwcHgiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik01MC40MzQsMjAuMjcxYy0xMi40OTksMC0yMi42NjgsMTAuMTY5LTIyLjY2OCwyMi42NjhjMCwxMS44MTQsMTguODE1LDMyLjE1NSwyMC45NiwzNC40MzdsMS43MDgsMS44MTZsMS43MDgtMS44MTYNCgkJYzIuMTQ1LTIuMjgxLDIwLjk2LTIyLjYyMywyMC45Ni0zNC40MzdDNzMuMTAzLDMwLjQ0LDYyLjkzNCwyMC4yNzEsNTAuNDM0LDIwLjI3MXogTTUwLjQzNCw1Mi4zMmMtNS4xNzIsMC05LjM4LTQuMjA4LTkuMzgtOS4zOA0KCQlzNC4yMDgtOS4zOCw5LjM4LTkuMzhjNS4xNzMsMCw5LjM4LDQuMjA4LDkuMzgsOS4zOFM1NS42MDcsNTIuMzIsNTAuNDM0LDUyLjMyeiIvPg0KPC9nPg0KPC9zdmc+DQo=',
674
		'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==',
675
		'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',
676
	);
677
678
	// Return the chosen icon's SVG string
679
	return $svgs[ $icon ];
680
}
681
682
/**
683
 * Modify Admin Nav Menu Label
684
 *
685
 * @since 1.3
686
 *
687
 * @param object $post_type The current object to add a menu items meta box for.
688
 *
689
 * @return mixed
690
 */
691
function modify_nav_menu_meta_box_object( $post_type ) {
692
	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...
693
		$post_type->labels->name = esc_html__( 'Donation Forms', 'give' );
694
	}
695
696
	return $post_type;
697
}
698
699
add_filter( 'nav_menu_meta_box_object', 'modify_nav_menu_meta_box_object' );
700
701
/**
702
 * Show Donation Forms Post Type in Appearance > Menus by default on fresh install.
703
 *
704
 * @since 1.8.14
705
 *
706
 * @todo  Remove this, when WordPress Core ticket is resolved (https://core.trac.wordpress.org/ticket/16828).
707
 *
708
 * @return bool
709
 */
710
function give_donation_metabox_menu() {
711
712
	// Get Current Screen.
713
	$screen = get_current_screen();
714
715
	// Proceed, if current screen is navigation menus.
716
	if ( 'nav-menus' === $screen->id && give_is_setting_enabled( give_get_option( 'forms_singular' ) ) && ! get_user_option( 'give_is_donation_forms_menu_updated' ) ) {
717
718
		// Return false, if it fails to retrieve hidden meta box list and is not admin.
719
		if ( ! is_admin() || ( ! $hidden_meta_boxes = get_user_option( 'metaboxhidden_nav-menus' ) ) ) {
720
			return false;
721
		}
722
723
		// Return false, In case, we don't find 'Donation Form' in hidden meta box list.
724
		if ( ! in_array( 'add-post-type-give_forms', $hidden_meta_boxes, true ) ) {
725
			return false;
726
		}
727
728
		// Exclude 'Donation Form' value from hidden meta box's list.
729
		$hidden_meta_boxes = array_diff( $hidden_meta_boxes, array( 'add-post-type-give_forms' ) );
730
731
		// Get current user ID.
732
		$user = wp_get_current_user();
733
734
		update_user_option( $user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true );
735
		update_user_option( $user->ID, 'give_is_donation_forms_menu_updated', true, true );
736
	}
737
}
738
739
add_action( 'current_screen', 'give_donation_metabox_menu' );
740
741
/**
742
 * Array_column backup usage
743
 *
744
 * This file is part of the array_column library.
745
 *
746
 * @since      : 1.3.0.1
747
 *
748
 * @copyright  Copyright (c) Ben Ramsey (http://benramsey.com)
749
 * @license    https://opensource.org/licenses/MIT MIT
750
 */
751
752
if ( ! function_exists( 'array_column' ) ) {
753
	/**
754
	 * Returns the values from a single column of the input array, identified by
755
	 * the $columnKey.
756
	 *
757
	 * Optionally, you may provide an $indexKey to index the values in the returned
758
	 * array by the values from the $indexKey column in the input array.
759
	 *
760
	 * @param array      $input     A multi-dimensional array (record set) from which to pull
761
	 *                              a column of values.
762
	 * @param int|string $columnKey The column of values to return. This value may be the
763
	 *                              integer key of the column you wish to retrieve, or it
764
	 *                              may be the string key name for an associative array.
765
	 * @param mixed      $indexKey  (Optional.) The column to use as the index/keys for
766
	 *                              the returned array. This value may be the integer key
767
	 *                              of the column, or it may be the string key name.
768
	 *
769
	 * @return array
770
	 */
771
	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...
772
		// Using func_get_args() in order to check for proper number of
773
		// parameters and trigger errors exactly as the built-in array_column()
774
		// does in PHP 5.5.
775
		$argc   = func_num_args();
776
		$params = func_get_args();
777
778
		if ( $argc < 2 ) {
779
			trigger_error( sprintf( esc_html__( 'array_column() expects at least 2 parameters, %s given.', 'give' ), $argc ), E_USER_WARNING );
780
781
			return null;
782
		}
783
784
		if ( ! is_array( $params[0] ) ) {
785
			trigger_error( sprintf( esc_html__( 'array_column() expects parameter 1 to be array, %s given.', 'give' ), gettype( $params[0] ) ), E_USER_WARNING );
786
787
			return null;
788
		}
789
790 View Code Duplication
		if ( ! is_int( $params[1] ) && ! is_float( $params[1] ) && ! is_string( $params[1] ) && $params[1] !== null && ! ( is_object( $params[1] ) && method_exists( $params[1], '__toString' ) ) ) {
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...
791
			trigger_error( esc_html__( 'array_column(): The column key should be either a string or an integer.', 'give' ), E_USER_WARNING );
792
793
			return false;
794
		}
795
796 View Code Duplication
		if ( isset( $params[2] ) && ! is_int( $params[2] ) && ! is_float( $params[2] ) && ! is_string( $params[2] ) && ! ( is_object( $params[2] ) && method_exists( $params[2], '__toString' ) ) ) {
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...
797
			trigger_error( esc_html__( 'array_column(): The index key should be either a string or an integer.', 'give' ), E_USER_WARNING );
798
799
			return false;
800
		}
801
802
		$paramsInput     = $params[0];
803
		$paramsColumnKey = ( $params[1] !== null ) ? (string) $params[1] : null;
804
805
		$paramsIndexKey = null;
806
		if ( isset( $params[2] ) ) {
807
			if ( is_float( $params[2] ) || is_int( $params[2] ) ) {
808
				$paramsIndexKey = (int) $params[2];
809
			} else {
810
				$paramsIndexKey = (string) $params[2];
811
			}
812
		}
813
814
		$resultArray = array();
815
816
		foreach ( $paramsInput as $row ) {
817
			$key    = $value = null;
818
			$keySet = $valueSet = false;
819
820
			if ( $paramsIndexKey !== null && array_key_exists( $paramsIndexKey, $row ) ) {
821
				$keySet = true;
822
				$key    = (string) $row[ $paramsIndexKey ];
823
			}
824
825
			if ( $paramsColumnKey === null ) {
826
				$valueSet = true;
827
				$value    = $row;
828
			} elseif ( is_array( $row ) && array_key_exists( $paramsColumnKey, $row ) ) {
829
				$valueSet = true;
830
				$value    = $row[ $paramsColumnKey ];
831
			}
832
833
			if ( $valueSet ) {
834
				if ( $keySet ) {
835
					$resultArray[ $key ] = $value;
836
				} else {
837
					$resultArray[] = $value;
838
				}
839
			}
840
		}
841
842
		return $resultArray;
843
	}
844
}// End if().
845
846
/**
847
 * Determines the receipt visibility status.
848
 *
849
 * @since 1.3.2
850
 *
851
 * @param string $payment_key
852
 *
853
 * @return bool Whether the receipt is visible or not.
854
 */
855
function give_can_view_receipt( $payment_key = '' ) {
856
857
	$return = false;
858
859
	if ( empty( $payment_key ) ) {
860
		return $return;
861
	}
862
863
	global $give_receipt_args;
864
865
	$give_receipt_args['id'] = give_get_donation_id_by_key( $payment_key );
866
867
	$user_id = (int) give_get_payment_user_id( $give_receipt_args['id'] );
868
869
	$payment_meta = give_get_payment_meta( $give_receipt_args['id'] );
870
871
	if ( is_user_logged_in() ) {
872
		if ( $user_id === (int) get_current_user_id() ) {
873
			$return = true;
874
		} elseif ( wp_get_current_user()->user_email === give_get_payment_user_email( $give_receipt_args['id'] ) ) {
875
			$return = true;
876
		} elseif ( current_user_can( 'view_give_sensitive_data' ) ) {
877
			$return = true;
878
		}
879
	}
880
881
	// Check whether it is purchase session?
882
	$purchase_session = give_get_purchase_session();
883
	if ( ! empty( $purchase_session ) && ! is_user_logged_in() ) {
884
		if ( $purchase_session['purchase_key'] === $payment_meta['key'] ) {
885
			$return = true;
886
		}
887
	}
888
889
	// Check whether it is receipt access session?
890
	$receipt_session = give_get_receipt_session();
891
	if ( ! empty( $receipt_session ) && ! is_user_logged_in() ) {
892
		if ( $receipt_session === $payment_meta['key'] ) {
893
			$return = true;
894
		}
895
	}
896
897
	// Check whether it is history access session?
898
	if ( true === give_get_history_session() ) {
899
		$return = true;
900
	}
901
902
	return (bool) apply_filters( 'give_can_view_receipt', $return, $payment_key );
903
904
}
905
906
/**
907
 * Fallback for cal_days_in_month
908
 *
909
 * Fallback in case the calendar extension is not loaded in PHP; Only supports Gregorian calendar
910
 */
911
if ( ! function_exists( 'cal_days_in_month' ) ) {
912
	/**
913
	 * cal_days_in_month
914
	 *
915
	 * @param int $calendar
916
	 * @param int $month
917
	 * @param int $year
918
	 *
919
	 * @return bool|string
920
	 */
921
	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...
922
		return date( 't', mktime( 0, 0, 0, $month, 1, $year ) );
923
	}
924
}
925
926
/**
927
 * Get plugin info including status, type, and license validation.
928
 *
929
 * This is an enhanced version of get_plugins() that returns the status
930
 * (`active` or `inactive`) of all plugins, type of plugin (`add-on` or `other`
931
 * and license validation for Give add-ons (`true` or `false`). Does not include
932
 * MU plugins.
933
 *
934
 * @since 1.8.0
935
 *
936
 * @return array Plugin info plus status, type, and license validation if
937
 *               available.
938
 */
939
function give_get_plugins() {
940
	$plugins             = get_plugins();
941
	$active_plugin_paths = (array) get_option( 'active_plugins', array() );
942
943 View Code Duplication
	if ( is_multisite() ) {
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...
944
		$network_activated_plugin_paths = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
945
		$active_plugin_paths            = array_merge( $active_plugin_paths, $network_activated_plugin_paths );
946
	}
947
948
	foreach ( $plugins as $plugin_path => $plugin_data ) {
949
		// Is plugin active?
950
		if ( in_array( $plugin_path, $active_plugin_paths ) ) {
951
			$plugins[ $plugin_path ]['Status'] = 'active';
952
		} else {
953
			$plugins[ $plugin_path ]['Status'] = 'inactive';
954
		}
955
956
		$dirname = strtolower( dirname( $plugin_path ) );
957
958
		// Is plugin a Give add-on by WordImpress?
959
		if ( strstr( $dirname, 'give-' ) && strstr( $plugin_data['AuthorURI'], 'wordimpress.com' ) ) {
960
			// Plugin is a Give-addon.
961
			$plugins[ $plugin_path ]['Type'] = 'add-on';
962
963
			/* @var stdClass $license_active */
964
			$license_active = __give_get_active_license_info( Give_License::get_short_name( $plugin_data['Name'] ) );
965
966
			// Does a valid license exist?
967
			if ( ! empty( $license_active ) && 'valid' === $license_active->license ) {
968
				$plugins[ $plugin_path ]['License'] = true;
969
			} else {
970
				$plugins[ $plugin_path ]['License'] = false;
971
			}
972
		} else {
973
			// Plugin is not a Give add-on.
974
			$plugins[ $plugin_path ]['Type'] = 'other';
975
		}
976
	}
977
978
	return $plugins;
979
}
980
981
/**
982
 * Check if terms enabled or not for form.
983
 *
984
 * @since 1.8
985
 *
986
 * @param $form_id
987
 *
988
 * @return bool
989
 */
990
function give_is_terms_enabled( $form_id ) {
991
	$form_option = give_get_meta( $form_id, '_give_terms_option', true );
992
993
	if ( give_is_setting_enabled( $form_option, 'global' ) && give_is_setting_enabled( give_get_option( 'terms' ) ) ) {
994
		return true;
995
996
	} elseif ( give_is_setting_enabled( $form_option ) ) {
997
		return true;
998
999
	} else {
1000
		return false;
1001
	}
1002
}
1003
1004
/**
1005
 * Delete donation stats cache.
1006
 *
1007
 * @todo  Resolve stats cache key naming issue. Currently it is difficult to regenerate cache key.
1008
 *
1009
 * @since 1.8.7
1010
 *
1011
 * @param string|array $date_range Date for stats.
1012
 *                                 Date value should be in today, yesterday, this_week, last_week, this_month,
1013
 *                                 last_month, this_quarter, last_quarter, this_year, last_year. For date value other,
1014
 *                                 all cache will be removed.
1015
 *
1016
 * @param array        $args
1017
 *
1018
 * @return WP_Error|bool
1019
 */
1020
function give_delete_donation_stats( $date_range = '', $args = array() ) {
1021
1022
	// Delete all cache.
1023
	$status = Give_Cache::delete( Give_Cache::get_options_like( 'give_stats' ) );
1024
1025
	/**
1026
	 * Fire the action when donation stats delete.
1027
	 *
1028
	 * @since 1.8.7
1029
	 *
1030
	 * @param string|array $date_range
1031
	 * @param array        $args
1032
	 */
1033
	do_action( 'give_delete_donation_stats', $status, $date_range, $args );
1034
1035
	return $status;
1036
}
1037
1038
/**
1039
 * Check if admin creating new donation form or not.
1040
 *
1041
 * @since 2.0
1042
 * @return bool
1043
 */
1044
function give_is_add_new_form_page() {
1045
	$status = false;
1046
1047
	if ( false !== strpos( $_SERVER['REQUEST_URI'], '/wp-admin/post-new.php?post_type=give_forms' ) ) {
1048
		$status = true;
1049
	}
1050
1051
	return $status;
1052
}
1053
1054
/**
1055
 * Get Form/Payment meta.
1056
 *
1057
 * Note: This function will help you to get meta for payment and form.
1058
 *       If you want to get meta for donors then use get_meta of Give_Donor and
1059
 *       If you want to get meta for logs then use get_meta of Give_Logging->logmeta_db.
1060
 *
1061
 * @since 1.8.8
1062
 *
1063
 * @param int    $id
1064
 * @param string $meta_key
1065
 * @param bool   $single
1066
 * @param bool   $default
1067
 *
1068
 * @return mixed
1069
 */
1070
function give_get_meta( $id, $meta_key = '', $single = false, $default = false ) {
1071
	/**
1072
	 * Filter the meta value
1073
	 *
1074
	 * @since 1.8.8
1075
	 */
1076
	$meta_value = apply_filters( 'give_get_meta', get_post_meta( $id, $meta_key, $single ), $id, $meta_key, $default );
1077
1078
	if ( ( empty( $meta_key ) || empty( $meta_value ) ) && $default ) {
1079
		$meta_value = $default;
1080
	}
1081
1082
	return $meta_value;
1083
}
1084
1085
/**
1086
 * Update Form/Payment meta.
1087
 *
1088
 * @since 1.8.8
1089
 *
1090
 * @param int    $id
1091
 * @param string $meta_key
1092
 * @param mixed  $meta_value
1093
 * @param mixed  $prev_value
1094
 *
1095
 * @return mixed
1096
 */
1097
function give_update_meta( $id, $meta_key, $meta_value, $prev_value = '' ) {
1098
	$status = update_post_meta( $id, $meta_key, $meta_value, $prev_value );
1099
1100
	/**
1101
	 * Filter the meta value update status
1102
	 *
1103
	 * @since 1.8.8
1104
	 */
1105
	return apply_filters( 'give_update_meta', $status, $id, $meta_key, $meta_value );
1106
}
1107
1108
/**
1109
 * Delete Form/Payment meta.
1110
 *
1111
 * @since 1.8.8
1112
 *
1113
 * @param int    $id
1114
 * @param string $meta_key
1115
 * @param string $meta_value
1116
 *
1117
 * @return mixed
1118
 */
1119
function give_delete_meta( $id, $meta_key, $meta_value = '' ) {
1120
	$status = delete_post_meta( $id, $meta_key, $meta_value );
1121
1122
	/**
1123
	 * Filter the meta value delete status
1124
	 *
1125
	 * @since 1.8.8
1126
	 */
1127
	return apply_filters( 'give_delete_meta', $status, $id, $meta_key, $meta_value );
1128
}
1129
1130
/**
1131
 * Check if the upgrade routine has been run for a specific action
1132
 *
1133
 * @since  1.0
1134
 *
1135
 * @param  string $upgrade_action The upgrade action to check completion for
1136
 *
1137
 * @return bool                   If the action has been added to the completed actions array
1138
 */
1139
function give_has_upgrade_completed( $upgrade_action = '' ) {
1140
	// Bailout.
1141
	if ( empty( $upgrade_action ) ) {
1142
		return false;
1143
	}
1144
1145
	// Fresh install?
1146
	// If fresh install then all upgrades will be consider as completed.
1147
	$is_fresh_install = ! get_option( 'give_version' );
1148
	if ( $is_fresh_install ) {
1149
		return true;
1150
	}
1151
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1152
1153
	$completed_upgrades = give_get_completed_upgrades();
1154
1155
	return in_array( $upgrade_action, $completed_upgrades );
1156
1157
}
1158
1159
/**
1160
 * For use when doing 'stepped' upgrade routines, to see if we need to start somewhere in the middle
1161
 *
1162
 * @since 1.8
1163
 *
1164
 * @return mixed   When nothing to resume returns false, otherwise starts the upgrade where it left off
1165
 */
1166
function give_maybe_resume_upgrade() {
1167
	$doing_upgrade = get_option( 'give_doing_upgrade', false );
1168
	if ( empty( $doing_upgrade ) ) {
1169
		return false;
1170
	}
1171
1172
	return $doing_upgrade;
1173
}
1174
1175
/**
1176
 * Adds an upgrade action to the completed upgrades array
1177
 *
1178
 * @since  1.0
1179
 *
1180
 * @param  string $upgrade_action The action to add to the completed upgrades array
1181
 *
1182
 * @return bool                   If the function was successfully added
1183
 */
1184
function give_set_upgrade_complete( $upgrade_action = '' ) {
1185
1186
	if ( empty( $upgrade_action ) ) {
1187
		return false;
1188
	}
1189
1190
	$completed_upgrades   = give_get_completed_upgrades();
1191
	$completed_upgrades[] = $upgrade_action;
1192
1193
	// Remove any blanks, and only show uniques.
1194
	$completed_upgrades = array_unique( array_values( $completed_upgrades ) );
1195
1196
	/**
1197
	 * Fire the action when any upgrade set to complete.
1198
	 *
1199
	 * @since 1.8.12
1200
	 */
1201
	do_action( 'give_set_upgrade_completed', $upgrade_action, $completed_upgrades );
1202
1203
	return update_option( 'give_completed_upgrades', $completed_upgrades, false );
1204
}
1205
1206
/**
1207
 * Get's the array of completed upgrade actions
1208
 *
1209
 * @since  1.0
1210
 * @return array The array of completed upgrades
1211
 */
1212
function give_get_completed_upgrades() {
1213
	return (array) get_option( 'give_completed_upgrades' );
1214
}
1215
1216
/**
1217
 * In 2.0 we updated table for log, payment and form.
1218
 *
1219
 * Note: internal purpose only.
1220
 *
1221
 * @since 2.0
1222
 * @global wpdb  $wpdb
1223
 *
1224
 * @param string $type Context for table
1225
 *
1226
 * @return null|array
1227
 */
1228
function __give_v20_bc_table_details( $type ) {
1229
	global $wpdb;
1230
	$table = array();
1231
1232
	// Bailout.
1233
	if ( empty( $type ) ) {
1234
		return null;
1235
	}
1236
1237
	switch ( $type ) {
1238
		case 'form':
1239
			$table['name']         = $wpdb->formmeta;
1240
			$table['column']['id'] = 'form_id';
1241
1242
			break;
1243
1244
		case 'payment':
1245
			$table['name']         = $wpdb->donationmeta;
1246
			$table['column']['id'] = Give()->payment_meta->get_meta_type() . '_id';
1247
	}
1248
1249
	// Backward compatibility.
1250
	if ( ! give_has_upgrade_completed( 'v20_move_metadata_into_new_table' ) ) {
1251
		$table['name']         = $wpdb->postmeta;
1252
		$table['column']['id'] = 'post_id';
1253
	}
1254
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1255
1256
	return $table;
1257
}
1258
1259
/**
1260
 * Remove the Give transaction pages from WP search results.
1261
 *
1262
 * @since 1.8.13
1263
 *
1264
 * @param WP_Query $query
1265
 */
1266
function give_remove_pages_from_search( $query ) {
1267
1268
	if ( ! $query->is_admin && $query->is_search && $query->is_main_query() ) {
1269
1270
		$transaction_failed = give_get_option( 'failure_page', 0 );
1271
		$success_page       = give_get_option( 'success_page', 0 );
1272
1273
		$args = apply_filters( 'give_remove_pages_from_search', array(
1274
			$transaction_failed,
1275
			$success_page,
1276
		), $query );
1277
		$query->set( 'post__not_in', $args );
1278
	}
1279
}
1280
1281
add_action( 'pre_get_posts', 'give_remove_pages_from_search', 10, 1 );
1282
1283
/**
1284
 * Inserts a new key/value before a key in the array.
1285
 *
1286
 * @since 1.8.13
1287
 *
1288
 * @param string       $key       The key to insert before.
1289
 * @param array        $array     An array to insert in to.
1290
 * @param string       $new_key   The key to insert.
1291
 * @param array|string $new_value An value to insert.
1292
 *
1293
 * @return array The new array if the key exists, the passed array otherwise.
1294
 *
1295
 * @see   array_insert_before()
1296
 */
1297 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...
1298
	if ( array_key_exists( $key, $array ) ) {
1299
		$new = array();
1300
		foreach ( $array as $k => $value ) {
1301
			if ( $k === $key ) {
1302
				$new[ $new_key ] = $new_value;
1303
			}
1304
			$new[ $k ] = $value;
1305
		}
1306
1307
		return $new;
1308
	}
1309
1310
	return $array;
1311
}
1312
1313
/**
1314
 * Inserts a new key/value after a key in the array.
1315
 *
1316
 * @since 1.8.13
1317
 *
1318
 * @param string       $key       The key to insert after.
1319
 * @param array        $array     An array to insert in to.
1320
 * @param string       $new_key   The key to insert.
1321
 * @param array|string $new_value An value to insert.
1322
 *
1323
 * @return array The new array if the key exists, the passed array otherwise.
1324
 *
1325
 * @see   array_insert_before()
1326
 */
1327 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...
1328
	if ( array_key_exists( $key, $array ) ) {
1329
		$new = array();
1330
		foreach ( $array as $k => $value ) {
1331
			$new[ $k ] = $value;
1332
			if ( $k === $key ) {
1333
				$new[ $new_key ] = $new_value;
1334
			}
1335
		}
1336
1337
		return $new;
1338
	}
1339
1340
	return $array;
1341
}
1342
1343
/**
1344
 * Pluck a certain field out of each object in a list.
1345
 *
1346
 * This has the same functionality and prototype of
1347
 * array_column() (PHP 5.5) but also supports objects.
1348
 *
1349
 * @since 1.8.13
1350
 *
1351
 * @param array      $list      List of objects or arrays
1352
 * @param int|string $field     Field from the object to place instead of the entire object
1353
 * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
1354
 *                              Default null.
1355
 *
1356
 * @return array Array of found values. If `$index_key` is set, an array of found values with keys
1357
 *               corresponding to `$index_key`. If `$index_key` is null, array keys from the original
1358
 *               `$list` will be preserved in the results.
1359
 */
1360
function give_list_pluck( $list, $field, $index_key = null ) {
1361
1362
	if ( ! $index_key ) {
1363
		/**
1364
		 * This is simple. Could at some point wrap array_column()
1365
		 * if we knew we had an array of arrays.
1366
		 */
1367
		foreach ( $list as $key => $value ) {
1368
			if ( is_object( $value ) ) {
1369
				if ( isset( $value->$field ) ) {
1370
					$list[ $key ] = $value->$field;
1371
				}
1372
			} else {
1373
				if ( isset( $value[ $field ] ) ) {
1374
					$list[ $key ] = $value[ $field ];
1375
				}
1376
			}
1377
		}
1378
1379
		return $list;
1380
	}
1381
1382
	/*
1383
	 * When index_key is not set for a particular item, push the value
1384
	 * to the end of the stack. This is how array_column() behaves.
1385
	 */
1386
	$newlist = array();
1387
	foreach ( $list as $value ) {
1388
		if ( is_object( $value ) ) {
1389
			if ( isset( $value->$index_key ) ) {
1390
				$newlist[ $value->$index_key ] = $value->$field;
1391
			} else {
1392
				$newlist[] = $value->$field;
1393
			}
1394
		} else {
1395
			if ( isset( $value[ $index_key ] ) ) {
1396
				$newlist[ $value[ $index_key ] ] = $value[ $field ];
1397
			} else {
1398
				$newlist[] = $value[ $field ];
1399
			}
1400
		}
1401
	}
1402
1403
	$list = $newlist;
1404
1405
	return $list;
1406
}
1407
1408
/**
1409
 * Add meta data field to a donor.
1410
 *
1411
 * @since 1.8.13
1412
 *
1413
 * @param int    $donor_id   Donor ID.
1414
 * @param string $meta_key   Metadata name.
1415
 * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
1416
 * @param bool   $unique     Optional. Whether the same key should not be added.
1417
 *                           Default false.
1418
 *
1419
 * @return int|false Meta ID on success, false on failure.
1420
 */
1421
function add_donor_meta( $donor_id, $meta_key, $meta_value, $unique = false ) {
1422
	return add_metadata( 'give_customer', $donor_id, $meta_key, $meta_value, $unique );
1423
}
1424
1425
/**
1426
 * Remove metadata matching criteria from a Donor meta.
1427
 *
1428
 * You can match based on the key, or key and value. Removing based on key and
1429
 * value, will keep from removing duplicate metadata with the same key. It also
1430
 * allows removing all metadata matching key, if needed.
1431
 *
1432
 * @since 1.8.13
1433
 *
1434
 * @param int    $donor_id   Donor ID
1435
 * @param string $meta_key   Metadata name.
1436
 * @param mixed  $meta_value Optional. Metadata value.
1437
 *
1438
 * @return bool True on success, false on failure.
1439
 */
1440
function delete_donor_meta( $donor_id, $meta_key, $meta_value = '' ) {
1441
	return delete_metadata( 'give_customer', $donor_id, $meta_key, $meta_value );
1442
}
1443
1444
/**
1445
 * Retrieve donor meta field for a donor meta table.
1446
 *
1447
 * @since 1.8.13
1448
 *
1449
 * @param int    $donor_id Donor ID.
1450
 * @param string $key      Optional. The meta key to retrieve. By default, returns data for all keys.
1451
 * @param bool   $single   Whether to return a single value.
1452
 *
1453
 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
1454
 *  is true.
1455
 */
1456
function get_donor_meta( $donor_id, $key = '', $single = false ) {
1457
	return get_metadata( 'give_customer', $donor_id, $key, $single );
1458
}
1459
1460
/**
1461
 * Update customer meta field based on Donor ID.
1462
 *
1463
 * If the meta field for the donor does not exist, it will be added.
1464
 *
1465
 * @since 1.8.13
1466
 *
1467
 * @param int    $donor_id   Donor ID.
1468
 * @param string $meta_key   Metadata key.
1469
 * @param mixed  $meta_value Metadata value.
1470
 * @param mixed  $prev_value Optional. Previous value to check before removing.
1471
 *
1472
 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
1473
 */
1474
function update_donor_meta( $donor_id, $meta_key, $meta_value, $prev_value = '' ) {
1475
	return update_metadata( 'give_customer', $donor_id, $meta_key, $meta_value, $prev_value );
1476
}
1477
1478
1479
/**
1480
 * Give recalculate income and donation of the donation from ID
1481
 *
1482
 * @since 1.8.13
1483
 *
1484
 * @param int $form_id Form id of which recalculation needs to be done.
1485
 *
1486
 * @return void
1487
 */
1488
function give_recount_form_income_donation( $form_id = 0 ) {
1489
	// Check if form id is not empty.
1490
	if ( ! empty( $form_id ) ) {
1491
		/**
1492
		 * Filter to modify payment status.
1493
		 *
1494
		 * @since 1.8.13
1495
		 */
1496
		$accepted_statuses = apply_filters( 'give_recount_accepted_statuses', array( 'publish' ) );
1497
1498
		/**
1499
		 * Filter to modify args of payment query before recalculating the form total
1500
		 *
1501
		 * @since 1.8.13
1502
		 */
1503
		$args = apply_filters( 'give_recount_form_stats_args', array(
1504
				'give_forms'     => $form_id,
1505
				'status'         => $accepted_statuses,
1506
				'posts_per_page' => - 1,
1507
				'fields'         => 'ids',
1508
			) );
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 8 spaces, but found 12.
Loading history...
1509
1510
		$totals = array(
1511
			'sales'    => 0,
1512
			'earnings' => 0,
1513
		);
1514
1515
		$payments = new Give_Payments_Query( $args );
1516
		$payments = $payments->get_payments();
1517
1518
		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...
1519
			foreach ( $payments as $payment ) {
1520
				// Ensure acceptible status only
1521
				if ( ! in_array( $payment->post_status, $accepted_statuses ) ) {
1522
					continue;
1523
				}
1524
1525
				// Ensure only payments for this form are counted
1526
				if ( $payment->form_id != $form_id ) {
1527
					continue;
1528
				}
1529
1530
				$totals['sales'] ++;
1531
				$totals['earnings'] += $payment->total;
1532
1533
			}
1534
		}
1535
		give_update_meta( $form_id, '_give_form_sales', $totals['sales'] );
1536
		give_update_meta( $form_id, '_give_form_earnings', give_sanitize_amount_for_db( $totals['earnings'] ) );
1537
	}// End if().
1538
}
1539
1540
1541
/**
1542
 * Get attribute string
1543
 *
1544
 * @since 1.8.17
1545
 *
1546
 * @param array $attributes
1547
 * @param array $default_attributes
1548
 *
1549
 * @return string
1550
 */
1551
function give_get_attribute_str( $attributes, $default_attributes = array() ) {
1552
	$attribute_str = '';
1553
1554
	if( isset( $attributes['attributes'] ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
1555
		$attributes = $attributes['attributes'];
1556
	}
1557
1558
	if( ! empty( $default_attributes ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
1559
		$attributes = wp_parse_args( $attributes, $default_attributes );
1560
	}
1561
1562
	if ( empty( $attributes ) ) {
1563
		return $attribute_str;
1564
	}
1565
1566
	foreach ( $attributes as $tag => $value ) {
1567
		$attribute_str .= " {$tag}=\"{$value}\"";
1568
	}
1569
1570
	return trim( $attribute_str );
1571
}
1572
1573
/**
1574
 * Get the upload dir path
1575
 *
1576
 * @since 1.8.17
1577
 *
1578
 * @return string $wp_upload_dir;
1579
 */
1580
function give_get_wp_upload_dir() {
1581
	$wp_upload_dir = wp_upload_dir();
1582
1583
	return ( ! empty( $wp_upload_dir['path'] ) ? $wp_upload_dir['path'] : false );
1584
}
1585
1586
/**
1587
 * Get the data from uploaded JSON file
1588
 *
1589
 * @since 1.8.17
1590
 *
1591
 * @param string $file_name filename of the json file that is being uploaded
1592
 *
1593
 * @return string|bool $file_contents File content
1594
 */
1595
function give_get_core_settings_json( $file_name ) {
1596
	$upload_dir = give_get_wp_upload_dir();
1597
	$file_path  = $upload_dir . '/' . $file_name;
1598
1599
	if ( is_wp_error( $file_path ) || empty( $file_path ) ) {
1600
		Give_Admin_Settings::add_error( 'give-import-csv', __( 'Please upload or provide a valid JSON file.', 'give' ) );
1601
	}
1602
1603
	$file_contents = file_get_contents( $file_path );
0 ignored issues
show
introduced by
file_get_contents is highly discouraged, please use wpcom_vip_file_get_contents() instead.
Loading history...
1604
1605
	return $file_contents;
1606
}
1607
1608
/**
1609
 * Get number of donation to show when user is not login.
1610
 *
1611
 * @since 1.8.17
1612
 *
1613
 * @return int $country The two letter country code for the site's base country
1614
 */
1615
function give_get_limit_display_donations() {
1616
	return give_get_option( 'limit_display_donations', 1 );
1617
}
1618
1619
/**
1620
 * Add footer to the table when donor is view the donation history page with out login
1621
 *
1622
 * @since 1.8.17
1623
 */
1624
function give_donation_history_table_end() {
1625
	$email = Give()->session->get( 'give_email' );
1626
	?>
1627
	<tfoot>
1628
	<tr>
1629
		<td colspan="9999">
1630
			<div class="give-security-wrap">
1631
				<div class="give-security-column give-security-description-wrap">
1632
					<?php
1633
					echo sprintf( __( 'For security reasons, please confirm your email address (%s) to view your complete donation history.', 'give' ), $email );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1634
					?>
1635
				</div>
1636
				<div class="give-security-column give-security-button-wrap">
1637
					<a href="#" data-email="<?php echo $email; ?>" id="give-confirm-email-btn"
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$email'
Loading history...
1638
					   class="give-confirm-email-btn give-btn">
1639
						<?php _e( 'Confirm Email', 'give' ); ?>
1640
					</a>
1641
					<span><?php _e( 'Email Sent!', 'give' ); ?></span>
1642
				</div>
1643
			</div>
1644
		</td>
1645
	</tr>
1646
	</tfoot>
1647
	<?php
1648
}
1649
1650
1651
/**
1652
 * Wrapper for _doing_it_wrong.
1653
 *
1654
 * @since  1.8.18
1655
 *
1656
 * @param  string $function
1657
 * @param  string $message
1658
 * @param  string $version
1659
 *
1660
 * @return void
1661
 */
1662
function give_doing_it_wrong( $function, $message, $version ) {
1663
	$message .= "\nBacktrace:" . wp_debug_backtrace_summary();
1664
1665
	_doing_it_wrong( $function, $message, $version );
1666
}
1667
1668
1669
/**
1670
 * Remove limit from running php script complete.
1671
 *
1672
 * @since 1.8.18
1673
 */
1674
function give_ignore_user_abort() {
1675
	ignore_user_abort( true );
1676
1677
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
1678
		set_time_limit( 0 );
1679
	}
1680
}
1681
1682
/**
1683
 * Get post type count.
1684
 *
1685
 * @since 2.0.2
1686
 *
1687
 * @param string $post_type
1688
 * @param array  $args
1689
 *
1690
 * @return int
1691
 */
1692
function give_get_total_post_type_count( $post_type = '', $args = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $args 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...
1693
	global $wpdb;
1694
	$where = '';
1695
1696
	if ( ! $post_type ) {
1697
		return 0;
1698
	}
1699
1700
	// Bulit where query
1701
	if ( ! empty( $post_type ) ) {
1702
		$where .= ' WHERE';
1703
1704
		if ( is_array( $post_type ) ) {
1705
			$where .= " post_type='" . implode( "' OR post_type='", $post_type ) . "'";
1706
		} else {
1707
			$where .= " post_type='{$post_type}'";
1708
		}
1709
	}
1710
1711
	$result = $wpdb->get_var( "SELECT count(ID) FROM {$wpdb->posts}{$where}" );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1712
1713
	return absint( $result );
1714
}
1715
1716
/**
1717
 * Define a constant if it is not already defined.
1718
 *
1719
 * @since  2.0.5
1720
 *
1721
 * @param string $name  Constant name.
1722
 * @param string $value Value.
1723
 *
1724
 * @credit WooCommerce
1725
 */
1726
function give_maybe_define_constant( $name, $value ) {
1727
	if ( ! defined( $name ) ) {
1728
		define( $name, $value );
1729
	}
1730
}
1731
1732
/**
1733
 * Decode time short tag in string
1734
 *
1735
 * @since 2.1.0
1736
 *
1737
 * @param string $string
1738
 * @param int    $timestamp
1739
 *
1740
 * @return string
1741
 */
1742
function give_time_do_tags( $string, $timestamp = 0 ) {
1743
	$current_time = ! empty( $timestamp ) ? $timestamp : current_time( 'timestamp' );
1744
1745
	$formatted_string = str_replace( array(
1746
		'{D}',
1747
		'{DD}',
1748
		'{M}',
1749
		'{MM}',
1750
		'{YY}',
1751
		'{YYYY}',
1752
		'{H}',
1753
		'{HH}',
1754
		'{N}',
1755
		'{S}'
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
1756
	), array(
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 8 spaces, but found 4.
Loading history...
1757
			date( 'j', $current_time ),
1758
			date( 'd', $current_time ),
1759
			date( 'n', $current_time ),
1760
			date( 'm', $current_time ),
1761
			date( 'Y', $current_time ),
1762
			date( 'Y', $current_time ),
1763
			date( 'G', $current_time ),
1764
			date( 'H', $current_time ),
1765
			date( 's', $current_time )
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
1766
		), $string );
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 4 spaces, but found 8.
Loading history...
1767
1768
	/**
1769
	 * Filter the parsed string.
1770
	 *
1771
	 * @since 2.1.0
1772
	 */
1773
	return apply_filters( 'give_time_do_tags', $formatted_string, $string, $timestamp );
1774
}
1775
1776
1777
/**
1778
 * Check if Company field enabled or not for form or globally.
1779
 *
1780
 * @since 2.1
1781
 *
1782
 * @param $form_id
1783
 *
1784
 * @return bool
1785
 */
1786
function give_is_company_field_enabled( $form_id ) {
1787
	$form_setting_val   = give_get_meta( $form_id, '_give_company_field', true );
1788
	$global_setting_val = give_get_option( 'company_field' );
1789
1790
	if ( ! empty( $form_setting_val ) ) {
1791
		if ( give_is_setting_enabled( $form_setting_val, array( 'required', 'optional' ) ) ) {
0 ignored issues
show
Documentation introduced by
array('required', 'optional') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string|null.

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...
1792
			return true;
1793
		} elseif ( 'global' === $form_setting_val && give_is_setting_enabled( $global_setting_val, array(
0 ignored issues
show
Documentation introduced by
array('required', 'optional') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string|null.

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...
1794
				'required',
1795
				'optional'
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
1796
			) ) ) {
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 8 spaces, but found 12.
Loading history...
1797
			return true;
1798
		} else {
1799
			return false;
1800
		}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
1801
1802
	} elseif ( give_is_setting_enabled( $global_setting_val, array( 'required', 'optional' ) ) ) {
0 ignored issues
show
Documentation introduced by
array('required', 'optional') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string|null.

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...
1803
		return true;
1804
1805
	} else {
1806
		return false;
1807
	}
1808
}
1809
1810
/**
1811
 * Check if anonymous donation field enabled or not for form or globally.
1812
 *
1813
 * @since 2.1
1814
 *
1815
 * @param $form_id
1816
 *
1817
 * @return bool
1818
 */
1819 View Code Duplication
function give_is_anonymous_donation_field_enabled( $form_id ) {
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...
1820
	$form_setting_val   = give_get_meta( $form_id, '_give_anonymous_donation', true, 'global' );
0 ignored issues
show
Documentation introduced by
'global' is of type string, 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...
1821
	$global_setting_val = give_get_option( 'anonymous_donation', 'disabled' );
1822
1823
	if ( ! empty( $form_setting_val ) ) {
1824
		if( give_is_setting_enabled( $form_setting_val ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
1825
			return true;
1826
		}elseif ( 'global' === $form_setting_val && give_is_setting_enabled( $global_setting_val ) ){
1827
			return true;
1828
		}else{
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
1829
			return false;
1830
		}
1831
	} elseif ( give_is_setting_enabled( $global_setting_val ) ) {
1832
		return true;
1833
	}
1834
1835
	return false;
1836
}
1837
1838
/**
1839
 * Check if donor comment field enabled or not for form or globally.
1840
 *
1841
 * @since 2.1
1842
 *
1843
 * @param $form_id
1844
 *
1845
 * @return bool
1846
 */
1847 View Code Duplication
function give_is_donor_comment_field_enabled( $form_id ) {
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...
1848
	$form_setting_val   = give_get_meta( $form_id, '_give_donor_comment', true, 'global' );
0 ignored issues
show
Documentation introduced by
'global' is of type string, 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...
1849
	$global_setting_val = give_get_option( 'donor_comment', 'disabled' );
1850
1851
	if ( ! empty( $form_setting_val ) ) {
1852
		if( give_is_setting_enabled( $form_setting_val ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
1853
			return true;
1854
		} elseif ( 'global' === $form_setting_val && give_is_setting_enabled( $global_setting_val ) ){
1855
			return true;
1856
		}else{
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
1857
			return false;
1858
		}
1859
	} elseif ( give_is_setting_enabled( $global_setting_val ) ) {
1860
		return true;
1861
	}
1862
1863
	return false;
1864
1865
}
1866
1867
/**
1868
 * Get add-on user meta value information
1869
 * Note: only for internal use.
1870
 *
1871
 * @since 2.1.0
1872
 *
1873
 * @param string $license_id
1874
 *
1875
 * @return array
1876
 */
1877
function __give_get_active_license_info( $license_id ) {
1878
	global $wpdb;
1879
	$option_name = "{$license_id}_license_active";
1880
	$data        = array();
1881
1882
	if ( ! isset( $GLOBALS['give_active_licenses_info'] ) ) {
1883
		$GLOBALS['give_active_licenses_info']  = array();
1884
1885
		$licenses_info = $wpdb->get_results(
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1886
			"
1887
			SELECT option_name, option_value
1888
			FROM {$wpdb->options}
1889
			WHERE option_name LIKE '%_license_active%'
1890
			AND option_name LIKE '%give_%'
1891
			",
1892
			ARRAY_A
1893
		);
1894
1895 View Code Duplication
		if ( ! empty( $licenses_info ) ) {
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...
1896
			$GLOBALS['give_active_licenses_info'] = array_combine(
1897
				wp_list_pluck( $licenses_info, 'option_name' ),
1898
				wp_list_pluck( $licenses_info, 'option_value' )
1899
			);
1900
		}
1901
	}
1902
1903 View Code Duplication
	if ( in_array( $option_name, array_keys( $GLOBALS['give_active_licenses_info'] ) ) ) {
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...
1904
		$data = maybe_unserialize( $GLOBALS['give_active_licenses_info'][ $option_name ] );
1905
	}
1906
1907
	return $data;
1908
}
1909
1910
/**
1911
 * Get add-on user meta value information
1912
 * Note: only for internal use.
1913
 *
1914
 * @since 2.1.0
1915
 *
1916
 * @param string $banner_addon_name Give add-on name.
1917
 *
1918
 * @return array
1919
 */
1920
function __give_get_active_by_user_meta( $banner_addon_name ) {
1921
	global $wpdb;
1922
1923
	// Get the option key.
1924
	$option_name = Give_Addon_Activation_Banner::get_banner_user_meta_key( $banner_addon_name );
1925
	$data        = array();
1926
1927
	if (
1928
		! isset( $GLOBALS['give_addon_activated_by_user'][ $banner_addon_name ] )
1929
		|| empty( $GLOBALS['give_addon_activated_by_user'][ $banner_addon_name ] )
1930
	) {
1931
		$GLOBALS['give_addon_activated_by_user'][ $banner_addon_name ] = array();
1932
1933
		// Get the meta of activation banner by user.
1934
		$activation_banners = $wpdb->get_results(
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
1935
				"
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 12 spaces, but found 16.
Loading history...
1936
					SELECT option_name, option_value
1937
					FROM {$wpdb->options}
1938
					WHERE option_name LIKE '%_active_by_user%'
1939
					AND option_name LIKE '%give_addon%'
1940
					",
1941
			ARRAY_A
1942
		);
1943
1944 View Code Duplication
		if ( ! empty( $activation_banners ) ) {
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...
1945
			$GLOBALS['give_addon_activated_by_user'] = array_combine(
1946
				wp_list_pluck( $activation_banners, 'option_name' ),
1947
				wp_list_pluck( $activation_banners, 'option_value' )
1948
			);
1949
		}
1950
	}
1951
1952 View Code Duplication
	if ( in_array( $option_name, array_keys( $GLOBALS['give_addon_activated_by_user'] ) ) ) {
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...
1953
		$data = maybe_unserialize( $GLOBALS['give_addon_activated_by_user'][ $option_name ] );
1954
	}
1955
1956
	return $data;
1957
}
1958
1959
/**
1960
 * Get time interval for which nonce is valid
1961
 *
1962
 * @since 2.1.3
1963
 *
1964
 * @return int
1965
 */
1966
function give_get_nonce_life(){
1967
	/**
1968
	 * Filters the lifespan of nonces in seconds.
1969
	 *
1970
	 * @see wp-inlucdes/pluggable.php:wp_nonce_tick
1971
	 */
1972
	return (int) apply_filters( 'nonce_life', DAY_IN_SECONDS );
1973
}
1974
1975
/**
1976
 * Get nonce field without id
1977
 *
1978
 * @since 2.1.3
1979
 *
1980
 * @param  string $action
1981
 * @param  string $name
1982
 * @param bool    $referer
1983
 *
1984
 * @return string
1985
 */
1986
function give_get_nonce_field( $action, $name, $referer = false ) {
1987
	return str_replace(
1988
		"id=\"{$name}\"",
1989
		'',
1990
		wp_nonce_field( $action, $name, $referer, false )
1991
	);
1992
}
1993
1994
/**
1995
 * Display/Return a formatted goal for a donation form
1996
 *
1997
 * @param int|Give_Donate_Form $form Form ID or Form Object.
1998
 *
1999
 * @since 2.1
2000
 *
2001
 * @return array
2002
 */
2003
function give_goal_progress_stats( $form ) {
2004
2005
	if ( ! $form instanceof Give_Donate_Form ) {
2006
		$form = new Give_Donate_Form( $form );
2007
	}
2008
2009
	$donors = '';
0 ignored issues
show
Unused Code introduced by
$donors 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...
2010
2011
	$goal_format = give_get_form_goal_format( $form->ID );
2012
2013
	/**
2014
	 * Filter the form.
2015
	 *
2016
	 * @since 1.8.8
2017
	 */
2018
	$total_goal = apply_filters( 'give_goal_amount_target_output', round( give_maybe_sanitize_amount( $form->goal ) ), $form->ID, $form );
2019
2020
	switch ( $goal_format ) {
2021
		case  'donation':
2022
			/**
2023
			 * Filter the form donations.
2024
			 *
2025
			 * @since 2.1
2026
			 */
2027
			$actual = $donations = apply_filters( 'give_goal_donations_raised_output', $form->sales, $form->ID, $form );
0 ignored issues
show
Unused Code introduced by
$donations 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...
2028
			break;
2029
		case 'donors':
2030
			/**
2031
			 * Filter to modify total number if donor for the donation form.
2032
			 *
2033
			 * @since 2.1.3
2034
			 *
2035
			 * @param int $donors Total number of donors that donated to the form.
2036
			 * @param int $form_id Donation Form ID.
2037
			 * @param Give_Donate_Form $form instances of Give_Donate_Form.
2038
			 *
2039
			 * @return int $donors Total number of donors that donated to the form.
2040
			 */
2041
			$actual = $donors = apply_filters( 'give_goal_donors_target_output', give_get_form_donor_count( $form->ID ), $form->ID, $form );
0 ignored issues
show
Unused Code introduced by
$donors 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...
2042
			break;
2043
		default :
2044
			/**
2045
			 * Filter the form income.
2046
			 *
2047
			 * @since 1.8.8
2048
			 */
2049
			$actual = $income = apply_filters( 'give_goal_amount_raised_output', $form->earnings, $form->ID, $form );
0 ignored issues
show
Unused Code introduced by
$income 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...
2050
			break;
2051
	}
2052
2053
	$progress = $total_goal ? round( ( $actual / $total_goal ) * 100, 2 ) : 0;
2054
2055
	$stats_array = array(
2056
		'raw_actual' => $actual,
2057
		'raw_goal'   => $total_goal
0 ignored issues
show
introduced by
Each line in an array declaration must end in a comma
Loading history...
2058
	);
2059
2060
	/**
2061
	 * Filter the goal progress output
2062
	 *
2063
	 * @since 1.8.8
2064
	 */
2065
	$progress = apply_filters( 'give_goal_amount_funded_percentage_output', $progress, $form->ID, $form );
2066
2067
	// Define Actual Goal based on the goal format.
2068 View Code Duplication
	if ( 'percentage' === $goal_format ) {
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...
2069
		$actual = "{$actual}%";
2070
	} else if ( 'amount' === $goal_format ) {
2071
		$actual = give_currency_filter( give_format_amount( $actual ) );
2072
	}
2073
2074
	// Define Total Goal based on the goal format.
2075 View Code Duplication
	if ( 'percentage' === $goal_format ) {
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...
2076
		$total_goal = '';
2077
	} else if ( 'amount' === $goal_format ) {
2078
		$total_goal = give_currency_filter( give_format_amount( $total_goal ) );
2079
	}
2080
2081
	$stats_array = array_merge(
2082
		array(
2083
			'progress'       => $progress,
2084
			'actual'         => $actual,
2085
			'goal'           => $total_goal,
2086
			'format'         => $goal_format,
2087
		),
2088
		$stats_array
2089
	);
2090
2091
	/**
2092
	 * Filter the goal stats
2093
	 *
2094
	 * @since 2.1
2095
	 */
2096
	return apply_filters( 'give_goal_progress_stats', $stats_array );
2097
}
2098
2099
/**
2100
 * Get Name Title Prefixes (a.k.a. Salutation) value.
2101
 *
2102
 * @param int $form_id Donation Form ID.
2103
 *
2104
 * @since 2.2.0
2105
 *
2106
 * @return mixed
2107
 */
2108
function give_get_name_title_prefixes( $form_id = 0 ) {
2109
2110
	$name_title_prefix = give_is_name_title_prefix_enabled( $form_id );
2111
	$title_prefixes    = give_get_option( 'title_prefixes' );
2112
2113
	// If form id exists, then fetch form specific title prefixes.
2114
	if ( intval( $form_id ) > 0 && $name_title_prefix ) {
2115
2116
		$form_title_prefix = give_get_meta( $form_id, '_give_name_title_prefix', true );
2117
		if ( 'global' !== $form_title_prefix ) {
2118
			$form_title_prefixes = give_get_meta( $form_id, '_give_title_prefixes', true );
2119
2120
			// Check whether the form based title prefixes exists or not.
2121
			if ( is_array( $form_title_prefixes ) && count( $form_title_prefixes ) > 0 ) {
2122
				$title_prefixes = $form_title_prefixes;
2123
			}
2124
		}
2125
	}
2126
2127
	return $title_prefixes;
2128
}
2129
2130
/**
2131
 * Check whether the name title prefix is enabled or not.
2132
 *
2133
 * @param int    $form_id Donation Form ID.
2134
 * @param string $status  Status to set status based on option value.
2135
 *
2136
 * @since 2.2.0
2137
 *
2138
 * @return bool
2139
 */
2140
function give_is_name_title_prefix_enabled( $form_id = 0, $status = '' ) {
2141
	if ( empty( $status ) ) {
2142
		$status = array( 'required', 'optional' );
2143
	} else {
2144
		$status = array( $status );
2145
	}
2146
2147
	$title_prefix_status = give_is_setting_enabled( give_get_option( 'name_title_prefix' ), $status );
0 ignored issues
show
Documentation introduced by
$status is of type array<integer,string,{"0":"string"}>, but the function expects a string|null.

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...
2148
2149
	if ( intval( $form_id ) > 0 ) {
2150
		$form_title_prefix = give_get_meta( $form_id, '_give_name_title_prefix', true );
2151
2152
		if ( 'disabled' === $form_title_prefix ) {
2153
			$title_prefix_status = false;
2154
		} elseif ( in_array( $form_title_prefix, $status, true ) ) {
2155
			$title_prefix_status = give_is_setting_enabled( $form_title_prefix, $status );
0 ignored issues
show
Documentation introduced by
$status is of type array<integer,string,{"0":"string"}>, but the function expects a string|null.

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...
2156
		}
2157
	}
2158
2159
	return $title_prefix_status;
2160
2161
}
2162
2163
/**
2164
 * Get Donor Name with Title Prefix
2165
 *
2166
 * @param int|Give_Donor $donor Donor Information.
2167
 *
2168
 * @since 2.2.0
2169
 *
2170
 * @return object
2171
 */
2172
function give_get_name_with_title_prefixes( $donor ) {
2173
2174
	// Prepare Give_Donor object, if $donor is numeric.
2175
	if ( is_numeric( $donor ) ) {
2176
		$donor = new Give_Donor( $donor );
2177
	}
2178
2179
	$title_prefix = Give()->donor_meta->get_meta( $donor->id, '_give_donor_title_prefix', true );
2180
2181
	// Update Donor name, if non empty title prefix.
2182
	if ( ! empty( $title_prefix ) ) {
2183
		$donor->name = give_get_donor_name_with_title_prefixes( $title_prefix, $donor->name );
2184
	}
2185
2186
	return $donor;
2187
}
2188
2189
/**
2190
 * This function will generate donor name with title prefix if it is required.
2191
 *
2192
 * @param string $title_prefix Title Prefix of Donor
2193
 * @param string $name         Donor Name.
2194
 *
2195
 * @since 2.2.0
2196
 *
2197
 * @return string
2198
 */
2199
function give_get_donor_name_with_title_prefixes( $title_prefix, $name ) {
2200
2201
	$donor_name = $name;
2202
2203
	if ( ! empty( $title_prefix ) && ! empty( $name ) ) {
2204
		$donor_name = "{$title_prefix} {$name}";
2205
	}
2206
2207
	return trim( $donor_name );
2208
}
2209
2210
/**
2211
 * This function will fetch the default list of title prefixes.
2212
 *
2213
 * @since 2.2.0
2214
 *
2215
 * @return array
2216
 */
2217
function give_get_default_title_prefixes() {
2218
	/**
2219
	 * Filter the data
2220
	 * Set default title prefixes.
2221
	 *
2222
	 * @since 2.2.0
2223
	 */
2224
	return apply_filters(
2225
		'give_get_default_title_prefixes',
2226
		array(
2227
			'Mr.'  => __( 'Mr.', 'give' ),
2228
			'Mrs.' => __( 'Mrs.', 'give' ),
2229
			'Ms.'  => __( 'Ms.', 'give' ),
2230
		)
2231
	);
2232
}
2233
2234
/**
2235
 * This function will check whether the name title prefix field is required or not.
2236
 *
2237
 * @param int $form_id Donation Form ID.
2238
 *
2239
 * @since 2.2.0
2240
 *
2241
 * @return bool
2242
 */
2243
function give_is_name_title_prefix_required( $form_id = 0 ) {
2244
2245
	// Bail out, if name title prefix is not enabled.
2246
	if ( ! give_is_name_title_prefix_enabled( $form_id ) ) {
2247
		return false;
2248
	}
2249
2250
	$status      = array( 'optional' );
2251
	$is_optional = give_is_setting_enabled( give_get_option( 'name_title_prefix' ), $status );
0 ignored issues
show
Documentation introduced by
$status is of type array<integer,string,{"0":"string"}>, but the function expects a string|null.

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...
2252
2253
	if ( intval( $form_id ) > 0 ) {
2254
		$form_title_prefix = give_get_meta( $form_id, '_give_name_title_prefix', true );
2255
2256
		if ( 'required' === $form_title_prefix ) {
2257
			$is_optional = false;
2258
		} elseif ( 'optional' === $form_title_prefix ) {
2259
			$is_optional = true;
2260
		}
2261
	}
2262
2263
	return ( ! $is_optional );
2264
}
2265
2266
/**
2267
 * Get the admin messages key to show the notices.
2268
 *
2269
 * @since 2.1.4
2270
 *
2271
 * @return array $message admin message key.
2272
 */
2273
function give_get_admin_messages_key() {
2274
	$messages = empty( $_GET['give-messages'] ) ? array() : give_clean( $_GET['give-messages'] );
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...
2275
2276
	// backward compatibility.
2277
	if ( ! empty( $_GET['give-message'] ) ) {
2278
		$messages[] = give_clean( $_GET['give-message'] );
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...
2279
	}
2280
2281
	/**
2282
	 * Filter to modify the admin messages key.
2283
	 *
2284
	 * @since 2.1.4
2285
	 *
2286
	 * @param array $message admin message key.
2287
	 *
2288
	 * @return array $message admin message key.
2289
	 */
2290
	return (array) apply_filters( 'give_get_admin_messages_key', $messages );
2291
}
2292
2293
/**
2294
 * Get User Agent String.
2295
 *
2296
 * @since 2.1.4
2297
 *
2298
 * @return array|string
2299
 */
2300
function give_get_user_agent() {
2301
2302
	// Get User Agent.
2303
	$user_agent = ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? give_clean( $_SERVER['HTTP_USER_AGENT'] ) : ''; // WPCS: input var ok.
0 ignored issues
show
introduced by
Due to using Batcache, server side based client related logic will not work, use JS instead.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
2304
2305
	return $user_agent;
2306
}
2307
2308
/**
2309
 * Set a cookie - wrapper for setcookie using WP constants.
2310
 *
2311
 * @since 2.2.0
2312
 *
2313
 * @param  string  $name   Name of the cookie being set.
2314
 * @param  string  $value  Value of the cookie.
2315
 * @param  integer $expire Expiry of the cookie.
2316
 * @param  bool    $secure Whether the cookie should be served only over https.
2317
 */
2318
function give_setcookie( $name, $value, $expire = 0, $secure = false ) {
2319
	if ( ! headers_sent() ) {
2320
		setcookie(
0 ignored issues
show
introduced by
Due to using Batcache, server side based client related logic will not work, use JS instead.
Loading history...
2321
			$name,$value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure,
2322
			apply_filters( 'give_cookie_httponly', false, $name, $value, $expire, $secure )
2323
		);
2324
	}
2325
}
2326
2327
/**
2328
 * Get formatted billing address.
2329
 *
2330
 * @since 2.2.0
2331
 *
2332
 * @param array $address
2333
 *
2334
 * @return string Formatted address.
2335
 */
2336
function give_get_formatted_address( $address = array() ) {
2337
	$formatted_address = '';
2338
2339
	/**
2340
	 * Address format.
2341
	 *
2342
	 * @since 2.2.0
2343
	 */
2344
	$address_format = apply_filters( 'give_address_format_template', "{street_address}\n{city}, {state} {postal_code}\n{country}" );
2345
	preg_match_all( "/{([A-z0-9\-\_\ ]+)}/s", $address_format, $matches );
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal /{([A-z0-9\-\_\ ]+)}/s does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
2346
2347
	if( ! empty( $matches ) && ! empty( $address ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
2348
		$address_values = array();
2349
2350
		foreach ($matches[1] as $address_tag ) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
2351
			$address_values[ $address_tag ] = '';
2352
2353
			if( isset( $address[$address_tag] ) ) {
0 ignored issues
show
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
2354
				$address_values[ $address_tag ] = $address[$address_tag];
0 ignored issues
show
introduced by
Array keys should be surrounded by spaces unless they contain a string or an integer.
Loading history...
2355
			}
2356
		}
2357
2358
		$formatted_address  = str_ireplace( $matches[0], $address_values, $address_format );
2359
	}
2360
2361
	/**
2362
	 * Give get formatted address.
2363
	 *
2364
	 * @since 2.2.0
2365
	 *
2366
	 * @param string $formatted_address Formatted address.
2367
	 * @param string $address_format    Format of the address.
2368
	 */
2369
	$formatted_address = apply_filters( 'give_get_formatted_address', $formatted_address, $address_format, $address );
2370
2371
	return $formatted_address;
2372
}
2373
2374
/**
2375
 * Converts a PHP date format for use in JavaScript.
2376
 *
2377
 * @since 2.2.0
2378
 *
2379
 * @param string $php_format The PHP date format.
2380
 *
2381
 * @return string The JS date format.
2382
 */
2383
function give_convert_php_date_format_to_js( $php_format ) {
2384
	$js_format = $php_format;
2385
2386
	switch ( $php_format ) {
2387
		case 'F j, Y':
2388
			$js_format = 'MM dd, yy';
2389
			break;
2390
		case 'Y-m-d':
2391
			$js_format = 'yy-mm-dd';
2392
			break;
2393
		case 'm/d/Y':
2394
			$js_format = 'mm/dd/yy';
2395
			break;
2396
		case 'd/m/Y':
2397
			$js_format = 'dd/mm/yy';
2398
			break;
2399
	}
2400
2401
	/**
2402
	 * Filters the date format for use in JavaScript.
2403
	 *
2404
	 * @since 2.2.0
2405
	 *
2406
	 * @param string $js_format  The JS date format.
2407
	 * @param string $php_format The PHP date format.
2408
	 */
2409
	$js_format = apply_filters( 'give_js_date_format', $js_format, $php_format );
2410
2411
	return $js_format;
2412
}
2413
2414
/**
2415
 * Get localized date format for use in JavaScript.
2416
 *
2417
 * @since 2.2.0
2418
 *
2419
 * @return string.
0 ignored issues
show
Documentation introduced by
The doc-type string. could not be parsed: Unknown type name "string." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
2420
 */
2421
function give_get_localized_date_format_to_js() {
2422
2423
	return give_convert_php_date_format_to_js( get_option( 'date_format' ) );
2424
}
2425
2426
/**
2427
 * Get safe url for assets
2428
 * Note: this function will return url without http protocol
2429
 *
2430
 * @since 2.2.0
2431
 *
2432
 * @param string $url URL
2433
 *
2434
 * @return string
2435
 */
2436
function give_get_safe_asset_url( $url ) {
2437
2438
	// Bailout, if empty URL passed.
2439
	if ( empty( $url ) ) {
2440
		return $url;
2441
	}
2442
2443
	$schema = parse_url( $url, PHP_URL_SCHEME );
2444
	$schema_length = strlen( $schema ) + 1;
2445
	$url = substr( $url, $schema_length );
2446
2447
	return $url;
2448
}
2449