Test Failed
Push — issues/370 ( da4d1b...967cb5 )
by Ravinder
05:08
created

misc-functions.php ➔ give_is_cc_verify_enabled()   C

Complexity

Conditions 8
Paths 4

Size

Total Lines 27
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

Loading history...
2013
				// Ensure acceptible status only
2014
				if ( ! in_array( $payment->post_status, $accepted_statuses ) ) {
2015
					continue;
2016
				}
2017
2018
				// Ensure only payments for this form are counted
2019
				if ( $payment->form_id != $form_id ) {
2020
					continue;
2021
				}
2022
2023
				$totals['sales'] ++;
2024
				$totals['earnings'] += $payment->total;
2025
2026
			}
2027
		}
2028
		give_update_meta( $form_id, '_give_form_sales', $totals['sales'] );
2029
		give_update_meta( $form_id, '_give_form_earnings', give_sanitize_amount_for_db( $totals['earnings'] ) );
2030
	}// End if().
2031
}
2032
2033
/**
2034
 * Zero Decimal based Currency.
2035
 *
2036
 * @since 1.8.14
2037
 * @see   https://github.com/WordImpress/Give/issues/2191
2038
 *
2039
 *
2040
 * @param string $currency Currency code
2041
 *
2042
 * @return bool
2043
 */
2044
function give_is_zero_based_currency( $currency = '' ) {
2045
	$zero_based_currency = array(
2046
		'PYG', // Paraguayan Guarani.
2047
		'GNF', // Guinean Franc.
2048
		'RWF', // Rwandan Franc.
2049
		'JPY', // Japanese Yen.
2050
		'BIF', // Burundian Franc.
2051
		'KRW', // South Korean Won.
2052
		'MGA', // Malagasy Ariary.
2053
		'XAF', // Central African Cfa Franc.
2054
		'XPF', // Cfp Franc.
2055
		'CLP', // Chilean Peso.
2056
		'KMF', // Comorian Franc.
2057
		'DJF', // Djiboutian Franc.
2058
		'VUV', // Vanuatu Vatu.
2059
		'VND', // Vietnamese Dong.
2060
		'XOF', // West African Cfa Franc.
2061
	);
2062
2063
	// Set default currency.
2064
	if( empty( $currency ) ) {
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...
2065
		$currency = give_get_currency();
2066
	}
2067
2068
	// Check for Zero Based Currency.
2069
	if ( in_array( $currency, $zero_based_currency ) ) {
2070
		return true;
2071
	}
2072
2073
	return false;
2074
}
2075