Test Failed
Pull Request — master (#3324)
by Devin
07:59
created

misc-functions.php ➔ give_get_admin_messages_key()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 19
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 4
nop 0
dl 0
loc 19
ccs 0
cts 0
cp 0
crap 12
rs 9.4285
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, ',' ) ) {
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...
174
		$ip = give_clean( explode( ',', $ip ) );
175
		$ip = array_filter( $ip );
176
		$ip = implode( ',', $ip );
177
	} 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...
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 (
265
			'custom' !== $price_id
266
			&& ! empty( $item_price_level_text )
267
		) {
268
			// Matches a donation level - append level text.
269
			$item_name .= ' - ' . $item_price_level_text;
270
		}
271
	}
272
273
	/**
274
	 * Filter the Item Title of Payment Gateway.
275
	 *
276
	 * @param string $item_name    Item Title of Payment Gateway.
277
	 * @param int    $form_id      Donation Form ID.
278
	 * @param array  $payment_data Payment Data.
279
	 *
280
	 * @since 1.8.14
281
	 *
282
	 * @return string
283
	 */
284
	return apply_filters( 'give_payment_gateway_item_title', $item_name, $form_id, $payment_data );
285
}
286
287
/**
288
 * Get Donation Summary
289
 *
290
 * Creates a donation summary for payment gateways from the donation data before the payment is created in the database.
291
 *
292
 * @since       1.8.12
293
 *
294
 * @param array $donation_data
295
 * @param bool  $name_and_email
296
 * @param int   $length
297
 *
298
 * @return string
299
 */
300 52
function give_payment_gateway_donation_summary( $donation_data, $name_and_email = true, $length = 255 ) {
301
302 52
	$form_id  = isset( $donation_data['post_data']['give-form-id'] ) ? $donation_data['post_data']['give-form-id'] : '';
303
	$price_id = isset( $donation_data['post_data']['give-price-id'] ) ? $donation_data['post_data']['give-price-id'] : '';
304
305 52
	// Form title.
306
	$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' ) ) );
307
308 52
	// Form multilevel if applicable.
309 52
	if ( ! empty( $price_id ) && 'custom' !== $price_id ) {
310 52
		$summary .= ': ' . give_get_price_option_name( $form_id, $donation_data['post_data']['give-price-id'] );
311
	}
312 52
313
	// Add Donor's name + email if requested.
314
	if ( $name_and_email ) {
315
316
		// First name
317 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...
318
			$summary .= ' - ' . $donation_data['user_info']['first_name'];
319
		}
320
321 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...
322
			$summary .= ' ' . $donation_data['user_info']['last_name'];
323
		}
324
325
		$summary .= ' (' . $donation_data['user_email'] . ')';
326
	}
327
328
	// Cut the length
329
	$summary = substr( $summary, 0, $length );
330
331
	return apply_filters( 'give_payment_gateway_donation_summary', $summary );
332
}
333
334
335
/**
336
 * Get user host
337
 *
338
 * Returns the webhost this site is using if possible
339
 *
340
 * @since 1.0
341
 * @return string $host if detected, false otherwise
342
 */
343
function give_get_host() {
344
	$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...
345
346
	if ( defined( 'WPE_APIKEY' ) ) {
347
		$host = 'WP Engine';
348
	} elseif ( defined( 'PAGELYBIN' ) ) {
349
		$host = 'Pagely';
350
	} elseif ( DB_HOST == 'localhost:/tmp/mysql5.sock' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
351
		$host = 'ICDSoft';
352
	} elseif ( DB_HOST == 'mysqlv5' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
353
		$host = 'NetworkSolutions';
354
	} elseif ( strpos( DB_HOST, 'ipagemysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
355
		$host = 'iPage';
356
	} elseif ( strpos( DB_HOST, 'ipowermysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
357
		$host = 'IPower';
358
	} elseif ( strpos( DB_HOST, '.gridserver.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
359
		$host = 'MediaTemple Grid';
360
	} elseif ( strpos( DB_HOST, '.pair.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
361
		$host = 'pair Networks';
362
	} elseif ( strpos( DB_HOST, '.stabletransit.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
363
		$host = 'Rackspace Cloud';
364
	} elseif ( strpos( DB_HOST, '.sysfix.eu' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
365
		$host = 'SysFix.eu Power Hosting';
366
	} elseif ( strpos( $_SERVER['SERVER_NAME'], 'Flywheel' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
367
		$host = 'Flywheel';
368
	} else {
369
		// Adding a general fallback for data gathering
370
		$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...
371
	}
372
373
	return $host;
374
}
375
376
377
/**
378
 * Check site host
379
 *
380
 * @since 1.0
381
 *
382
 * @param bool /string $host The host to check
383
 *
384
 * @return bool true if host matches, false if not
385
 */
386
function give_is_host( $host = false ) {
387
388
	$return = false;
389
390
	if ( $host ) {
391
		$host = str_replace( ' ', '', strtolower( $host ) );
392
393
		switch ( $host ) {
394
			case 'wpengine':
395
				if ( defined( 'WPE_APIKEY' ) ) {
396
					$return = true;
397
				}
398
				break;
399
			case 'pagely':
400
				if ( defined( 'PAGELYBIN' ) ) {
401
					$return = true;
402
				}
403
				break;
404
			case 'icdsoft':
405
				if ( DB_HOST == 'localhost:/tmp/mysql5.sock' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
406
					$return = true;
407
				}
408
				break;
409
			case 'networksolutions':
410
				if ( DB_HOST == 'mysqlv5' ) {
0 ignored issues
show
introduced by
Found "== '". Use Yoda Condition checks, you must
Loading history...
411
					$return = true;
412
				}
413
				break;
414
			case 'ipage':
415
				if ( strpos( DB_HOST, 'ipagemysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
416
					$return = true;
417
				}
418
				break;
419
			case 'ipower':
420
				if ( strpos( DB_HOST, 'ipowermysql.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
421
					$return = true;
422
				}
423
				break;
424
			case 'mediatemplegrid':
425
				if ( strpos( DB_HOST, '.gridserver.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
426
					$return = true;
427
				}
428
				break;
429
			case 'pairnetworks':
430
				if ( strpos( DB_HOST, '.pair.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
431
					$return = true;
432
				}
433
				break;
434
			case 'rackspacecloud':
435
				if ( strpos( DB_HOST, '.stabletransit.com' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
436
					$return = true;
437
				}
438
				break;
439
			case 'sysfix.eu':
440
			case 'sysfix.eupowerhosting':
441
				if ( strpos( DB_HOST, '.sysfix.eu' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
442
					$return = true;
443
				}
444
				break;
445
			case 'flywheel':
446
				if ( strpos( $_SERVER['SERVER_NAME'], 'Flywheel' ) !== false ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
447
					$return = true;
448
				}
449
				break;
450
			default:
451
				$return = false;
452
		}// End switch().
453
	}// End if().
454
455
	return $return;
456
}
457
458
/**
459
 * Marks a function as deprecated and informs when it has been used.
460
 *
461
 * There is a hook give_deprecated_function_run that will be called that can be used
462
 * to get the backtrace up to what file and function called the deprecated
463
 * function.
464
 *
465
 * The current behavior is to trigger a user error if WP_DEBUG is true.
466
 *
467
 * This function is to be used in every function that is deprecated.
468
 *
469
 * @uses do_action() Calls 'give_deprecated_function_run' and passes the function name, what to use instead,
470
 *   and the version the function was deprecated in.
471
 * @uses apply_filters() Calls 'give_deprecated_function_trigger_error' and expects boolean value of true to do
472
 *   trigger or false to not trigger error.
473
 *
474
 * @param string $function    The function that was called.
475
 * @param string $version     The plugin version that deprecated the function.
476
 * @param string $replacement Optional. The function that should have been called.
477
 * @param array  $backtrace   Optional. Contains stack backtrace of deprecated function.
478
 */
479
function _give_deprecated_function( $function, $version, $replacement = null, $backtrace = null ) {
480
481
	/**
482
	 * Fires while give deprecated function call occurs.
483
	 *
484
	 * Allow you to hook to deprecated function call.
485
	 *
486
	 * @since 1.0
487
	 *
488
	 * @param string $function    The function that was called.
489
	 * @param string $replacement Optional. The function that should have been called.
490
	 * @param string $version     The plugin version that deprecated the function.
491
	 */
492
	do_action( 'give_deprecated_function_run', $function, $replacement, $version );
493
494
	$show_errors = current_user_can( 'manage_options' );
495
496
	// Allow plugin to filter the output error trigger.
497
	if ( WP_DEBUG && apply_filters( 'give_deprecated_function_trigger_error', $show_errors ) ) {
498
		if ( ! is_null( $replacement ) ) {
499
			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Give version %2$s! Use %3$s instead.', 'give' ), $function, $version, $replacement ) );
500
			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...
501
			// Alternatively we could dump this to a file.
502
		} else {
503
			trigger_error( sprintf( __( '%1$s is <strong>deprecated</strong> since Give version %2$s with no alternative available.', 'give' ), $function, $version ) );
504
			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...
505
			// Alternatively we could dump this to a file.
506
		}
507
	}
508
}
509
510
/**
511
 * Give Get Admin ID
512
 *
513
 * Helper function to return the ID of the post for admin usage
514
 *
515
 * @return string $post_id
516 1
 */
517
function give_get_admin_post_id() {
518 1
	$post_id = isset( $_REQUEST['post'] )
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
519
		? absint( $_REQUEST['post'] )
0 ignored issues
show
introduced by
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
520
		: null;
521 1
522
	$post_id = ! empty( $post_id )
523
		? $post_id
524
		: ( 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...
525
526
	$post_id = ! empty( $post_id )
527
		? $post_id
528
		: ( 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...
529
530
	return $post_id;
531
}
532 1
533
/**
534
 * Get PHP Arg Separator Output
535
 *
536
 * @since 1.0
537
 * @return string Arg separator output
538
 */
539
function give_get_php_arg_separator_output() {
540
	return ini_get( 'arg_separator.output' );
541
}
542
543
544
/**
545
 * Month Num To Name
546
 *
547
 * Takes a month number and returns the name three letter name of it.
548
 *
549
 * @since 1.0
550
 *
551
 * @param int $n
552
 *
553
 * @return string Short month name
554
 */
555
function give_month_num_to_name( $n ) {
556
	$timestamp = mktime( 0, 0, 0, $n, 1, 2005 );
557
558
	return date_i18n( 'M', $timestamp );
559
}
560
561
562
/**
563
 * Checks whether function is disabled.
564
 *
565
 * @since 1.0
566
 *
567
 * @param string $function Name of the function.
568
 *
569
 * @return bool Whether or not function is disabled.
570
 */
571
function give_is_func_disabled( $function ) {
572
	$disabled = explode( ',', ini_get( 'disable_functions' ) );
573
574
	return in_array( $function, $disabled );
575
}
576
577
578
/**
579
 * Give Newsletter
580
 *
581
 * Returns the main Give newsletter form
582
 */
583
function give_get_newsletter() {
584
	?>
585
586
	<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>
587
588
	<div class="give-newsletter-form-wrap">
589
590
		<form action="//givewp.us3.list-manage.com/subscribe/post?u=3ccb75d68bda4381e2f45794c&amp;id=12a081aa13"
591
		      method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate"
592
		      target="_blank" novalidate>
593
			<div class="give-newsletter-confirmation">
594
				<p><?php esc_html_e( 'Thanks for Subscribing!', 'give' ); ?> :)</p>
595
			</div>
596
597
			<table class="form-table give-newsletter-form">
598
				<tr valign="middle">
599
					<td>
600
						<label for="mce-EMAIL"
601
						       class="screen-reader-text"><?php esc_html_e( 'Email Address (required)', 'give' ); ?></label>
602
						<input type="email" name="EMAIL" id="mce-EMAIL"
603
						       placeholder="<?php esc_attr_e( 'Email Address (required)', 'give' ); ?>"
604
						       class="required email" value="">
605
					</td>
606
					<td>
607
						<label for="mce-FNAME"
608
						       class="screen-reader-text"><?php esc_html_e( 'First Name', 'give' ); ?></label>
609
						<input type="text" name="FNAME" id="mce-FNAME"
610
						       placeholder="<?php esc_attr_e( 'First Name', 'give' ); ?>" class="" value="">
611
					</td>
612
					<td>
613
						<label for="mce-LNAME"
614
						       class="screen-reader-text"><?php esc_html_e( 'Last Name', 'give' ); ?></label>
615
						<input type="text" name="LNAME" id="mce-LNAME"
616
						       placeholder="<?php esc_attr_e( 'Last Name', 'give' ); ?>" class="" value="">
617
					</td>
618
					<td>
619
						<input type="submit" name="subscribe" id="mc-embedded-subscribe" class="button"
620
						       value="<?php esc_attr_e( 'Subscribe', 'give' ); ?>">
621
					</td>
622
				</tr>
623
			</table>
624
		</form>
625
626
		<div style="position: absolute; left: -5000px;">
627
			<input type="text" name="b_3ccb75d68bda4381e2f45794c_12a081aa13" tabindex="-1" value="">
628
		</div>
629
630
	</div>
631
632
	<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...
633
	<script type='text/javascript'>(function( $ ) {
634
			window.fnames = new Array();
635
			window.ftypes = new Array();
636
			fnames[ 0 ] = 'EMAIL';
637
			ftypes[ 0 ] = 'email';
638
			fnames[ 1 ] = 'FNAME';
639
			ftypes[ 1 ] = 'text';
640
			fnames[ 2 ] = 'LNAME';
641
			ftypes[ 2 ] = 'text';
642
643
			//Successful submission
644
			$( 'form[name="mc-embedded-subscribe-form"]' ).on( 'submit', function() {
645
646
				var email_field = $( this ).find( '#mce-EMAIL' ).val();
647
				if ( ! email_field ) {
648
					return false;
649
				}
650
				$( this ).find( '.give-newsletter-confirmation' ).show().delay( 5000 ).slideUp();
651
				$( this ).find( '.give-newsletter-form' ).hide();
652
653
			} );
654
655
		}( jQuery ));
656
		var $mcj = jQuery.noConflict( true );
657
658
659
	</script>
660
	<!--End mc_embed_signup-->
661
662
	<?php
663
}
664
665
666
/**
667
 * Create SVG library function
668
 *
669
 * @param string $icon
670
 *
671
 * @return string
672
 */
673
function give_svg_icons( $icon ) {
674
675
	// Store your SVGs in an associative array
676
	$svgs = array(
677
		'microphone'    => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjY0cHgiIGhlaWdodD0iMTAwcHgiIHZpZXdCb3g9IjAgLTIwIDY0IDEyMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNjQgMTAwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8Zz4NCgk8Zz4NCgkJPHBhdGggZD0iTTYyLDM2LjIxNWgtM2MtMS4xLDAtMiwwLjktMiwyVjUyYzAsNi42ODYtNS4yNjYsMTgtMjUsMThTNyw1OC42ODYsNyw1MlYzOC4yMTVjMC0xLjEtMC45LTItMi0ySDJjLTEuMSwwLTIsMC45LTIsMlY1Mg0KCQkJYzAsMTEuMTg0LDguMjE1LDIzLjE1MiwyNywyNC44MDFWOTBIMTRjLTEuMSwwLTIsMC44OTgtMiwydjZjMCwxLjEsMC45LDIsMiwyaDM2YzEuMSwwLDItMC45LDItMnYtNmMwLTEuMTAyLTAuOS0yLTItMkgzN1Y3Ni44MDENCgkJCUM1NS43ODUsNzUuMTUyLDY0LDYzLjE4NCw2NCw1MlYzOC4yMTVDNjQsMzcuMTE1LDYzLjEsMzYuMjE1LDYyLDM2LjIxNXoiLz4NCgkJPHBhdGggZD0iTTMyLDYwYzExLjczMiwwLDE1LTQuODE4LDE1LThWMzYuMjE1SDE3VjUyQzE3LDU1LjE4MiwyMC4yNjYsNjAsMzIsNjB6Ii8+DQoJCTxwYXRoIGQ9Ik00Nyw4YzAtMy4xODQtMy4yNjgtOC0xNS04QzIwLjI2NiwwLDE3LDQuODE2LDE3LDh2MjEuMjE1aDMwVjh6Ii8+DQoJPC9nPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPC9zdmc+DQo=',
678
		'alert'         => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pg0KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE2LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPg0KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCINCgkgd2lkdGg9IjI4LjkzOHB4IiBoZWlnaHQ9IjI1LjAwNXB4IiB2aWV3Qm94PSIwIDAgMjguOTM4IDI1LjAwNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMjguOTM4IDI1LjAwNTsiDQoJIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggc3R5bGU9ImZpbGw6IzAwMDAwMDsiIGQ9Ik0yOC44NTksMjQuMTU4TDE0Ljk1NywwLjI3OUMxNC44NTYsMC4xMDYsMTQuNjcsMCwxNC40NjgsMGMtMC4xOTgsMC0wLjM4MywwLjEwNi0wLjQ4MSwwLjI3OQ0KCUwwLjA3OSwyNC4xNThjLTAuMTAyLDAuMTc1LTAuMTA2LDAuMzg5LTAuMDA2LDAuNTY1YzAuMTAzLDAuMTc0LDAuMjg3LDAuMjgyLDAuNDg4LDAuMjgyaDI3LjgxNGMwLjIwMSwwLDAuMzg5LTAuMTA4LDAuNDg4LTAuMjgyDQoJYzAuMDQ3LTAuMDg4LDAuMDc0LTAuMTg2LDAuMDc0LTAuMjgxQzI4LjkzOCwyNC4zNDMsMjguOTExLDI0LjI0NSwyOC44NTksMjQuMTU4eiBNMTYuMzY5LDguNDc1bC0wLjQ2Miw5LjQ5M2gtMi4zODlsLTAuNDYxLTkuNDkzDQoJSDE2LjM2OXogTTE0LjcxMSwyMi44MjhoLTAuMDQyYy0xLjA4OSwwLTEuODQzLTAuODE3LTEuODQzLTEuOTA3YzAtMS4xMzEsMC43NzQtMS45MDcsMS44ODUtMS45MDdzMS44NDYsMC43NzUsMS44NjcsMS45MDcNCglDMTYuNTc5LDIyLjAxMSwxNS44NDQsMjIuODI4LDE0LjcxMSwyMi44Mjh6Ii8+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8Zz4NCjwvZz4NCjxnPg0KPC9nPg0KPGc+DQo8L2c+DQo8L3N2Zz4NCg==',
679
		'placemark'     => 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iMTAwcHgiIGhlaWdodD0iMTAwcHgiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik01MC40MzQsMjAuMjcxYy0xMi40OTksMC0yMi42NjgsMTAuMTY5LTIyLjY2OCwyMi42NjhjMCwxMS44MTQsMTguODE1LDMyLjE1NSwyMC45NiwzNC40MzdsMS43MDgsMS44MTZsMS43MDgtMS44MTYNCgkJYzIuMTQ1LTIuMjgxLDIwLjk2LTIyLjYyMywyMC45Ni0zNC40MzdDNzMuMTAzLDMwLjQ0LDYyLjkzNCwyMC4yNzEsNTAuNDM0LDIwLjI3MXogTTUwLjQzNCw1Mi4zMmMtNS4xNzIsMC05LjM4LTQuMjA4LTkuMzgtOS4zOA0KCQlzNC4yMDgtOS4zOCw5LjM4LTkuMzhjNS4xNzMsMCw5LjM4LDQuMjA4LDkuMzgsOS4zOFM1NS42MDcsNTIuMzIsNTAuNDM0LDUyLjMyeiIvPg0KPC9nPg0KPC9zdmc+DQo=',
680
		'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==',
681
		'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',
682
	);
683
684
	// Return the chosen icon's SVG string
685
	return $svgs[ $icon ];
686
}
687
688
/**
689
 * Modify Admin Nav Menu Label
690
 *
691
 * @since 1.3
692
 *
693
 * @param object $post_type The current object to add a menu items meta box for.
694
 *
695
 * @return mixed
696
 */
697
function modify_nav_menu_meta_box_object( $post_type ) {
698
	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...
699
		$post_type->labels->name = esc_html__( 'Donation Forms', 'give' );
700
	}
701
702
	return $post_type;
703
}
704
705
add_filter( 'nav_menu_meta_box_object', 'modify_nav_menu_meta_box_object' );
706
707
/**
708
 * Show Donation Forms Post Type in Appearance > Menus by default on fresh install.
709
 *
710
 * @since 1.8.14
711
 *
712
 * @todo  Remove this, when WordPress Core ticket is resolved (https://core.trac.wordpress.org/ticket/16828).
713
 *
714
 * @return bool
715
 */
716
function give_donation_metabox_menu() {
717
718
	// Get Current Screen.
719
	$screen = get_current_screen();
720
721
	// Proceed, if current screen is navigation menus.
722
	if (
723
		'nav-menus' === $screen->id &&
724
		give_is_setting_enabled( give_get_option( 'forms_singular' ) ) &&
725
		! get_user_option( 'give_is_donation_forms_menu_updated' )
726
	) {
727
728
		// Return false, if it fails to retrieve hidden meta box list and is not admin.
729
		if (
730
			! is_admin() ||
731
			( ! $hidden_meta_boxes = get_user_option( 'metaboxhidden_nav-menus' ) )
732
		) {
733
			return false;
734
		}
735
736
		// Return false, In case, we don't find 'Donation Form' in hidden meta box list.
737
		if ( ! in_array( 'add-post-type-give_forms', $hidden_meta_boxes, true ) ) {
738
			return false;
739
		}
740
741
		// Exclude 'Donation Form' value from hidden meta box's list.
742
		$hidden_meta_boxes = array_diff( $hidden_meta_boxes, array( 'add-post-type-give_forms' ) );
743
744
		// Get current user ID.
745
		$user = wp_get_current_user();
746
747
		update_user_option( $user->ID, 'metaboxhidden_nav-menus', $hidden_meta_boxes, true );
748
		update_user_option( $user->ID, 'give_is_donation_forms_menu_updated', true, true );
749
	}
750
}
751
752
add_action( 'current_screen', 'give_donation_metabox_menu' );
753
754
/**
755
 * Array_column backup usage
756
 *
757
 * This file is part of the array_column library.
758
 *
759
 * @since      : 1.3.0.1
760
 *
761
 * @copyright  Copyright (c) Ben Ramsey (http://benramsey.com)
762
 * @license    https://opensource.org/licenses/MIT MIT
763
 */
764
765
if ( ! function_exists( 'array_column' ) ) {
766
	/**
767
	 * Returns the values from a single column of the input array, identified by
768
	 * the $columnKey.
769
	 *
770
	 * Optionally, you may provide an $indexKey to index the values in the returned
771
	 * array by the values from the $indexKey column in the input array.
772
	 *
773
	 * @param array      $input     A multi-dimensional array (record set) from which to pull
774
	 *                              a column of values.
775
	 * @param int|string $columnKey The column of values to return. This value may be the
776
	 *                              integer key of the column you wish to retrieve, or it
777
	 *                              may be the string key name for an associative array.
778
	 * @param mixed      $indexKey  (Optional.) The column to use as the index/keys for
779
	 *                              the returned array. This value may be the integer key
780
	 *                              of the column, or it may be the string key name.
781
	 *
782
	 * @return array
783
	 */
784
	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...
785
		// Using func_get_args() in order to check for proper number of
786
		// parameters and trigger errors exactly as the built-in array_column()
787
		// does in PHP 5.5.
788
		$argc   = func_num_args();
789
		$params = func_get_args();
790
791
		if ( $argc < 2 ) {
792
			trigger_error( sprintf( esc_html__( 'array_column() expects at least 2 parameters, %s given.', 'give' ), $argc ), E_USER_WARNING );
793
794
			return null;
795
		}
796
797
		if ( ! is_array( $params[0] ) ) {
798
			trigger_error( sprintf( esc_html__( 'array_column() expects parameter 1 to be array, %s given.', 'give' ), gettype( $params[0] ) ), E_USER_WARNING );
799
800
			return null;
801
		}
802
803 View Code Duplication
		if ( ! is_int( $params[1] )
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
804
		     && ! is_float( $params[1] )
805
		     && ! is_string( $params[1] )
806
		     && $params[1] !== null
807
		     && ! ( is_object( $params[1] ) && method_exists( $params[1], '__toString' ) )
808
		) {
809
			trigger_error( esc_html__( 'array_column(): The column key should be either a string or an integer.', 'give' ), E_USER_WARNING );
810
811
			return false;
812
		}
813
814 View Code Duplication
		if ( isset( $params[2] )
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
815
		     && ! is_int( $params[2] )
816
		     && ! is_float( $params[2] )
817
		     && ! is_string( $params[2] )
818
		     && ! ( is_object( $params[2] ) && method_exists( $params[2], '__toString' ) )
819
		) {
820
			trigger_error( esc_html__( 'array_column(): The index key should be either a string or an integer.', 'give' ), E_USER_WARNING );
821
822
			return false;
823
		}
824
825
		$paramsInput     = $params[0];
826
		$paramsColumnKey = ( $params[1] !== null ) ? (string) $params[1] : null;
827
828
		$paramsIndexKey = null;
829
		if ( isset( $params[2] ) ) {
830
			if ( is_float( $params[2] ) || is_int( $params[2] ) ) {
831
				$paramsIndexKey = (int) $params[2];
832
			} else {
833
				$paramsIndexKey = (string) $params[2];
834
			}
835
		}
836
837
		$resultArray = array();
838
839
		foreach ( $paramsInput as $row ) {
840
			$key    = $value = null;
841
			$keySet = $valueSet = false;
842
843
			if ( $paramsIndexKey !== null && array_key_exists( $paramsIndexKey, $row ) ) {
844
				$keySet = true;
845
				$key    = (string) $row[ $paramsIndexKey ];
846
			}
847
848
			if ( $paramsColumnKey === null ) {
849
				$valueSet = true;
850
				$value    = $row;
851
			} elseif ( is_array( $row ) && array_key_exists( $paramsColumnKey, $row ) ) {
852
				$valueSet = true;
853
				$value    = $row[ $paramsColumnKey ];
854
			}
855
856
			if ( $valueSet ) {
857
				if ( $keySet ) {
858
					$resultArray[ $key ] = $value;
859
				} else {
860
					$resultArray[] = $value;
861
				}
862
			}
863
		}
864
865
		return $resultArray;
866
	}
867
}// End if().
868
869
/**
870
 * Determines the receipt visibility status.
871
 *
872
 * @since 1.3.2
873
 *
874
 * @param string $payment_key
875
 *
876
 * @return bool Whether the receipt is visible or not.
877
 */
878
function give_can_view_receipt( $payment_key = '' ) {
879
880
	$return = false;
881
882
	if ( empty( $payment_key ) ) {
883
		return $return;
884
	}
885
886
	global $give_receipt_args;
887
888
	$give_receipt_args['id'] = give_get_donation_id_by_key( $payment_key );
889
890
	$user_id = (int) give_get_payment_user_id( $give_receipt_args['id'] );
891
892
	$payment_meta = give_get_payment_meta( $give_receipt_args['id'] );
893
894
	if ( is_user_logged_in() ) {
895
		if ( $user_id === (int) get_current_user_id() ) {
896
			$return = true;
897
		} elseif ( wp_get_current_user()->user_email === give_get_payment_user_email( $give_receipt_args['id'] ) ) {
898
			$return = true;
899
		} elseif ( current_user_can( 'view_give_sensitive_data' ) ) {
900
			$return = true;
901
		}
902
	}
903
904
	// Check whether it is purchase session?
905
	$purchase_session = give_get_purchase_session();
906
	if ( ! empty( $purchase_session ) && ! is_user_logged_in() ) {
907
		if ( $purchase_session['purchase_key'] === $payment_meta['key'] ) {
908
			$return = true;
909
		}
910
	}
911
912
	// Check whether it is receipt access session?
913
	$receipt_session = give_get_receipt_session();
914
	if ( ! empty( $receipt_session ) && ! is_user_logged_in() ) {
915
		if ( $receipt_session === $payment_meta['key'] ) {
916
			$return = true;
917
		}
918
	}
919
920
	// Check whether it is history access session?
921
	if ( true === give_get_history_session() ) {
922
		$return = true;
923
	}
924
925
	return (bool) apply_filters( 'give_can_view_receipt', $return, $payment_key );
926
927
}
928
929
/**
930
 * Fallback for cal_days_in_month
931
 *
932
 * Fallback in case the calendar extension is not loaded in PHP; Only supports Gregorian calendar
933
 */
934
if ( ! function_exists( 'cal_days_in_month' ) ) {
935
	/**
936
	 * cal_days_in_month
937
	 *
938
	 * @param int $calendar
939
	 * @param int $month
940
	 * @param int $year
941
	 *
942
	 * @return bool|string
943
	 */
944
	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...
945
		return date( 't', mktime( 0, 0, 0, $month, 1, $year ) );
946
	}
947
}
948
949
/**
950
 * Get plugin info including status, type, and license validation.
951
 *
952
 * This is an enhanced version of get_plugins() that returns the status
953
 * (`active` or `inactive`) of all plugins, type of plugin (`add-on` or `other`
954
 * and license validation for Give add-ons (`true` or `false`). Does not include
955
 * MU plugins.
956
 *
957
 * @since 1.8.0
958
 *
959
 * @return array Plugin info plus status, type, and license validation if
960
 *               available.
961
 */
962
function give_get_plugins() {
963
	$plugins             = get_plugins();
964
	$active_plugin_paths = (array) get_option( 'active_plugins', array() );
965
966
	if ( is_multisite() ) {
967
		$network_activated_plugin_paths = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
968
		$active_plugin_paths            = array_merge( $active_plugin_paths, $network_activated_plugin_paths );
969
	}
970
971
	foreach ( $plugins as $plugin_path => $plugin_data ) {
972
		// Is plugin active?
973
		if ( in_array( $plugin_path, $active_plugin_paths ) ) {
974
			$plugins[ $plugin_path ]['Status'] = 'active';
975
		} else {
976
			$plugins[ $plugin_path ]['Status'] = 'inactive';
977
		}
978
979
		$dirname = strtolower( dirname( $plugin_path ) );
980
981
		// Is plugin a Give add-on by WordImpress?
982
		if ( strstr( $dirname, 'give-' ) && strstr( $plugin_data['AuthorURI'], 'wordimpress.com' ) ) {
983
			// Plugin is a Give-addon.
984
			$plugins[ $plugin_path ]['Type'] = 'add-on';
985
986
			/* @var stdClass $license_active */
987
			$license_active = __give_get_active_license_info( Give_License::get_short_name( $plugin_data['Name'] ) );
988
989
			// Does a valid license exist?
990
			if ( ! empty( $license_active ) && 'valid' === $license_active->license ) {
991
				$plugins[ $plugin_path ]['License'] = true;
992
			} else {
993
				$plugins[ $plugin_path ]['License'] = false;
994
			}
995
		} else {
996
			// Plugin is not a Give add-on.
997
			$plugins[ $plugin_path ]['Type'] = 'other';
998
		}
999
	}
1000
1001
	return $plugins;
1002
}
1003
1004
/**
1005
 * Check if terms enabled or not for form.
1006
 *
1007
 * @since 1.8
1008
 *
1009
 * @param $form_id
1010
 *
1011
 * @return bool
1012
 */
1013
function give_is_terms_enabled( $form_id ) {
1014
	$form_option = give_get_meta( $form_id, '_give_terms_option', true );
1015
1016
	if (
1017
		give_is_setting_enabled( $form_option, 'global' )
1018
		&& give_is_setting_enabled( give_get_option( 'terms' ) )
1019
	) {
1020
		return true;
1021
1022
	} elseif ( give_is_setting_enabled( $form_option ) ) {
1023
		return true;
1024
1025
	} else {
1026
		return false;
1027
	}
1028
}
1029
1030
/**
1031
 * Delete donation stats cache.
1032
 *
1033
 * @todo  Resolve stats cache key naming issue. Currently it is difficult to regenerate cache key.
1034
 *
1035
 * @since 1.8.7
1036
 *
1037
 * @param string|array $date_range Date for stats.
1038
 *                                 Date value should be in today, yesterday, this_week, last_week, this_month,
1039
 *                                 last_month, this_quarter, last_quarter, this_year, last_year. For date value other,
1040
 *                                 all cache will be removed.
1041
 *
1042
 * @param array        $args
1043
 *
1044
 * @return WP_Error|bool
1045
 */
1046
function give_delete_donation_stats( $date_range = '', $args = array() ) {
1047
1048
	// Delete all cache.
1049
	$status = Give_Cache::delete( Give_Cache::get_options_like( 'give_stats' ) );
1050
1051
	/**
1052
	 * Fire the action when donation stats delete.
1053
	 *
1054
	 * @since 1.8.7
1055
	 *
1056
	 * @param string|array $date_range
1057
	 * @param array        $args
1058
	 */
1059
	do_action( 'give_delete_donation_stats', $status, $date_range, $args );
1060
1061
	return $status;
1062
}
1063
1064
/**
1065
 * Check if admin creating new donation form or not.
1066
 *
1067
 * @since 2.0
1068
 * @return bool
1069
 */
1070
function give_is_add_new_form_page() {
1071
	$status = false;
1072
1073
	if ( false !== strpos( $_SERVER['REQUEST_URI'], '/wp-admin/post-new.php?post_type=give_forms' ) ) {
1074
		$status = true;
1075
	}
1076
1077
	return $status;
1078
}
1079
1080
/**
1081
 * Get Form/Payment meta.
1082
 *
1083
 * Note: This function will help you to get meta for payment and form.
1084
 *       If you want to get meta for donors then use get_meta of Give_Donor and
1085
 *       If you want to get meta for logs then use get_meta of Give_Logging->logmeta_db.
1086
 *
1087
 * @since 1.8.8
1088
 *
1089
 * @param int    $id
1090
 * @param string $meta_key
1091
 * @param bool   $single
1092
 * @param bool   $default
1093
 *
1094
 * @return mixed
1095
 */
1096
function give_get_meta( $id, $meta_key = '', $single = false, $default = false ) {
1097
	/**
1098
	 * Filter the meta value
1099
	 *
1100
	 * @since 1.8.8
1101
	 */
1102
	$meta_value = apply_filters(
1103
		'give_get_meta',
1104
		get_post_meta( $id, $meta_key, $single ),
1105
		$id,
1106
		$meta_key,
1107
		$default
1108
	);
1109
1110
	if (
1111
		( empty( $meta_key ) || empty( $meta_value ) )
1112
		&& $default
1113
	) {
1114
		$meta_value = $default;
1115
	}
1116
1117
	return $meta_value;
1118
}
1119
1120
/**
1121
 * Update Form/Payment meta.
1122
 *
1123
 * @since 1.8.8
1124
 *
1125
 * @param int    $id
1126
 * @param string $meta_key
1127
 * @param mixed  $meta_value
1128
 * @param mixed  $prev_value
1129
 *
1130
 * @return mixed
1131
 */
1132
function give_update_meta( $id, $meta_key, $meta_value, $prev_value = '' ) {
1133
	$status = update_post_meta( $id, $meta_key, $meta_value, $prev_value );
1134
1135
	/**
1136
	 * Filter the meta value update status
1137
	 *
1138
	 * @since 1.8.8
1139
	 */
1140
	return apply_filters( 'give_update_meta', $status, $id, $meta_key, $meta_value );
1141
}
1142
1143
/**
1144
 * Delete Form/Payment meta.
1145
 *
1146
 * @since 1.8.8
1147
 *
1148
 * @param int    $id
1149
 * @param string $meta_key
1150
 * @param string $meta_value
1151
 *
1152
 * @return mixed
1153
 */
1154
function give_delete_meta( $id, $meta_key, $meta_value = '' ) {
1155
	$status = delete_post_meta( $id, $meta_key, $meta_value );
1156
1157
	/**
1158
	 * Filter the meta value delete status
1159
	 *
1160
	 * @since 1.8.8
1161
	 */
1162
	return apply_filters( 'give_delete_meta', $status, $id, $meta_key, $meta_value );
1163
}
1164
1165
/**
1166
 * Check if the upgrade routine has been run for a specific action
1167
 *
1168
 * @since  1.0
1169
 *
1170
 * @param  string $upgrade_action The upgrade action to check completion for
1171
 *
1172
 * @return bool                   If the action has been added to the completed actions array
1173
 */
1174
function give_has_upgrade_completed( $upgrade_action = '' ) {
1175
	// Bailout.
1176
	if ( empty( $upgrade_action ) ) {
1177
		return false;
1178
	}
1179
1180
	// Fresh install?
1181
	// If fresh install then all upgrades will be consider as completed.
1182
	$is_fresh_install = ! get_option( 'give_version' );
1183
	if ( $is_fresh_install ) {
1184
		return true;
1185
	}
1186
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1187
1188
	$completed_upgrades = give_get_completed_upgrades();
1189
1190
	return in_array( $upgrade_action, $completed_upgrades );
1191
1192
}
1193
1194
/**
1195
 * For use when doing 'stepped' upgrade routines, to see if we need to start somewhere in the middle
1196
 *
1197
 * @since 1.8
1198
 *
1199
 * @return mixed   When nothing to resume returns false, otherwise starts the upgrade where it left off
1200
 */
1201
function give_maybe_resume_upgrade() {
1202
	$doing_upgrade = get_option( 'give_doing_upgrade', false );
1203
	if ( empty( $doing_upgrade ) ) {
1204
		return false;
1205
	}
1206
1207
	return $doing_upgrade;
1208
}
1209
1210
/**
1211
 * Adds an upgrade action to the completed upgrades array
1212
 *
1213
 * @since  1.0
1214
 *
1215
 * @param  string $upgrade_action The action to add to the completed upgrades array
1216
 *
1217
 * @return bool                   If the function was successfully added
1218
 */
1219
function give_set_upgrade_complete( $upgrade_action = '' ) {
1220
1221
	if ( empty( $upgrade_action ) ) {
1222
		return false;
1223
	}
1224
1225
	$completed_upgrades   = give_get_completed_upgrades();
1226
	$completed_upgrades[] = $upgrade_action;
1227
1228
	// Remove any blanks, and only show uniques.
1229
	$completed_upgrades = array_unique( array_values( $completed_upgrades ) );
1230
1231
	/**
1232
	 * Fire the action when any upgrade set to complete.
1233
	 *
1234
	 * @since 1.8.12
1235
	 */
1236
	do_action( 'give_set_upgrade_completed', $upgrade_action, $completed_upgrades );
1237
1238
	return update_option( 'give_completed_upgrades', $completed_upgrades, 'no' );
1239
}
1240
1241
/**
1242
 * Get's the array of completed upgrade actions
1243
 *
1244
 * @since  1.0
1245
 * @return array The array of completed upgrades
1246
 */
1247
function give_get_completed_upgrades() {
1248
	return (array) get_option( 'give_completed_upgrades' );
1249
}
1250
1251
/**
1252
 * In 2.0 we updated table for log, payment and form.
1253
 *
1254
 * Note: internal purpose only.
1255
 *
1256
 * @since 2.0
1257
 * @global wpdb  $wpdb
1258
 *
1259
 * @param string $type Context for table
1260
 *
1261
 * @return null|array
1262
 */
1263
function __give_v20_bc_table_details( $type ) {
1264
	global $wpdb;
1265
	$table = array();
1266
1267
	// Bailout.
1268
	if ( empty( $type ) ) {
1269
		return null;
1270
	}
1271
1272
	switch ( $type ) {
1273
		case 'form':
1274
			$table['name']         = $wpdb->formmeta;
1275
			$table['column']['id'] = 'form_id';
1276
1277
			break;
1278
1279
		case 'payment':
1280
			$table['name']         = $wpdb->paymentmeta;
1281
			$table['column']['id'] = 'payment_id';
1282
	}
1283
1284
	// Backward compatibility.
1285
	if ( ! give_has_upgrade_completed( 'v20_move_metadata_into_new_table' ) ) {
1286
		$table['name']         = $wpdb->postmeta;
1287
		$table['column']['id'] = 'post_id';
1288
	}
1289
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
1290
1291
	return $table;
1292
}
1293
1294
/**
1295
 * Remove the Give transaction pages from WP search results.
1296
 *
1297
 * @since 1.8.13
1298
 *
1299
 * @param WP_Query $query
1300
 */
1301
function give_remove_pages_from_search( $query ) {
1302
1303
	if ( ! $query->is_admin && $query->is_search && $query->is_main_query() ) {
1304
1305
		$transaction_failed = give_get_option( 'failure_page', 0 );
1306
		$success_page       = give_get_option( 'success_page', 0 );
1307
1308
		$args               = apply_filters(
1309
			'give_remove_pages_from_search', array(
1310
			$transaction_failed,
1311
			$success_page,
1312
		), $query
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 8.
Loading history...
1313
		);
1314
		$query->set( 'post__not_in', $args );
1315
	}
1316
}
1317
1318
add_action( 'pre_get_posts', 'give_remove_pages_from_search', 10, 1 );
1319
1320
/**
1321
 * Inserts a new key/value before a key in the array.
1322
 *
1323
 * @since 1.8.13
1324
 *
1325
 * @param string       $key       The key to insert before.
1326
 * @param array        $array     An array to insert in to.
1327
 * @param string       $new_key   The key to insert.
1328
 * @param array|string $new_value An value to insert.
1329
 *
1330
 * @return array The new array if the key exists, the passed array otherwise.
1331
 *
1332
 * @see   array_insert_before()
1333
 */
1334 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...
1335
	if ( array_key_exists( $key, $array ) ) {
1336
		$new = array();
1337
		foreach ( $array as $k => $value ) {
1338
			if ( $k === $key ) {
1339
				$new[ $new_key ] = $new_value;
1340
			}
1341
			$new[ $k ] = $value;
1342
		}
1343
1344
		return $new;
1345
	}
1346
1347
	return $array;
1348
}
1349
1350
/**
1351
 * Inserts a new key/value after a key in the array.
1352
 *
1353
 * @since 1.8.13
1354
 *
1355
 * @param string       $key       The key to insert after.
1356
 * @param array        $array     An array to insert in to.
1357
 * @param string       $new_key   The key to insert.
1358
 * @param array|string $new_value An value to insert.
1359
 *
1360
 * @return array The new array if the key exists, the passed array otherwise.
1361
 *
1362
 * @see   array_insert_before()
1363
 */
1364 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...
1365
	if ( array_key_exists( $key, $array ) ) {
1366
		$new = array();
1367
		foreach ( $array as $k => $value ) {
1368
			$new[ $k ] = $value;
1369
			if ( $k === $key ) {
1370
				$new[ $new_key ] = $new_value;
1371
			}
1372
		}
1373
1374
		return $new;
1375
	}
1376
1377
	return $array;
1378
}
1379
1380
/**
1381
 * Pluck a certain field out of each object in a list.
1382
 *
1383
 * This has the same functionality and prototype of
1384
 * array_column() (PHP 5.5) but also supports objects.
1385
 *
1386
 * @since 1.8.13
1387
 *
1388
 * @param array      $list      List of objects or arrays
1389
 * @param int|string $field     Field from the object to place instead of the entire object
1390
 * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
1391
 *                              Default null.
1392
 *
1393
 * @return array Array of found values. If `$index_key` is set, an array of found values with keys
1394
 *               corresponding to `$index_key`. If `$index_key` is null, array keys from the original
1395
 *               `$list` will be preserved in the results.
1396
 */
1397
function give_list_pluck( $list, $field, $index_key = null ) {
1398
1399
	if ( ! $index_key ) {
1400
		/**
1401
		 * This is simple. Could at some point wrap array_column()
1402
		 * if we knew we had an array of arrays.
1403
		 */
1404
		foreach ( $list as $key => $value ) {
1405
			if ( is_object( $value ) ) {
1406
				if ( isset( $value->$field ) ) {
1407
					$list[ $key ] = $value->$field;
1408
				}
1409
			} else {
1410
				if ( isset( $value[ $field ] ) ) {
1411
					$list[ $key ] = $value[ $field ];
1412
				}
1413
			}
1414
		}
1415
1416
		return $list;
1417
	}
1418
1419
	/*
1420
	 * When index_key is not set for a particular item, push the value
1421
	 * to the end of the stack. This is how array_column() behaves.
1422
	 */
1423
	$newlist = array();
1424
	foreach ( $list as $value ) {
1425
		if ( is_object( $value ) ) {
1426
			if ( isset( $value->$index_key ) ) {
1427
				$newlist[ $value->$index_key ] = $value->$field;
1428
			} else {
1429
				$newlist[] = $value->$field;
1430
			}
1431
		} else {
1432
			if ( isset( $value[ $index_key ] ) ) {
1433
				$newlist[ $value[ $index_key ] ] = $value[ $field ];
1434
			} else {
1435
				$newlist[] = $value[ $field ];
1436
			}
1437
		}
1438
	}
1439
1440
	$list = $newlist;
1441
1442
	return $list;
1443
}
1444
1445
/**
1446
 * Add meta data field to a donor.
1447
 *
1448
 * @since 1.8.13
1449
 *
1450
 * @param int    $donor_id   Donor ID.
1451
 * @param string $meta_key   Metadata name.
1452
 * @param mixed  $meta_value Metadata value. Must be serializable if non-scalar.
1453
 * @param bool   $unique     Optional. Whether the same key should not be added.
1454
 *                           Default false.
1455
 *
1456
 * @return int|false Meta ID on success, false on failure.
1457
 */
1458
function add_donor_meta( $donor_id, $meta_key, $meta_value, $unique = false ) {
1459
	return add_metadata( 'give_customer', $donor_id, $meta_key, $meta_value, $unique );
1460
}
1461
1462
/**
1463
 * Remove metadata matching criteria from a Donor meta.
1464
 *
1465
 * You can match based on the key, or key and value. Removing based on key and
1466
 * value, will keep from removing duplicate metadata with the same key. It also
1467
 * allows removing all metadata matching key, if needed.
1468
 *
1469
 * @since 1.8.13
1470
 *
1471
 * @param int    $donor_id   Donor ID
1472
 * @param string $meta_key   Metadata name.
1473
 * @param mixed  $meta_value Optional. Metadata value.
1474
 *
1475
 * @return bool True on success, false on failure.
1476
 */
1477
function delete_donor_meta( $donor_id, $meta_key, $meta_value = '' ) {
1478
	return delete_metadata( 'give_customer', $donor_id, $meta_key, $meta_value );
1479
}
1480
1481
/**
1482
 * Retrieve donor meta field for a donor meta table.
1483
 *
1484
 * @since 1.8.13
1485
 *
1486
 * @param int    $donor_id Donor ID.
1487
 * @param string $key      Optional. The meta key to retrieve. By default, returns data for all keys.
1488
 * @param bool   $single   Whether to return a single value.
1489
 *
1490
 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
1491
 *  is true.
1492
 */
1493
function get_donor_meta( $donor_id, $key = '', $single = false ) {
1494
	return get_metadata( 'give_customer', $donor_id, $key, $single );
1495
}
1496
1497
/**
1498
 * Update customer meta field based on Donor ID.
1499
 *
1500
 * If the meta field for the donor does not exist, it will be added.
1501
 *
1502
 * @since 1.8.13
1503
 *
1504
 * @param int    $donor_id   Donor ID.
1505
 * @param string $meta_key   Metadata key.
1506
 * @param mixed  $meta_value Metadata value.
1507
 * @param mixed  $prev_value Optional. Previous value to check before removing.
1508
 *
1509
 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
1510
 */
1511
function update_donor_meta( $donor_id, $meta_key, $meta_value, $prev_value = '' ) {
1512
	return update_metadata( 'give_customer', $donor_id, $meta_key, $meta_value, $prev_value );
1513
}
1514
1515
1516
/**
1517
 * Give recalculate income and donation of the donation from ID
1518
 *
1519
 * @since 1.8.13
1520
 *
1521
 * @param int $form_id Form id of which recalculation needs to be done.
1522
 *
1523
 * @return void
1524
 */
1525
function give_recount_form_income_donation( $form_id = 0 ) {
1526
	// Check if form id is not empty.
1527
	if ( ! empty( $form_id ) ) {
1528
		/**
1529
		 * Filter to modify payment status.
1530
		 *
1531
		 * @since 1.8.13
1532
		 */
1533
		$accepted_statuses = apply_filters( 'give_recount_accepted_statuses', array( 'publish' ) );
1534
1535
		/**
1536
		 * Filter to modify args of payment query before recalculating the form total
1537
		 *
1538
		 * @since 1.8.13
1539
		 */
1540
		$args = apply_filters(
1541
			'give_recount_form_stats_args', array(
1542
				'give_forms'     => $form_id,
1543
				'status'         => $accepted_statuses,
1544
				'posts_per_page' => - 1,
1545
				'fields'         => 'ids',
1546
			)
1547
		);
1548
1549
		$totals = array(
1550
			'sales'    => 0,
1551
			'earnings' => 0,
1552
		);
1553
1554
		$payments = new Give_Payments_Query( $args );
1555
		$payments = $payments->get_payments();
1556
1557
		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...
1558
			foreach ( $payments as $payment ) {
1559
				// Ensure acceptible status only
1560
				if ( ! in_array( $payment->post_status, $accepted_statuses ) ) {
1561
					continue;
1562
				}
1563
1564
				// Ensure only payments for this form are counted
1565
				if ( $payment->form_id != $form_id ) {
1566
					continue;
1567
				}
1568
1569
				$totals['sales'] ++;
1570
				$totals['earnings'] += $payment->total;
1571
1572
			}
1573
		}
1574
		give_update_meta( $form_id, '_give_form_sales', $totals['sales'] );
1575
		give_update_meta( $form_id, '_give_form_earnings', give_sanitize_amount_for_db( $totals['earnings'] ) );
1576
	}// End if().
1577
}
1578
1579
1580
/**
1581
 * Get attribute string
1582
 *
1583
 * @since 1.8.17
1584
 *
1585
 * @param array $attributes
1586
 *
1587
 * @return string
1588
 */
1589
function give_get_attribute_str( $attributes ) {
1590
	$attribute_str = '';
1591
1592
	if ( empty( $attributes ) ) {
1593
		return $attribute_str;
1594
	}
1595
1596
	foreach ( $attributes as $tag => $value ) {
1597
		$attribute_str .= " {$tag}=\"{$value}\"";
1598
	}
1599
1600
	return trim( $attribute_str );
1601
}
1602
1603
/**
1604
 * Get the upload dir path
1605
 *
1606
 * @since 1.8.17
1607
 *
1608
 * @return string $wp_upload_dir;
1609
 */
1610
function give_get_wp_upload_dir() {
1611
	$wp_upload_dir = wp_upload_dir();
1612
1613
	return ( ! empty( $wp_upload_dir['path'] ) ? $wp_upload_dir['path'] : false );
1614
}
1615
1616
/**
1617
 * Get the data from uploaded JSON file
1618
 *
1619
 * @since 1.8.17
1620
 *
1621
 * @param string $file_name filename of the json file that is being uploaded
1622
 *
1623
 * @return string|bool $file_contents File content
1624
 */
1625
function give_get_core_settings_json( $file_name ) {
1626
	$upload_dir = give_get_wp_upload_dir();
1627
	$file_path  = $upload_dir . '/' . $file_name;
1628
1629
	if ( is_wp_error( $file_path ) || empty( $file_path ) ) {
1630
		Give_Admin_Settings::add_error( 'give-import-csv', __( 'Please upload or provide a valid JSON file.', 'give' ) );
1631
	}
1632
1633
	$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...
1634
1635
	return $file_contents;
1636
}
1637
1638
/**
1639
 * Get number of donation to show when user is not login.
1640
 *
1641
 * @since 1.8.17
1642
 *
1643
 * @return int $country The two letter country code for the site's base country
1644
 */
1645
function give_get_limit_display_donations() {
1646
	return give_get_option( 'limit_display_donations', 1 );
1647
}
1648
1649
/**
1650
 * Add footer to the table when donor is view the donation history page with out login
1651
 *
1652
 * @since 1.8.17
1653
 */
1654
function give_donation_history_table_end() {
1655
	$email = Give()->session->get( 'give_email' );
1656
	?>
1657
	<tfoot>
1658
	<tr>
1659
		<td colspan="9999">
1660
			<div class="give-security-wrap">
1661
				<div class="give-security-column give-security-description-wrap">
1662
					<?php
1663
					echo sprintf(
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
1664
						__( 'For security reasons, please confirm your email address (%s) to view your complete donation history.', 'give' ),
1665
						$email
1666
					);
1667
					?>
1668
				</div>
1669
				<div class="give-security-column give-security-button-wrap">
1670
					<a href="#" data-email="<?php echo $email; ?>" id="give-confirm-email-btn" class="give-confirm-email-btn give-btn">
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$email'
Loading history...
1671
						<?php _e( 'Confirm Email', 'give' ); ?>
1672
					</a>
1673
					<span><?php _e( 'Email Sent!', 'give' ); ?></span>
1674
				</div>
1675
			</div>
1676
		</td>
1677
	</tr>
1678
	</tfoot>
1679
	<?php
1680
}
1681
1682
1683
/**
1684
 * Wrapper for _doing_it_wrong.
1685
 *
1686
 * @since  1.8.18
1687
 * @param  string $function
1688
 * @param  string $message
1689
 * @param  string $version
1690
 *
1691
 * @return void
1692
 */
1693
function give_doing_it_wrong( $function, $message, $version ) {
1694
	$message .= "\nBacktrace:" . wp_debug_backtrace_summary();
1695
1696
	_doing_it_wrong( $function, $message , $version );
1697
}
1698
1699
1700
/**
1701
 * Remove limit from running php script complete.
1702
 *
1703
 * @since 1.8.18
1704
 */
1705
function give_ignore_user_abort(){
1706
	ignore_user_abort( true );
1707
1708
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
1709
		set_time_limit( 0 );
1710
	}
1711
}
1712
1713
/**
1714
 * Get post type count.
1715
 *
1716
 * @since 2.0.2
1717
 *
1718
 * @param string $post_type
1719
 * @param array  $args
1720
 *
1721
 * @return int
1722
 */
1723
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...
1724
	global $wpdb;
1725
	$where = '';
1726
1727
	if( ! $post_type ) {
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...
1728
		return 0;
1729
	}
1730
1731
	// Bulit where query
1732
	if( ! empty( $post_type ) ) {
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...
1733
		$where.=' WHERE';
0 ignored issues
show
introduced by
Expected 1 space before ".="; 0 found
Loading history...
introduced by
Expected 1 space after ".="; 0 found
Loading history...
1734
1735
		if( is_array( $post_type ) ) {
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...
1736
			$where .= " post_type='" . implode( "' OR post_type='", $post_type ) . "'";
1737
		}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...
1738
			$where .= " post_type='{$post_type}'";
1739
		}
1740
	}
1741
1742
	$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...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
1743
1744
	return absint( $result );
1745
}
1746
1747
/**
1748
 * Define a constant if it is not already defined.
1749
 *
1750
 * @since 2.0.5
1751
 * @param string $name  Constant name.
1752
 * @param string $value Value.
1753
 *
1754
 * @credit WooCommerce
1755
 */
1756
function give_maybe_define_constant( $name, $value ) {
1757
	if ( ! defined( $name ) ) {
1758
		define( $name, $value );
1759
	}
1760
}
1761
1762
/**
1763
 * Decode time short tag in string
1764
 *
1765
 * @since 2.1.0
1766
 *
1767
 * @param string $string
1768
 * @param int    $timestamp
1769
 *
1770
 * @return string
1771
 */
1772
function give_time_do_tags( $string, $timestamp = 0 ) {
1773
	$current_time = ! empty( $timestamp ) ? $timestamp : current_time( 'timestamp' );
1774
1775
	$formatted_string = str_replace(
1776
		array(
1777
			'{D}',
1778
			'{DD}',
1779
			'{M}',
1780
			'{MM}',
1781
			'{YY}',
1782
			'{YYYY}',
1783
			'{H}',
1784
			'{HH}',
1785
			'{N}',
1786
			'{S}'
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
1787
		),
1788
		array(
1789
			date( 'j', $current_time ),
1790
			date( 'd', $current_time ),
1791
			date( 'n', $current_time ),
1792
			date( 'm', $current_time ),
1793
			date( 'Y', $current_time ),
1794
			date( 'Y', $current_time ),
1795
			date( 'G', $current_time ),
1796
			date( 'H', $current_time ),
1797
			date( 's', $current_time )
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
1798
		),
1799
		$string
1800
	);
1801
1802
	/**
1803
	 * Filter the parsed string.
1804
	 *
1805
	 * @since 2.1.0
1806
	 */
1807
	return apply_filters( 'give_time_do_tags', $formatted_string, $string, $timestamp );
1808
}
1809
1810
1811
/**
1812
 * Check if Company field enabled or not for form or globally.
1813
 *
1814
 * @since 2.1.0
1815
 *
1816
 * @param $form_id
1817
 *
1818
 * @return bool
1819
 */
1820
function give_is_company_field_enabled( $form_id ) {
1821
	$form_setting_val           = give_get_meta( $form_id, '_give_company_field', true );
1822
	$global_setting_val = give_get_option( 'company_field' );
1823
1824
	if ( ! empty( $form_setting_val ) ) {
1825
		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...
introduced by
Space after opening control structure is required
Loading history...
introduced by
No space before opening parenthesis is prohibited
Loading history...
1826
			return true;
1827
		} elseif ( 'global' === $form_setting_val && 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...
1828
			return true;
1829
		} 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...
1830
			return false;
1831
		}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
1832
1833
	} 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...
1834
		return true;
1835
1836
	} else {
1837
		return false;
1838
	}
1839
}
1840
1841
/**
1842
 * Get add-on user meta value information
1843
 * Note: only for internal use.
1844
 *
1845
 * @since 2.1.0
1846
 *
1847
 * @param string $license_id
1848
 *
1849
 * @return array
1850
 */
1851
function __give_get_active_license_info( $license_id ) {
1852
	global $wpdb;
1853
	$option_name = "{$license_id}_license_active";
1854
	$data        = array();
1855
1856
	if ( ! isset( $GLOBALS['give_active_licenses_info'] ) ) {
1857
		$GLOBALS['give_active_licenses_info']  = array();
1858
1859
		$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...
1860
			"
1861
			SELECT option_name, option_value
1862
			FROM {$wpdb->options}
1863
			WHERE option_name LIKE '%_license_active%'
1864
			AND option_name LIKE '%give_%'
1865
			",
1866
			ARRAY_A
1867
		);
1868
1869 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...
1870
			$GLOBALS['give_active_licenses_info'] = array_combine(
1871
				wp_list_pluck( $licenses_info, 'option_name' ),
1872
				wp_list_pluck( $licenses_info, 'option_value' )
1873
			);
1874
		}
1875
	}
1876
1877 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...
1878
		$data = maybe_unserialize( $GLOBALS['give_active_licenses_info'][ $option_name ] );
1879
	}
1880
1881
	return $data;
1882
}
1883
1884
/**
1885
 * Get add-on user meta value information
1886
 * Note: only for internal use.
1887
 *
1888
 * @since 2.1.0
1889
 *
1890
 * @param string $banner_addon_name Give add-on name.
1891
 *
1892
 * @return array
1893
 */
1894
function __give_get_active_by_user_meta( $banner_addon_name ) {
1895
	global $wpdb;
1896
1897
	// Get the option key.
1898
	$option_name = Give_Addon_Activation_Banner::get_banner_user_meta_key( $banner_addon_name );
1899
	$data        = array();
1900
1901
	if (
1902
		! isset( $GLOBALS['give_addon_activated_by_user'][ $banner_addon_name ] )
1903
		|| empty( $GLOBALS['give_addon_activated_by_user'][ $banner_addon_name ] )
1904
	) {
1905
		$GLOBALS['give_addon_activated_by_user'][ $banner_addon_name ] = array();
1906
1907
		// Get the meta of activation banner by user.
1908
		$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...
1909
				"
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...
1910
					SELECT option_name, option_value
1911
					FROM {$wpdb->options}
1912
					WHERE option_name LIKE '%_active_by_user%'
1913
					AND option_name LIKE '%give_addon%'
1914
					",
1915
			ARRAY_A
1916
		);
1917
1918 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...
1919
			$GLOBALS['give_addon_activated_by_user'] = array_combine(
1920
				wp_list_pluck( $activation_banners, 'option_name' ),
1921
				wp_list_pluck( $activation_banners, 'option_value' )
1922
			);
1923
		}
1924
	}
1925
1926 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...
1927
		$data = maybe_unserialize( $GLOBALS['give_addon_activated_by_user'][ $option_name ] );
1928
	}
1929
1930
	return $data;
1931
}
1932
1933
/**
1934
 * Get time interval for which nonce is valid
1935
 *
1936
 * @since 2.1.3
1937
 *
1938
 * @return int
1939
 */
1940
function give_get_nonce_life(){
1941
	/**
1942
	 * Filters the lifespan of nonces in seconds.
1943
	 *
1944
	 * @see wp-inlucdes/pluggable.php:wp_nonce_tick
1945
	 */
1946
	return (int) apply_filters( 'nonce_life', DAY_IN_SECONDS );
1947
}
1948
1949
/**
1950
 * Get nonce field without id
1951
 *
1952
 * @since 2.1.3
1953
 *
1954
 * @param  string $action
1955
 * @param  string $name
1956
 * @param bool    $referer
1957
 *
1958
 * @return string
1959
 */
1960
function give_get_nonce_field( $action, $name, $referer = false ) {
1961
	return str_replace(
1962
		"id=\"{$name}\"",
1963
		'',
1964
		wp_nonce_field( $action, $name, $referer, false )
1965
	);
1966
}
1967
1968
/**
1969
 * Display/Return a formatted goal for a donation form
1970
 *
1971
 * @param int|Give_Donate_Form $form Form ID or Form Object.
1972
 *
1973
 * @since 2.1
1974
 *
1975
 * @return array
1976
 */
1977
function give_goal_progress_stats( $form ) {
1978
1979
	if ( ! $form instanceof Give_Donate_Form ) {
1980
		$form = new Give_Donate_Form( $form );
1981
	}
1982
1983
	$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...
1984
1985
	$goal_format = give_get_form_goal_format( $form->ID );
1986
1987
	/**
1988
	 * Filter the form.
1989
	 *
1990
	 * @since 1.8.8
1991
	 */
1992
	$total_goal = apply_filters( 'give_goal_amount_target_output', round( give_maybe_sanitize_amount( $form->goal ) ), $form->ID, $form );
1993
1994
	switch ( $goal_format ) {
1995
		case  'donation':
1996
			/**
1997
			 * Filter the form donations.
1998
			 *
1999
			 * @since 2.1
2000
			 */
2001
			$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...
2002
			break;
2003
		case 'donors':
2004
			/**
2005
			 * Filter to modify total number if donor for the donation form.
2006
			 *
2007
			 * @since 2.1.3
2008
			 *
2009
			 * @param int $donors Total number of donors that donated to the form.
2010
			 * @param int $form_id Donation Form ID.
2011
			 * @param Give_Donate_Form $form instances of Give_Donate_Form.
2012
			 *
2013
			 * @return int $donors Total number of donors that donated to the form.
2014
			 */
2015
			$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...
2016
			break;
2017
		default :
2018
			/**
2019
			 * Filter the form income.
2020
			 *
2021
			 * @since 1.8.8
2022
			 */
2023
			$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...
2024
			break;
2025
	}
2026
2027
	$progress = round( ( $actual / $total_goal ) * 100, 2 );
2028
2029
	$stats_array = array(
2030
		'raw_actual' => $actual,
2031
		'raw_goal'   => $total_goal
0 ignored issues
show
introduced by
Each line in an array declaration must end in a comma
Loading history...
2032
	);
2033
2034
	/**
2035
	 * Filter the goal progress output
2036
	 *
2037
	 * @since 1.8.8
2038
	 */
2039
	$progress = apply_filters( 'give_goal_amount_funded_percentage_output', $progress, $form->ID, $form );
2040
2041
	// Define Actual Goal based on the goal format.
2042 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...
2043
		$actual = "{$actual}%";
2044
	} else if ( 'amount' === $goal_format ) {
2045
		$actual = give_currency_filter( give_format_amount( $actual ) );
2046
	}
2047
2048
	// Define Total Goal based on the goal format.
2049 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...
2050
		$total_goal = '';
2051
	} else if ( 'amount' === $goal_format ) {
2052
		$total_goal = give_currency_filter( give_format_amount( $total_goal ) );
2053
	}
2054
2055
	$stats_array = array_merge(
2056
		array(
2057
			'progress'       => $progress,
2058
			'actual'         => $actual,
2059
			'goal'           => $total_goal,
2060
			'format'         => $goal_format,
2061
		),
2062
		$stats_array
2063
	);
2064
2065
	/**
2066
	 * Filter the goal stats
2067
	 *
2068
	 * @since 2.1
2069
	 */
2070
	return apply_filters( 'give_goal_progress_stats', $stats_array );
2071
2072
}
2073
2074
/**
2075
 * Get the admin messages key to show the notices.
2076
 *
2077
 * @since 2.1.4
2078
 *
2079
 * @return array $message admin message key.
2080
 */
2081
function give_get_admin_messages_key() {
2082
	$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...
2083
2084
	// backward compatibility.
2085
	if ( ! empty( $_GET['give-message'] ) ) {
2086
		$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...
2087
	}
2088
2089
	/**
2090
	 * Filter to modify the admin messages key.
2091
	 *
2092
	 * @since 2.1.4
2093
	 *
2094
	 * @param array $message admin message key.
2095
	 *
2096
	 * @return array $message admin message key.
2097
	 */
2098
	return (array) apply_filters( 'give_get_admin_messages_key', $messages );
2099
}
2100
2101
/**
2102
 * Get User Agent String.
2103
 *
2104
 * @since 2.1.4
2105
 *
2106
 * @return array|string
2107
 */
2108
function give_get_user_agent() {
2109
2110
	// Get User Agent.
2111
	$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...
2112
2113
	return $user_agent;
2114
2115
}
2116