Event Tickets - Version 5.2.0

Version Description

Download this release

Release Info

Developer bordoni
Plugin Icon 128x128 Event Tickets
Version 5.2.0
Comparing to
See all releases

Code changes from version 5.1.10 to 5.2.0

Files changed (129) hide show
  1. common/lang/tribe-common.pot +25 -25
  2. common/node_modules/intro.js/intro.js +0 -4421
  3. common/node_modules/intro.js/introjs-rtl.css +0 -23
  4. common/node_modules/intro.js/introjs.css +0 -436
  5. common/src/Tribe/Admin/Conditional_Content/Black_Friday.php +84 -0
  6. common/src/Tribe/Admin/Conditional_Content/Datetime_Conditional_Abstract.php +150 -0
  7. common/src/Tribe/Admin/Conditional_Content/Service_Provider.php +45 -0
  8. common/src/Tribe/Admin/Notice/Date_Based.php +33 -5
  9. common/src/Tribe/Admin/Notice/Marketing/Black_Friday.php +13 -26
  10. common/src/Tribe/Ajax/Dropdown.php +1 -1
  11. common/src/Tribe/Editor.php +16 -2
  12. common/src/Tribe/Main.php +2 -2
  13. common/src/Tribe/Onboarding/Hints_Abstract.php +0 -98
  14. common/src/Tribe/Onboarding/Main.php +0 -223
  15. common/src/Tribe/Onboarding/README.md +0 -242
  16. common/src/Tribe/Onboarding/Tour_Abstract.php +0 -98
  17. common/src/Tribe/PUE/Checker.php +5 -2
  18. common/src/Tribe/Service_Providers/Onboarding.php +0 -140
  19. common/src/admin-views/conditional_content/black-friday.php +35 -0
  20. common/src/admin-views/notices/tribe-bf-general.php +12 -3
  21. common/src/functions/utils.php +20 -0
  22. common/src/resources/css/common-full.min.css +1 -1
  23. common/src/resources/css/dialog.min.css +1 -1
  24. common/src/resources/css/onboarding.min.css +0 -1
  25. common/src/resources/css/tribe-common-admin.min.css +1 -1
  26. common/src/resources/css/variables-skeleton.min.css +1 -1
  27. common/src/resources/images/marketing/bf-promo.png +0 -0
  28. common/src/resources/images/mascot.png +0 -0
  29. common/src/resources/images/promos/bf-promo.png +0 -0
  30. common/src/resources/js/onboarding.js +0 -106
  31. common/src/resources/js/onboarding.min.js +0 -1
  32. common/src/views/v2/components/icons/list.php +12 -1
  33. common/vendor/autoload.php +1 -1
  34. common/vendor/autoload_52.php +1 -1
  35. common/vendor/composer/autoload_classmap.php +3 -4
  36. common/vendor/composer/autoload_real.php +4 -4
  37. common/vendor/composer/autoload_real_52.php +3 -3
  38. common/vendor/composer/autoload_static.php +8 -9
  39. common/vendor/composer/installed.json +4 -4
  40. event-tickets.php +1 -1
  41. lang/event-tickets-cs_CZ.mo +0 -0
  42. lang/event-tickets-nb_NO.mo +0 -0
  43. lang/event-tickets-nl_NL.mo +0 -0
  44. lang/event-tickets-ro_RO.mo +0 -0
  45. lang/event-tickets-ru_RU.mo +0 -0
  46. lang/event-tickets.pot +4829 -528
  47. readme.txt +11 -62
  48. src/Tickets/Assets.php +22 -4
  49. src/Tickets/Commerce/Admin/Notices.php +130 -0
  50. src/Tickets/Commerce/Admin_Tables/Attendees.php +660 -0
  51. src/Tickets/Commerce/Admin_Tables/Orders.php +337 -0
  52. src/Tickets/Commerce/Assets.php +14 -0
  53. src/Tickets/Commerce/Attendee.php +370 -36
  54. src/Tickets/Commerce/Cart.php +74 -64
  55. src/Tickets/Commerce/Cart/Cart_Interface.php +13 -3
  56. src/Tickets/Commerce/Cart/Unmanaged_Cart.php +33 -8
  57. src/Tickets/Commerce/Checkout.php +43 -0
  58. src/Tickets/Commerce/Communication/Email.php +9 -8
  59. src/Tickets/Commerce/Compatibility/Events.php +51 -0
  60. src/Tickets/Commerce/Editor/Metabox.php +7 -7
  61. src/Tickets/Commerce/Flag_Actions/Archive_Attendees.php +2 -2
  62. src/Tickets/Commerce/Flag_Actions/Backfill_Purchaser.php +100 -0
  63. src/Tickets/Commerce/Flag_Actions/Decrease_Sales.php +72 -0
  64. src/Tickets/Commerce/Flag_Actions/Decrease_Stock.php +2 -2
  65. src/Tickets/Commerce/Flag_Actions/End_Duplicated_Pending_Orders.php +64 -0
  66. src/Tickets/Commerce/Flag_Actions/Flag_Action_Handler.php +5 -0
  67. src/Tickets/Commerce/Flag_Actions/Generate_Attendees.php +52 -8
  68. src/Tickets/Commerce/Flag_Actions/Increase_Sales.php +71 -0
  69. src/Tickets/Commerce/Flag_Actions/Increase_Stock.php +2 -2
  70. src/Tickets/Commerce/Flag_Actions/Send_Email.php +74 -0
  71. src/Tickets/Commerce/Gateways/Abstract_Gateway.php +7 -0
  72. src/Tickets/Commerce/Gateways/Interface_Gateway.php +10 -1
  73. src/Tickets/Commerce/Gateways/Manager.php +17 -36
  74. src/Tickets/Commerce/Gateways/Manual/Assets.php +32 -0
  75. src/Tickets/Commerce/Gateways/Manual/Gateway.php +56 -0
  76. src/Tickets/Commerce/Gateways/Manual/Hooks.php +74 -0
  77. src/Tickets/Commerce/Gateways/Manual/Order.php +90 -0
  78. src/Tickets/Commerce/Gateways/Manual/Provider.php +50 -0
  79. src/Tickets/Commerce/Gateways/PayPal/Assets.php +78 -1
  80. src/Tickets/Commerce/Gateways/PayPal/Buttons.php +71 -9
  81. src/Tickets/Commerce/Gateways/PayPal/Client.php +107 -35
  82. src/Tickets/Commerce/Gateways/PayPal/Gateway.php +104 -1
  83. src/Tickets/Commerce/Gateways/PayPal/Hooks.php +182 -13
  84. src/Tickets/Commerce/Gateways/PayPal/Location/Country.php +851 -0
  85. src/Tickets/Commerce/Gateways/PayPal/Location/State.php +1699 -0
  86. src/Tickets/Commerce/Gateways/PayPal/Merchant.php +155 -10
  87. src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php +0 -241
  88. src/Tickets/Commerce/Gateways/PayPal/Provider.php +0 -5
  89. src/Tickets/Commerce/Gateways/PayPal/REST/On_Boarding_Endpoint.php +18 -7
  90. src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php +205 -10
  91. src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php +5 -0
  92. src/Tickets/Commerce/Gateways/PayPal/Settings.php +6 -5
  93. src/Tickets/Commerce/Gateways/PayPal/Signup.php +157 -4
  94. src/Tickets/Commerce/Gateways/PayPal/Webhooks.php +2 -1
  95. src/Tickets/Commerce/Gateways/PayPal/Webhooks/Events.php +39 -1
  96. src/Tickets/Commerce/Gateways/PayPal/WhoDat.php +7 -3
  97. src/Tickets/Commerce/Hooks.php +276 -19
  98. src/Tickets/Commerce/Legacy_Compat.php +0 -3
  99. src/Tickets/Commerce/Models/Attendee_Model.php +34 -37
  100. src/Tickets/Commerce/Models/Order_Model.php +16 -8
  101. src/Tickets/Commerce/Module.php +184 -7
  102. src/Tickets/Commerce/Notice_Handler.php +160 -0
  103. src/Tickets/Commerce/Order.php +178 -339
  104. src/Tickets/Commerce/Payments_Tab.php +109 -0
  105. src/Tickets/Commerce/Provider.php +15 -3
  106. src/Tickets/Commerce/Reports/Attendees.php +588 -0
  107. src/Tickets/Commerce/Reports/Event.php +0 -55
  108. src/Tickets/Commerce/Reports/Orders.php +408 -0
  109. src/Tickets/Commerce/Reports/Report_Abstract.php +129 -0
  110. src/Tickets/Commerce/Reports/Ticket.php +0 -40
  111. src/Tickets/Commerce/Repositories/Attendees_Repository.php +27 -16
  112. src/Tickets/Commerce/Repositories/Order_Repository.php +8 -5
  113. src/Tickets/Commerce/Settings.php +52 -83
  114. src/Tickets/Commerce/Shortcodes/Checkout_Shortcode.php +43 -23
  115. src/Tickets/Commerce/Shortcodes/Success_Shortcode.php +30 -7
  116. src/Tickets/Commerce/Status/Action_Required.php +2 -0
  117. src/Tickets/Commerce/Status/Approved.php +2 -0
  118. src/Tickets/Commerce/Status/Completed.php +7 -1
  119. src/Tickets/Commerce/Status/Created.php +1 -0
  120. src/Tickets/Commerce/Status/Denied.php +1 -0
  121. src/Tickets/Commerce/Status/Not_Completed.php +3 -1
  122. src/Tickets/Commerce/Status/Pending.php +3 -2
  123. src/Tickets/Commerce/Status/Refunded.php +1 -0
  124. src/Tickets/Commerce/Status/Reversed.php +1 -0
  125. src/Tickets/Commerce/Status/Undefined.php +1 -0
  126. src/Tickets/Commerce/Status/Voided.php +1 -0
  127. src/Tickets/Commerce/Success.php +34 -0
  128. src/Tickets/Commerce/Ticket.php +146 -12
  129. src/Tickets/Commerce/Utils/Price.php +56 -15
common/lang/tribe-common.pot CHANGED
@@ -4,11 +4,11 @@ msgid ""
4
  msgstr ""
5
  "Project-Id-Version: Tribe Common 4.14.5\n"
6
  "Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
7
- "POT-Creation-Date: 2021-09-14 04:33:24+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2021-09-14 04:33\n"
12
  "Last-Translator: \n"
13
  "Language-Team: \n"
14
 
@@ -2299,104 +2299,104 @@ msgstr ""
2299
  msgid "Clear"
2300
  msgstr ""
2301
 
2302
- #: src/Tribe/PUE/Checker.php:497
2303
  msgid "A valid license key is required for support and updates"
2304
  msgstr ""
2305
 
2306
- #: src/Tribe/PUE/Checker.php:500
2307
  msgid ""
2308
  "%1$sBuy a license%2$s for the Event Aggregator service to access additional "
2309
  "import features."
2310
  msgstr ""
2311
 
2312
- #: src/Tribe/PUE/Checker.php:512 src/Tribe/PUE/Checker.php:523
2313
  #: src/admin-views/troubleshooting/ea-status/license-key.php:40
2314
  msgid "License Key"
2315
  msgstr ""
2316
 
2317
- #: src/Tribe/PUE/Checker.php:532 src/Tribe/PUE/Checker.php:566
2318
  msgid "License Key Status:"
2319
  msgstr ""
2320
 
2321
- #: src/Tribe/PUE/Checker.php:541
2322
  msgid "Override network license key"
2323
  msgstr ""
2324
 
2325
- #: src/Tribe/PUE/Checker.php:542
2326
  msgid ""
2327
  "Check this box if you wish to override the network license key with your own"
2328
  msgstr ""
2329
 
2330
- #: src/Tribe/PUE/Checker.php:553
2331
  msgid "Site License Key"
2332
  msgstr ""
2333
 
2334
- #: src/Tribe/PUE/Checker.php:653
2335
  msgid "License key(s) updated."
2336
  msgstr ""
2337
 
2338
- #: src/Tribe/PUE/Checker.php:907
2339
  msgid ""
2340
  "Hmmm... something's wrong with this validator. Please contact %ssupport%s."
2341
  msgstr ""
2342
 
2343
- #: src/Tribe/PUE/Checker.php:920
2344
  msgid "unknown date"
2345
  msgstr ""
2346
 
2347
- #: src/Tribe/PUE/Checker.php:926
2348
  msgid "Sorry, key validation server is not available."
2349
  msgstr ""
2350
 
2351
- #: src/Tribe/PUE/Checker.php:946
2352
  msgid "Valid Key! Expires on %s"
2353
  msgstr ""
2354
 
2355
- #: src/Tribe/PUE/Checker.php:951
2356
  msgid "Thanks for setting up a valid key. It will expire on %s"
2357
  msgstr ""
2358
 
2359
- #: src/Tribe/PUE/Checker.php:978 src/Tribe/PUE/Notices.php:342
2360
  msgid "Renew Your License Now"
2361
  msgstr ""
2362
 
2363
- #: src/Tribe/PUE/Checker.php:980 src/Tribe/PUE/Notices.php:344
2364
  msgid " (opens in a new window)"
2365
  msgstr ""
2366
 
2367
- #: src/Tribe/PUE/Checker.php:997
2368
  msgid "Please refresh the page and try your request again."
2369
  msgstr ""
2370
 
2371
- #: src/Tribe/PUE/Checker.php:1017
2372
  msgid ""
2373
  "There is an update for %s. You'll need to %scheck your license%s to have "
2374
  "access to updates, downloads, and support."
2375
  msgstr ""
2376
 
2377
- #: src/Tribe/PUE/Checker.php:1074
2378
  msgid ""
2379
  "There is an update for %s. %sRenew your license%s to get access to bug "
2380
  "fixes, security updates, and new features."
2381
  msgstr ""
2382
 
2383
- #: src/Tribe/PUE/Checker.php:1104
2384
  msgid "Update now to version %s."
2385
  msgstr ""
2386
 
2387
- #: src/Tribe/PUE/Checker.php:1115
2388
  msgid "There is a new version of %1$s available. %2$s"
2389
  msgstr ""
2390
 
2391
- #: src/Tribe/PUE/Checker.php:1696
2392
  msgid "A valid license has been entered by your network administrator."
2393
  msgstr ""
2394
 
2395
- #: src/Tribe/PUE/Checker.php:1697
2396
  msgid "No license entered. Consult your network administrator."
2397
  msgstr ""
2398
 
2399
- #: src/Tribe/PUE/Checker.php:1698
2400
  msgid "Expired license. Consult your network administrator."
2401
  msgstr ""
2402
 
4
  msgstr ""
5
  "Project-Id-Version: Tribe Common 4.14.5\n"
6
  "Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
7
+ "POT-Creation-Date: 2021-10-11 18:13:59+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2021-10-11 18:13\n"
12
  "Last-Translator: \n"
13
  "Language-Team: \n"
14
 
2299
  msgid "Clear"
2300
  msgstr ""
2301
 
2302
+ #: src/Tribe/PUE/Checker.php:500
2303
  msgid "A valid license key is required for support and updates"
2304
  msgstr ""
2305
 
2306
+ #: src/Tribe/PUE/Checker.php:503
2307
  msgid ""
2308
  "%1$sBuy a license%2$s for the Event Aggregator service to access additional "
2309
  "import features."
2310
  msgstr ""
2311
 
2312
+ #: src/Tribe/PUE/Checker.php:515 src/Tribe/PUE/Checker.php:526
2313
  #: src/admin-views/troubleshooting/ea-status/license-key.php:40
2314
  msgid "License Key"
2315
  msgstr ""
2316
 
2317
+ #: src/Tribe/PUE/Checker.php:535 src/Tribe/PUE/Checker.php:569
2318
  msgid "License Key Status:"
2319
  msgstr ""
2320
 
2321
+ #: src/Tribe/PUE/Checker.php:544
2322
  msgid "Override network license key"
2323
  msgstr ""
2324
 
2325
+ #: src/Tribe/PUE/Checker.php:545
2326
  msgid ""
2327
  "Check this box if you wish to override the network license key with your own"
2328
  msgstr ""
2329
 
2330
+ #: src/Tribe/PUE/Checker.php:556
2331
  msgid "Site License Key"
2332
  msgstr ""
2333
 
2334
+ #: src/Tribe/PUE/Checker.php:656
2335
  msgid "License key(s) updated."
2336
  msgstr ""
2337
 
2338
+ #: src/Tribe/PUE/Checker.php:910
2339
  msgid ""
2340
  "Hmmm... something's wrong with this validator. Please contact %ssupport%s."
2341
  msgstr ""
2342
 
2343
+ #: src/Tribe/PUE/Checker.php:923
2344
  msgid "unknown date"
2345
  msgstr ""
2346
 
2347
+ #: src/Tribe/PUE/Checker.php:929
2348
  msgid "Sorry, key validation server is not available."
2349
  msgstr ""
2350
 
2351
+ #: src/Tribe/PUE/Checker.php:949
2352
  msgid "Valid Key! Expires on %s"
2353
  msgstr ""
2354
 
2355
+ #: src/Tribe/PUE/Checker.php:954
2356
  msgid "Thanks for setting up a valid key. It will expire on %s"
2357
  msgstr ""
2358
 
2359
+ #: src/Tribe/PUE/Checker.php:981 src/Tribe/PUE/Notices.php:342
2360
  msgid "Renew Your License Now"
2361
  msgstr ""
2362
 
2363
+ #: src/Tribe/PUE/Checker.php:983 src/Tribe/PUE/Notices.php:344
2364
  msgid " (opens in a new window)"
2365
  msgstr ""
2366
 
2367
+ #: src/Tribe/PUE/Checker.php:1000
2368
  msgid "Please refresh the page and try your request again."
2369
  msgstr ""
2370
 
2371
+ #: src/Tribe/PUE/Checker.php:1020
2372
  msgid ""
2373
  "There is an update for %s. You'll need to %scheck your license%s to have "
2374
  "access to updates, downloads, and support."
2375
  msgstr ""
2376
 
2377
+ #: src/Tribe/PUE/Checker.php:1077
2378
  msgid ""
2379
  "There is an update for %s. %sRenew your license%s to get access to bug "
2380
  "fixes, security updates, and new features."
2381
  msgstr ""
2382
 
2383
+ #: src/Tribe/PUE/Checker.php:1107
2384
  msgid "Update now to version %s."
2385
  msgstr ""
2386
 
2387
+ #: src/Tribe/PUE/Checker.php:1118
2388
  msgid "There is a new version of %1$s available. %2$s"
2389
  msgstr ""
2390
 
2391
+ #: src/Tribe/PUE/Checker.php:1699
2392
  msgid "A valid license has been entered by your network administrator."
2393
  msgstr ""
2394
 
2395
+ #: src/Tribe/PUE/Checker.php:1700
2396
  msgid "No license entered. Consult your network administrator."
2397
  msgstr ""
2398
 
2399
+ #: src/Tribe/PUE/Checker.php:1701
2400
  msgid "Expired license. Consult your network administrator."
2401
  msgstr ""
2402
 
common/node_modules/intro.js/intro.js DELETED
@@ -1,4421 +0,0 @@
1
- /*!
2
- * Intro.js v3.4.0
3
- * https://introjs.com
4
- *
5
- * Copyright (C) 2012-2021 Afshin Mehrabani (@afshinmeh).
6
- * https://raw.githubusercontent.com/usablica/intro.js/master/license.md
7
- *
8
- * Date: Thu, 25 Mar 2021 09:48:49 GMT
9
- */
10
-
11
- (function (global, factory) {
12
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
13
- typeof define === 'function' && define.amd ? define(factory) :
14
- (global = global || self, global.introJs = factory());
15
- }(this, (function () { 'use strict';
16
-
17
- function _typeof(obj) {
18
- "@babel/helpers - typeof";
19
-
20
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
21
- _typeof = function (obj) {
22
- return typeof obj;
23
- };
24
- } else {
25
- _typeof = function (obj) {
26
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
27
- };
28
- }
29
-
30
- return _typeof(obj);
31
- }
32
-
33
- /**
34
- * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
35
- * via: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
36
- *
37
- * @param obj1
38
- * @param obj2
39
- * @returns obj3 a new object based on obj1 and obj2
40
- */
41
- function mergeOptions(obj1, obj2) {
42
- var obj3 = {};
43
- var attrname;
44
-
45
- for (attrname in obj1) {
46
- obj3[attrname] = obj1[attrname];
47
- }
48
-
49
- for (attrname in obj2) {
50
- obj3[attrname] = obj2[attrname];
51
- }
52
-
53
- return obj3;
54
- }
55
-
56
- /**
57
- * Mark any object with an incrementing number
58
- * used for keeping track of objects
59
- *
60
- * @param Object obj Any object or DOM Element
61
- * @param String key
62
- * @return Object
63
- */
64
- var stamp = function () {
65
- var keys = {};
66
- return function stamp(obj) {
67
- var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "introjs-stamp";
68
- // each group increments from 0
69
- keys[key] = keys[key] || 0; // stamp only once per object
70
-
71
- if (obj[key] === undefined) {
72
- // increment key for each new object
73
- obj[key] = keys[key]++;
74
- }
75
-
76
- return obj[key];
77
- };
78
- }();
79
-
80
- /**
81
- * Iterates arrays
82
- *
83
- * @param {Array} arr
84
- * @param {Function} forEachFnc
85
- * @param {Function} completeFnc
86
- * @return {Null}
87
- */
88
- function forEach(arr, forEachFnc, completeFnc) {
89
- // in case arr is an empty query selector node list
90
- if (arr) {
91
- for (var i = 0, len = arr.length; i < len; i++) {
92
- forEachFnc(arr[i], i);
93
- }
94
- }
95
-
96
- if (typeof completeFnc === "function") {
97
- completeFnc();
98
- }
99
- }
100
-
101
- /**
102
- * DOMEvent Handles all DOM events
103
- *
104
- * methods:
105
- *
106
- * on - add event handler
107
- * off - remove event
108
- */
109
-
110
- var DOMEvent = function () {
111
- function DOMEvent() {
112
- var events_key = "introjs_event";
113
- /**
114
- * Gets a unique ID for an event listener
115
- *
116
- * @param obj Object
117
- * @param type event type
118
- * @param listener Function
119
- * @param context Object
120
- * @return String
121
- */
122
-
123
- this._id = function (obj, type, listener, context) {
124
- return type + stamp(listener) + (context ? "_".concat(stamp(context)) : "");
125
- };
126
- /**
127
- * Adds event listener
128
- *
129
- * @param obj Object obj
130
- * @param type String
131
- * @param listener Function
132
- * @param context Object
133
- * @param useCapture Boolean
134
- * @return null
135
- */
136
-
137
-
138
- this.on = function (obj, type, listener, context, useCapture) {
139
- var id = this._id.apply(this, arguments);
140
-
141
- var handler = function handler(e) {
142
- return listener.call(context || obj, e || window.event);
143
- };
144
-
145
- if ("addEventListener" in obj) {
146
- obj.addEventListener(type, handler, useCapture);
147
- } else if ("attachEvent" in obj) {
148
- obj.attachEvent("on".concat(type), handler);
149
- }
150
-
151
- obj[events_key] = obj[events_key] || {};
152
- obj[events_key][id] = handler;
153
- };
154
- /**
155
- * Removes event listener
156
- *
157
- * @param obj Object
158
- * @param type String
159
- * @param listener Function
160
- * @param context Object
161
- * @param useCapture Boolean
162
- * @return null
163
- */
164
-
165
-
166
- this.off = function (obj, type, listener, context, useCapture) {
167
- var id = this._id.apply(this, arguments);
168
-
169
- var handler = obj[events_key] && obj[events_key][id];
170
-
171
- if (!handler) {
172
- return;
173
- }
174
-
175
- if ("removeEventListener" in obj) {
176
- obj.removeEventListener(type, handler, useCapture);
177
- } else if ("detachEvent" in obj) {
178
- obj.detachEvent("on".concat(type), handler);
179
- }
180
-
181
- obj[events_key][id] = null;
182
- };
183
- }
184
-
185
- return new DOMEvent();
186
- }();
187
-
188
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
189
-
190
- function createCommonjsModule(fn, module) {
191
- return module = { exports: {} }, fn(module, module.exports), module.exports;
192
- }
193
-
194
- var check = function (it) {
195
- return it && it.Math == Math && it;
196
- };
197
-
198
- // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
199
- var global_1 =
200
- /* global globalThis -- safe */
201
- check(typeof globalThis == 'object' && globalThis) ||
202
- check(typeof window == 'object' && window) ||
203
- check(typeof self == 'object' && self) ||
204
- check(typeof commonjsGlobal == 'object' && commonjsGlobal) ||
205
- // eslint-disable-next-line no-new-func -- fallback
206
- (function () { return this; })() || Function('return this')();
207
-
208
- var fails = function (exec) {
209
- try {
210
- return !!exec();
211
- } catch (error) {
212
- return true;
213
- }
214
- };
215
-
216
- // Detect IE8's incomplete defineProperty implementation
217
- var descriptors = !fails(function () {
218
- return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;
219
- });
220
-
221
- var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
222
- var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
223
-
224
- // Nashorn ~ JDK8 bug
225
- var NASHORN_BUG = getOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);
226
-
227
- // `Object.prototype.propertyIsEnumerable` method implementation
228
- // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
229
- var f = NASHORN_BUG ? function propertyIsEnumerable(V) {
230
- var descriptor = getOwnPropertyDescriptor(this, V);
231
- return !!descriptor && descriptor.enumerable;
232
- } : nativePropertyIsEnumerable;
233
-
234
- var objectPropertyIsEnumerable = {
235
- f: f
236
- };
237
-
238
- var createPropertyDescriptor = function (bitmap, value) {
239
- return {
240
- enumerable: !(bitmap & 1),
241
- configurable: !(bitmap & 2),
242
- writable: !(bitmap & 4),
243
- value: value
244
- };
245
- };
246
-
247
- var toString = {}.toString;
248
-
249
- var classofRaw = function (it) {
250
- return toString.call(it).slice(8, -1);
251
- };
252
-
253
- var split = ''.split;
254
-
255
- // fallback for non-array-like ES3 and non-enumerable old V8 strings
256
- var indexedObject = fails(function () {
257
- // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
258
- // eslint-disable-next-line no-prototype-builtins -- safe
259
- return !Object('z').propertyIsEnumerable(0);
260
- }) ? function (it) {
261
- return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
262
- } : Object;
263
-
264
- // `RequireObjectCoercible` abstract operation
265
- // https://tc39.es/ecma262/#sec-requireobjectcoercible
266
- var requireObjectCoercible = function (it) {
267
- if (it == undefined) throw TypeError("Can't call method on " + it);
268
- return it;
269
- };
270
-
271
- // toObject with fallback for non-array-like ES3 strings
272
-
273
-
274
-
275
- var toIndexedObject = function (it) {
276
- return indexedObject(requireObjectCoercible(it));
277
- };
278
-
279
- var isObject = function (it) {
280
- return typeof it === 'object' ? it !== null : typeof it === 'function';
281
- };
282
-
283
- // `ToPrimitive` abstract operation
284
- // https://tc39.es/ecma262/#sec-toprimitive
285
- // instead of the ES6 spec version, we didn't implement @@toPrimitive case
286
- // and the second argument - flag - preferred type is a string
287
- var toPrimitive = function (input, PREFERRED_STRING) {
288
- if (!isObject(input)) return input;
289
- var fn, val;
290
- if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
291
- if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
292
- if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
293
- throw TypeError("Can't convert object to primitive value");
294
- };
295
-
296
- var hasOwnProperty = {}.hasOwnProperty;
297
-
298
- var has = function (it, key) {
299
- return hasOwnProperty.call(it, key);
300
- };
301
-
302
- var document$1 = global_1.document;
303
- // typeof document.createElement is 'object' in old IE
304
- var EXISTS = isObject(document$1) && isObject(document$1.createElement);
305
-
306
- var documentCreateElement = function (it) {
307
- return EXISTS ? document$1.createElement(it) : {};
308
- };
309
-
310
- // Thank's IE8 for his funny defineProperty
311
- var ie8DomDefine = !descriptors && !fails(function () {
312
- return Object.defineProperty(documentCreateElement('div'), 'a', {
313
- get: function () { return 7; }
314
- }).a != 7;
315
- });
316
-
317
- var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
318
-
319
- // `Object.getOwnPropertyDescriptor` method
320
- // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
321
- var f$1 = descriptors ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
322
- O = toIndexedObject(O);
323
- P = toPrimitive(P, true);
324
- if (ie8DomDefine) try {
325
- return nativeGetOwnPropertyDescriptor(O, P);
326
- } catch (error) { /* empty */ }
327
- if (has(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
328
- };
329
-
330
- var objectGetOwnPropertyDescriptor = {
331
- f: f$1
332
- };
333
-
334
- var anObject = function (it) {
335
- if (!isObject(it)) {
336
- throw TypeError(String(it) + ' is not an object');
337
- } return it;
338
- };
339
-
340
- var nativeDefineProperty = Object.defineProperty;
341
-
342
- // `Object.defineProperty` method
343
- // https://tc39.es/ecma262/#sec-object.defineproperty
344
- var f$2 = descriptors ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
345
- anObject(O);
346
- P = toPrimitive(P, true);
347
- anObject(Attributes);
348
- if (ie8DomDefine) try {
349
- return nativeDefineProperty(O, P, Attributes);
350
- } catch (error) { /* empty */ }
351
- if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
352
- if ('value' in Attributes) O[P] = Attributes.value;
353
- return O;
354
- };
355
-
356
- var objectDefineProperty = {
357
- f: f$2
358
- };
359
-
360
- var createNonEnumerableProperty = descriptors ? function (object, key, value) {
361
- return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
362
- } : function (object, key, value) {
363
- object[key] = value;
364
- return object;
365
- };
366
-
367
- var setGlobal = function (key, value) {
368
- try {
369
- createNonEnumerableProperty(global_1, key, value);
370
- } catch (error) {
371
- global_1[key] = value;
372
- } return value;
373
- };
374
-
375
- var SHARED = '__core-js_shared__';
376
- var store = global_1[SHARED] || setGlobal(SHARED, {});
377
-
378
- var sharedStore = store;
379
-
380
- var functionToString = Function.toString;
381
-
382
- // this helper broken in `3.4.1-3.4.4`, so we can't use `shared` helper
383
- if (typeof sharedStore.inspectSource != 'function') {
384
- sharedStore.inspectSource = function (it) {
385
- return functionToString.call(it);
386
- };
387
- }
388
-
389
- var inspectSource = sharedStore.inspectSource;
390
-
391
- var WeakMap = global_1.WeakMap;
392
-
393
- var nativeWeakMap = typeof WeakMap === 'function' && /native code/.test(inspectSource(WeakMap));
394
-
395
- var shared = createCommonjsModule(function (module) {
396
- (module.exports = function (key, value) {
397
- return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
398
- })('versions', []).push({
399
- version: '3.9.1',
400
- mode: 'global',
401
- copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
402
- });
403
- });
404
-
405
- var id = 0;
406
- var postfix = Math.random();
407
-
408
- var uid = function (key) {
409
- return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
410
- };
411
-
412
- var keys = shared('keys');
413
-
414
- var sharedKey = function (key) {
415
- return keys[key] || (keys[key] = uid(key));
416
- };
417
-
418
- var hiddenKeys = {};
419
-
420
- var WeakMap$1 = global_1.WeakMap;
421
- var set, get, has$1;
422
-
423
- var enforce = function (it) {
424
- return has$1(it) ? get(it) : set(it, {});
425
- };
426
-
427
- var getterFor = function (TYPE) {
428
- return function (it) {
429
- var state;
430
- if (!isObject(it) || (state = get(it)).type !== TYPE) {
431
- throw TypeError('Incompatible receiver, ' + TYPE + ' required');
432
- } return state;
433
- };
434
- };
435
-
436
- if (nativeWeakMap) {
437
- var store$1 = sharedStore.state || (sharedStore.state = new WeakMap$1());
438
- var wmget = store$1.get;
439
- var wmhas = store$1.has;
440
- var wmset = store$1.set;
441
- set = function (it, metadata) {
442
- metadata.facade = it;
443
- wmset.call(store$1, it, metadata);
444
- return metadata;
445
- };
446
- get = function (it) {
447
- return wmget.call(store$1, it) || {};
448
- };
449
- has$1 = function (it) {
450
- return wmhas.call(store$1, it);
451
- };
452
- } else {
453
- var STATE = sharedKey('state');
454
- hiddenKeys[STATE] = true;
455
- set = function (it, metadata) {
456
- metadata.facade = it;
457
- createNonEnumerableProperty(it, STATE, metadata);
458
- return metadata;
459
- };
460
- get = function (it) {
461
- return has(it, STATE) ? it[STATE] : {};
462
- };
463
- has$1 = function (it) {
464
- return has(it, STATE);
465
- };
466
- }
467
-
468
- var internalState = {
469
- set: set,
470
- get: get,
471
- has: has$1,
472
- enforce: enforce,
473
- getterFor: getterFor
474
- };
475
-
476
- var redefine = createCommonjsModule(function (module) {
477
- var getInternalState = internalState.get;
478
- var enforceInternalState = internalState.enforce;
479
- var TEMPLATE = String(String).split('String');
480
-
481
- (module.exports = function (O, key, value, options) {
482
- var unsafe = options ? !!options.unsafe : false;
483
- var simple = options ? !!options.enumerable : false;
484
- var noTargetGet = options ? !!options.noTargetGet : false;
485
- var state;
486
- if (typeof value == 'function') {
487
- if (typeof key == 'string' && !has(value, 'name')) {
488
- createNonEnumerableProperty(value, 'name', key);
489
- }
490
- state = enforceInternalState(value);
491
- if (!state.source) {
492
- state.source = TEMPLATE.join(typeof key == 'string' ? key : '');
493
- }
494
- }
495
- if (O === global_1) {
496
- if (simple) O[key] = value;
497
- else setGlobal(key, value);
498
- return;
499
- } else if (!unsafe) {
500
- delete O[key];
501
- } else if (!noTargetGet && O[key]) {
502
- simple = true;
503
- }
504
- if (simple) O[key] = value;
505
- else createNonEnumerableProperty(O, key, value);
506
- // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
507
- })(Function.prototype, 'toString', function toString() {
508
- return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
509
- });
510
- });
511
-
512
- var path = global_1;
513
-
514
- var aFunction = function (variable) {
515
- return typeof variable == 'function' ? variable : undefined;
516
- };
517
-
518
- var getBuiltIn = function (namespace, method) {
519
- return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global_1[namespace])
520
- : path[namespace] && path[namespace][method] || global_1[namespace] && global_1[namespace][method];
521
- };
522
-
523
- var ceil = Math.ceil;
524
- var floor = Math.floor;
525
-
526
- // `ToInteger` abstract operation
527
- // https://tc39.es/ecma262/#sec-tointeger
528
- var toInteger = function (argument) {
529
- return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
530
- };
531
-
532
- var min = Math.min;
533
-
534
- // `ToLength` abstract operation
535
- // https://tc39.es/ecma262/#sec-tolength
536
- var toLength = function (argument) {
537
- return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
538
- };
539
-
540
- var max = Math.max;
541
- var min$1 = Math.min;
542
-
543
- // Helper for a popular repeating case of the spec:
544
- // Let integer be ? ToInteger(index).
545
- // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
546
- var toAbsoluteIndex = function (index, length) {
547
- var integer = toInteger(index);
548
- return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
549
- };
550
-
551
- // `Array.prototype.{ indexOf, includes }` methods implementation
552
- var createMethod = function (IS_INCLUDES) {
553
- return function ($this, el, fromIndex) {
554
- var O = toIndexedObject($this);
555
- var length = toLength(O.length);
556
- var index = toAbsoluteIndex(fromIndex, length);
557
- var value;
558
- // Array#includes uses SameValueZero equality algorithm
559
- // eslint-disable-next-line no-self-compare -- NaN check
560
- if (IS_INCLUDES && el != el) while (length > index) {
561
- value = O[index++];
562
- // eslint-disable-next-line no-self-compare -- NaN check
563
- if (value != value) return true;
564
- // Array#indexOf ignores holes, Array#includes - not
565
- } else for (;length > index; index++) {
566
- if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
567
- } return !IS_INCLUDES && -1;
568
- };
569
- };
570
-
571
- var arrayIncludes = {
572
- // `Array.prototype.includes` method
573
- // https://tc39.es/ecma262/#sec-array.prototype.includes
574
- includes: createMethod(true),
575
- // `Array.prototype.indexOf` method
576
- // https://tc39.es/ecma262/#sec-array.prototype.indexof
577
- indexOf: createMethod(false)
578
- };
579
-
580
- var indexOf = arrayIncludes.indexOf;
581
-
582
-
583
- var objectKeysInternal = function (object, names) {
584
- var O = toIndexedObject(object);
585
- var i = 0;
586
- var result = [];
587
- var key;
588
- for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
589
- // Don't enum bug & hidden keys
590
- while (names.length > i) if (has(O, key = names[i++])) {
591
- ~indexOf(result, key) || result.push(key);
592
- }
593
- return result;
594
- };
595
-
596
- // IE8- don't enum bug keys
597
- var enumBugKeys = [
598
- 'constructor',
599
- 'hasOwnProperty',
600
- 'isPrototypeOf',
601
- 'propertyIsEnumerable',
602
- 'toLocaleString',
603
- 'toString',
604
- 'valueOf'
605
- ];
606
-
607
- var hiddenKeys$1 = enumBugKeys.concat('length', 'prototype');
608
-
609
- // `Object.getOwnPropertyNames` method
610
- // https://tc39.es/ecma262/#sec-object.getownpropertynames
611
- var f$3 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
612
- return objectKeysInternal(O, hiddenKeys$1);
613
- };
614
-
615
- var objectGetOwnPropertyNames = {
616
- f: f$3
617
- };
618
-
619
- var f$4 = Object.getOwnPropertySymbols;
620
-
621
- var objectGetOwnPropertySymbols = {
622
- f: f$4
623
- };
624
-
625
- // all object keys, includes non-enumerable and symbols
626
- var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
627
- var keys = objectGetOwnPropertyNames.f(anObject(it));
628
- var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
629
- return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
630
- };
631
-
632
- var copyConstructorProperties = function (target, source) {
633
- var keys = ownKeys(source);
634
- var defineProperty = objectDefineProperty.f;
635
- var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
636
- for (var i = 0; i < keys.length; i++) {
637
- var key = keys[i];
638
- if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
639
- }
640
- };
641
-
642
- var replacement = /#|\.prototype\./;
643
-
644
- var isForced = function (feature, detection) {
645
- var value = data[normalize(feature)];
646
- return value == POLYFILL ? true
647
- : value == NATIVE ? false
648
- : typeof detection == 'function' ? fails(detection)
649
- : !!detection;
650
- };
651
-
652
- var normalize = isForced.normalize = function (string) {
653
- return String(string).replace(replacement, '.').toLowerCase();
654
- };
655
-
656
- var data = isForced.data = {};
657
- var NATIVE = isForced.NATIVE = 'N';
658
- var POLYFILL = isForced.POLYFILL = 'P';
659
-
660
- var isForced_1 = isForced;
661
-
662
- var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
663
-
664
-
665
-
666
-
667
-
668
-
669
- /*
670
- options.target - name of the target object
671
- options.global - target is the global object
672
- options.stat - export as static methods of target
673
- options.proto - export as prototype methods of target
674
- options.real - real prototype method for the `pure` version
675
- options.forced - export even if the native feature is available
676
- options.bind - bind methods to the target, required for the `pure` version
677
- options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
678
- options.unsafe - use the simple assignment of property instead of delete + defineProperty
679
- options.sham - add a flag to not completely full polyfills
680
- options.enumerable - export as enumerable property
681
- options.noTargetGet - prevent calling a getter on target
682
- */
683
- var _export = function (options, source) {
684
- var TARGET = options.target;
685
- var GLOBAL = options.global;
686
- var STATIC = options.stat;
687
- var FORCED, target, key, targetProperty, sourceProperty, descriptor;
688
- if (GLOBAL) {
689
- target = global_1;
690
- } else if (STATIC) {
691
- target = global_1[TARGET] || setGlobal(TARGET, {});
692
- } else {
693
- target = (global_1[TARGET] || {}).prototype;
694
- }
695
- if (target) for (key in source) {
696
- sourceProperty = source[key];
697
- if (options.noTargetGet) {
698
- descriptor = getOwnPropertyDescriptor$1(target, key);
699
- targetProperty = descriptor && descriptor.value;
700
- } else targetProperty = target[key];
701
- FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
702
- // contained in target
703
- if (!FORCED && targetProperty !== undefined) {
704
- if (typeof sourceProperty === typeof targetProperty) continue;
705
- copyConstructorProperties(sourceProperty, targetProperty);
706
- }
707
- // add a flag to not completely full polyfills
708
- if (options.sham || (targetProperty && targetProperty.sham)) {
709
- createNonEnumerableProperty(sourceProperty, 'sham', true);
710
- }
711
- // extend global
712
- redefine(target, key, sourceProperty, options);
713
- }
714
- };
715
-
716
- // `RegExp.prototype.flags` getter implementation
717
- // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
718
- var regexpFlags = function () {
719
- var that = anObject(this);
720
- var result = '';
721
- if (that.global) result += 'g';
722
- if (that.ignoreCase) result += 'i';
723
- if (that.multiline) result += 'm';
724
- if (that.dotAll) result += 's';
725
- if (that.unicode) result += 'u';
726
- if (that.sticky) result += 'y';
727
- return result;
728
- };
729
-
730
- // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError,
731
- // so we use an intermediate function.
732
- function RE(s, f) {
733
- return RegExp(s, f);
734
- }
735
-
736
- var UNSUPPORTED_Y = fails(function () {
737
- // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError
738
- var re = RE('a', 'y');
739
- re.lastIndex = 2;
740
- return re.exec('abcd') != null;
741
- });
742
-
743
- var BROKEN_CARET = fails(function () {
744
- // https://bugzilla.mozilla.org/show_bug.cgi?id=773687
745
- var re = RE('^r', 'gy');
746
- re.lastIndex = 2;
747
- return re.exec('str') != null;
748
- });
749
-
750
- var regexpStickyHelpers = {
751
- UNSUPPORTED_Y: UNSUPPORTED_Y,
752
- BROKEN_CARET: BROKEN_CARET
753
- };
754
-
755
- var nativeExec = RegExp.prototype.exec;
756
- // This always refers to the native implementation, because the
757
- // String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
758
- // which loads this file before patching the method.
759
- var nativeReplace = String.prototype.replace;
760
-
761
- var patchedExec = nativeExec;
762
-
763
- var UPDATES_LAST_INDEX_WRONG = (function () {
764
- var re1 = /a/;
765
- var re2 = /b*/g;
766
- nativeExec.call(re1, 'a');
767
- nativeExec.call(re2, 'a');
768
- return re1.lastIndex !== 0 || re2.lastIndex !== 0;
769
- })();
770
-
771
- var UNSUPPORTED_Y$1 = regexpStickyHelpers.UNSUPPORTED_Y || regexpStickyHelpers.BROKEN_CARET;
772
-
773
- // nonparticipating capturing group, copied from es5-shim's String#split patch.
774
- // eslint-disable-next-line regexp/no-assertion-capturing-group, regexp/no-empty-group -- required for testing
775
- var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
776
-
777
- var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y$1;
778
-
779
- if (PATCH) {
780
- patchedExec = function exec(str) {
781
- var re = this;
782
- var lastIndex, reCopy, match, i;
783
- var sticky = UNSUPPORTED_Y$1 && re.sticky;
784
- var flags = regexpFlags.call(re);
785
- var source = re.source;
786
- var charsAdded = 0;
787
- var strCopy = str;
788
-
789
- if (sticky) {
790
- flags = flags.replace('y', '');
791
- if (flags.indexOf('g') === -1) {
792
- flags += 'g';
793
- }
794
-
795
- strCopy = String(str).slice(re.lastIndex);
796
- // Support anchored sticky behavior.
797
- if (re.lastIndex > 0 && (!re.multiline || re.multiline && str[re.lastIndex - 1] !== '\n')) {
798
- source = '(?: ' + source + ')';
799
- strCopy = ' ' + strCopy;
800
- charsAdded++;
801
- }
802
- // ^(? + rx + ) is needed, in combination with some str slicing, to
803
- // simulate the 'y' flag.
804
- reCopy = new RegExp('^(?:' + source + ')', flags);
805
- }
806
-
807
- if (NPCG_INCLUDED) {
808
- reCopy = new RegExp('^' + source + '$(?!\\s)', flags);
809
- }
810
- if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
811
-
812
- match = nativeExec.call(sticky ? reCopy : re, strCopy);
813
-
814
- if (sticky) {
815
- if (match) {
816
- match.input = match.input.slice(charsAdded);
817
- match[0] = match[0].slice(charsAdded);
818
- match.index = re.lastIndex;
819
- re.lastIndex += match[0].length;
820
- } else re.lastIndex = 0;
821
- } else if (UPDATES_LAST_INDEX_WRONG && match) {
822
- re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
823
- }
824
- if (NPCG_INCLUDED && match && match.length > 1) {
825
- // Fix browsers whose `exec` methods don't consistently return `undefined`
826
- // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
827
- nativeReplace.call(match[0], reCopy, function () {
828
- for (i = 1; i < arguments.length - 2; i++) {
829
- if (arguments[i] === undefined) match[i] = undefined;
830
- }
831
- });
832
- }
833
-
834
- return match;
835
- };
836
- }
837
-
838
- var regexpExec = patchedExec;
839
-
840
- // `RegExp.prototype.exec` method
841
- // https://tc39.es/ecma262/#sec-regexp.prototype.exec
842
- _export({ target: 'RegExp', proto: true, forced: /./.exec !== regexpExec }, {
843
- exec: regexpExec
844
- });
845
-
846
- var engineIsNode = classofRaw(global_1.process) == 'process';
847
-
848
- var engineUserAgent = getBuiltIn('navigator', 'userAgent') || '';
849
-
850
- var process = global_1.process;
851
- var versions = process && process.versions;
852
- var v8 = versions && versions.v8;
853
- var match, version;
854
-
855
- if (v8) {
856
- match = v8.split('.');
857
- version = match[0] + match[1];
858
- } else if (engineUserAgent) {
859
- match = engineUserAgent.match(/Edge\/(\d+)/);
860
- if (!match || match[1] >= 74) {
861
- match = engineUserAgent.match(/Chrome\/(\d+)/);
862
- if (match) version = match[1];
863
- }
864
- }
865
-
866
- var engineV8Version = version && +version;
867
-
868
- var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
869
- /* global Symbol -- required for testing */
870
- return !Symbol.sham &&
871
- // Chrome 38 Symbol has incorrect toString conversion
872
- // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
873
- (engineIsNode ? engineV8Version === 38 : engineV8Version > 37 && engineV8Version < 41);
874
- });
875
-
876
- var useSymbolAsUid = nativeSymbol
877
- /* global Symbol -- safe */
878
- && !Symbol.sham
879
- && typeof Symbol.iterator == 'symbol';
880
-
881
- var WellKnownSymbolsStore = shared('wks');
882
- var Symbol$1 = global_1.Symbol;
883
- var createWellKnownSymbol = useSymbolAsUid ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid;
884
-
885
- var wellKnownSymbol = function (name) {
886
- if (!has(WellKnownSymbolsStore, name) || !(nativeSymbol || typeof WellKnownSymbolsStore[name] == 'string')) {
887
- if (nativeSymbol && has(Symbol$1, name)) {
888
- WellKnownSymbolsStore[name] = Symbol$1[name];
889
- } else {
890
- WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);
891
- }
892
- } return WellKnownSymbolsStore[name];
893
- };
894
-
895
- // TODO: Remove from `core-js@4` since it's moved to entry points
896
-
897
-
898
-
899
-
900
-
901
-
902
-
903
- var SPECIES = wellKnownSymbol('species');
904
-
905
- var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
906
- // #replace needs built-in support for named groups.
907
- // #match works fine because it just return the exec results, even if it has
908
- // a "grops" property.
909
- var re = /./;
910
- re.exec = function () {
911
- var result = [];
912
- result.groups = { a: '7' };
913
- return result;
914
- };
915
- return ''.replace(re, '$<a>') !== '7';
916
- });
917
-
918
- // IE <= 11 replaces $0 with the whole match, as if it was $&
919
- // https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0
920
- var REPLACE_KEEPS_$0 = (function () {
921
- return 'a'.replace(/./, '$0') === '$0';
922
- })();
923
-
924
- var REPLACE = wellKnownSymbol('replace');
925
- // Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string
926
- var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () {
927
- if (/./[REPLACE]) {
928
- return /./[REPLACE]('a', '$0') === '';
929
- }
930
- return false;
931
- })();
932
-
933
- // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
934
- // Weex JS has frozen built-in prototypes, so use try / catch wrapper
935
- var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
936
- // eslint-disable-next-line regexp/no-empty-group -- required for testing
937
- var re = /(?:)/;
938
- var originalExec = re.exec;
939
- re.exec = function () { return originalExec.apply(this, arguments); };
940
- var result = 'ab'.split(re);
941
- return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
942
- });
943
-
944
- var fixRegexpWellKnownSymbolLogic = function (KEY, length, exec, sham) {
945
- var SYMBOL = wellKnownSymbol(KEY);
946
-
947
- var DELEGATES_TO_SYMBOL = !fails(function () {
948
- // String methods call symbol-named RegEp methods
949
- var O = {};
950
- O[SYMBOL] = function () { return 7; };
951
- return ''[KEY](O) != 7;
952
- });
953
-
954
- var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
955
- // Symbol-named RegExp methods call .exec
956
- var execCalled = false;
957
- var re = /a/;
958
-
959
- if (KEY === 'split') {
960
- // We can't use real regex here since it causes deoptimization
961
- // and serious performance degradation in V8
962
- // https://github.com/zloirock/core-js/issues/306
963
- re = {};
964
- // RegExp[@@split] doesn't call the regex's exec method, but first creates
965
- // a new one. We need to return the patched regex when creating the new one.
966
- re.constructor = {};
967
- re.constructor[SPECIES] = function () { return re; };
968
- re.flags = '';
969
- re[SYMBOL] = /./[SYMBOL];
970
- }
971
-
972
- re.exec = function () { execCalled = true; return null; };
973
-
974
- re[SYMBOL]('');
975
- return !execCalled;
976
- });
977
-
978
- if (
979
- !DELEGATES_TO_SYMBOL ||
980
- !DELEGATES_TO_EXEC ||
981
- (KEY === 'replace' && !(
982
- REPLACE_SUPPORTS_NAMED_GROUPS &&
983
- REPLACE_KEEPS_$0 &&
984
- !REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE
985
- )) ||
986
- (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
987
- ) {
988
- var nativeRegExpMethod = /./[SYMBOL];
989
- var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
990
- if (regexp.exec === regexpExec) {
991
- if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
992
- // The native String method already delegates to @@method (this
993
- // polyfilled function), leasing to infinite recursion.
994
- // We avoid it by directly calling the native @@method method.
995
- return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };
996
- }
997
- return { done: true, value: nativeMethod.call(str, regexp, arg2) };
998
- }
999
- return { done: false };
1000
- }, {
1001
- REPLACE_KEEPS_$0: REPLACE_KEEPS_$0,
1002
- REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE: REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE
1003
- });
1004
- var stringMethod = methods[0];
1005
- var regexMethod = methods[1];
1006
-
1007
- redefine(String.prototype, KEY, stringMethod);
1008
- redefine(RegExp.prototype, SYMBOL, length == 2
1009
- // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
1010
- // 21.2.5.11 RegExp.prototype[@@split](string, limit)
1011
- ? function (string, arg) { return regexMethod.call(string, this, arg); }
1012
- // 21.2.5.6 RegExp.prototype[@@match](string)
1013
- // 21.2.5.9 RegExp.prototype[@@search](string)
1014
- : function (string) { return regexMethod.call(string, this); }
1015
- );
1016
- }
1017
-
1018
- if (sham) createNonEnumerableProperty(RegExp.prototype[SYMBOL], 'sham', true);
1019
- };
1020
-
1021
- // `String.prototype.{ codePointAt, at }` methods implementation
1022
- var createMethod$1 = function (CONVERT_TO_STRING) {
1023
- return function ($this, pos) {
1024
- var S = String(requireObjectCoercible($this));
1025
- var position = toInteger(pos);
1026
- var size = S.length;
1027
- var first, second;
1028
- if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
1029
- first = S.charCodeAt(position);
1030
- return first < 0xD800 || first > 0xDBFF || position + 1 === size
1031
- || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF
1032
- ? CONVERT_TO_STRING ? S.charAt(position) : first
1033
- : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
1034
- };
1035
- };
1036
-
1037
- var stringMultibyte = {
1038
- // `String.prototype.codePointAt` method
1039
- // https://tc39.es/ecma262/#sec-string.prototype.codepointat
1040
- codeAt: createMethod$1(false),
1041
- // `String.prototype.at` method
1042
- // https://github.com/mathiasbynens/String.prototype.at
1043
- charAt: createMethod$1(true)
1044
- };
1045
-
1046
- var charAt = stringMultibyte.charAt;
1047
-
1048
- // `AdvanceStringIndex` abstract operation
1049
- // https://tc39.es/ecma262/#sec-advancestringindex
1050
- var advanceStringIndex = function (S, index, unicode) {
1051
- return index + (unicode ? charAt(S, index).length : 1);
1052
- };
1053
-
1054
- // `RegExpExec` abstract operation
1055
- // https://tc39.es/ecma262/#sec-regexpexec
1056
- var regexpExecAbstract = function (R, S) {
1057
- var exec = R.exec;
1058
- if (typeof exec === 'function') {
1059
- var result = exec.call(R, S);
1060
- if (typeof result !== 'object') {
1061
- throw TypeError('RegExp exec method returned something other than an Object or null');
1062
- }
1063
- return result;
1064
- }
1065
-
1066
- if (classofRaw(R) !== 'RegExp') {
1067
- throw TypeError('RegExp#exec called on incompatible receiver');
1068
- }
1069
-
1070
- return regexpExec.call(R, S);
1071
- };
1072
-
1073
- // @@match logic
1074
- fixRegexpWellKnownSymbolLogic('match', 1, function (MATCH, nativeMatch, maybeCallNative) {
1075
- return [
1076
- // `String.prototype.match` method
1077
- // https://tc39.es/ecma262/#sec-string.prototype.match
1078
- function match(regexp) {
1079
- var O = requireObjectCoercible(this);
1080
- var matcher = regexp == undefined ? undefined : regexp[MATCH];
1081
- return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
1082
- },
1083
- // `RegExp.prototype[@@match]` method
1084
- // https://tc39.es/ecma262/#sec-regexp.prototype-@@match
1085
- function (regexp) {
1086
- var res = maybeCallNative(nativeMatch, regexp, this);
1087
- if (res.done) return res.value;
1088
-
1089
- var rx = anObject(regexp);
1090
- var S = String(this);
1091
-
1092
- if (!rx.global) return regexpExecAbstract(rx, S);
1093
-
1094
- var fullUnicode = rx.unicode;
1095
- rx.lastIndex = 0;
1096
- var A = [];
1097
- var n = 0;
1098
- var result;
1099
- while ((result = regexpExecAbstract(rx, S)) !== null) {
1100
- var matchStr = String(result[0]);
1101
- A[n] = matchStr;
1102
- if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
1103
- n++;
1104
- }
1105
- return n === 0 ? null : A;
1106
- }
1107
- ];
1108
- });
1109
-
1110
- // `IsArray` abstract operation
1111
- // https://tc39.es/ecma262/#sec-isarray
1112
- var isArray = Array.isArray || function isArray(arg) {
1113
- return classofRaw(arg) == 'Array';
1114
- };
1115
-
1116
- // `ToObject` abstract operation
1117
- // https://tc39.es/ecma262/#sec-toobject
1118
- var toObject = function (argument) {
1119
- return Object(requireObjectCoercible(argument));
1120
- };
1121
-
1122
- var createProperty = function (object, key, value) {
1123
- var propertyKey = toPrimitive(key);
1124
- if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));
1125
- else object[propertyKey] = value;
1126
- };
1127
-
1128
- var SPECIES$1 = wellKnownSymbol('species');
1129
-
1130
- // `ArraySpeciesCreate` abstract operation
1131
- // https://tc39.es/ecma262/#sec-arrayspeciescreate
1132
- var arraySpeciesCreate = function (originalArray, length) {
1133
- var C;
1134
- if (isArray(originalArray)) {
1135
- C = originalArray.constructor;
1136
- // cross-realm fallback
1137
- if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
1138
- else if (isObject(C)) {
1139
- C = C[SPECIES$1];
1140
- if (C === null) C = undefined;
1141
- }
1142
- } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
1143
- };
1144
-
1145
- var SPECIES$2 = wellKnownSymbol('species');
1146
-
1147
- var arrayMethodHasSpeciesSupport = function (METHOD_NAME) {
1148
- // We can't use this feature detection in V8 since it causes
1149
- // deoptimization and serious performance degradation
1150
- // https://github.com/zloirock/core-js/issues/677
1151
- return engineV8Version >= 51 || !fails(function () {
1152
- var array = [];
1153
- var constructor = array.constructor = {};
1154
- constructor[SPECIES$2] = function () {
1155
- return { foo: 1 };
1156
- };
1157
- return array[METHOD_NAME](Boolean).foo !== 1;
1158
- });
1159
- };
1160
-
1161
- var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
1162
- var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
1163
- var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';
1164
-
1165
- // We can't use this feature detection in V8 since it causes
1166
- // deoptimization and serious performance degradation
1167
- // https://github.com/zloirock/core-js/issues/679
1168
- var IS_CONCAT_SPREADABLE_SUPPORT = engineV8Version >= 51 || !fails(function () {
1169
- var array = [];
1170
- array[IS_CONCAT_SPREADABLE] = false;
1171
- return array.concat()[0] !== array;
1172
- });
1173
-
1174
- var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
1175
-
1176
- var isConcatSpreadable = function (O) {
1177
- if (!isObject(O)) return false;
1178
- var spreadable = O[IS_CONCAT_SPREADABLE];
1179
- return spreadable !== undefined ? !!spreadable : isArray(O);
1180
- };
1181
-
1182
- var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;
1183
-
1184
- // `Array.prototype.concat` method
1185
- // https://tc39.es/ecma262/#sec-array.prototype.concat
1186
- // with adding support of @@isConcatSpreadable and @@species
1187
- _export({ target: 'Array', proto: true, forced: FORCED }, {
1188
- // eslint-disable-next-line no-unused-vars -- required for `.length`
1189
- concat: function concat(arg) {
1190
- var O = toObject(this);
1191
- var A = arraySpeciesCreate(O, 0);
1192
- var n = 0;
1193
- var i, k, length, len, E;
1194
- for (i = -1, length = arguments.length; i < length; i++) {
1195
- E = i === -1 ? O : arguments[i];
1196
- if (isConcatSpreadable(E)) {
1197
- len = toLength(E.length);
1198
- if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
1199
- for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
1200
- } else {
1201
- if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
1202
- createProperty(A, n++, E);
1203
- }
1204
- }
1205
- A.length = n;
1206
- return A;
1207
- }
1208
- });
1209
-
1210
- var TO_STRING_TAG = wellKnownSymbol('toStringTag');
1211
- var test = {};
1212
-
1213
- test[TO_STRING_TAG] = 'z';
1214
-
1215
- var toStringTagSupport = String(test) === '[object z]';
1216
-
1217
- var TO_STRING_TAG$1 = wellKnownSymbol('toStringTag');
1218
- // ES3 wrong here
1219
- var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';
1220
-
1221
- // fallback for IE11 Script Access Denied error
1222
- var tryGet = function (it, key) {
1223
- try {
1224
- return it[key];
1225
- } catch (error) { /* empty */ }
1226
- };
1227
-
1228
- // getting tag from ES6+ `Object.prototype.toString`
1229
- var classof = toStringTagSupport ? classofRaw : function (it) {
1230
- var O, tag, result;
1231
- return it === undefined ? 'Undefined' : it === null ? 'Null'
1232
- // @@toStringTag case
1233
- : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG$1)) == 'string' ? tag
1234
- // builtinTag case
1235
- : CORRECT_ARGUMENTS ? classofRaw(O)
1236
- // ES3 arguments fallback
1237
- : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
1238
- };
1239
-
1240
- // `Object.prototype.toString` method implementation
1241
- // https://tc39.es/ecma262/#sec-object.prototype.tostring
1242
- var objectToString = toStringTagSupport ? {}.toString : function toString() {
1243
- return '[object ' + classof(this) + ']';
1244
- };
1245
-
1246
- // `Object.prototype.toString` method
1247
- // https://tc39.es/ecma262/#sec-object.prototype.tostring
1248
- if (!toStringTagSupport) {
1249
- redefine(Object.prototype, 'toString', objectToString, { unsafe: true });
1250
- }
1251
-
1252
- var TO_STRING = 'toString';
1253
- var RegExpPrototype = RegExp.prototype;
1254
- var nativeToString = RegExpPrototype[TO_STRING];
1255
-
1256
- var NOT_GENERIC = fails(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; });
1257
- // FF44- RegExp#toString has a wrong name
1258
- var INCORRECT_NAME = nativeToString.name != TO_STRING;
1259
-
1260
- // `RegExp.prototype.toString` method
1261
- // https://tc39.es/ecma262/#sec-regexp.prototype.tostring
1262
- if (NOT_GENERIC || INCORRECT_NAME) {
1263
- redefine(RegExp.prototype, TO_STRING, function toString() {
1264
- var R = anObject(this);
1265
- var p = String(R.source);
1266
- var rf = R.flags;
1267
- var f = String(rf === undefined && R instanceof RegExp && !('flags' in RegExpPrototype) ? regexpFlags.call(R) : rf);
1268
- return '/' + p + '/' + f;
1269
- }, { unsafe: true });
1270
- }
1271
-
1272
- var MATCH = wellKnownSymbol('match');
1273
-
1274
- // `IsRegExp` abstract operation
1275
- // https://tc39.es/ecma262/#sec-isregexp
1276
- var isRegexp = function (it) {
1277
- var isRegExp;
1278
- return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classofRaw(it) == 'RegExp');
1279
- };
1280
-
1281
- var aFunction$1 = function (it) {
1282
- if (typeof it != 'function') {
1283
- throw TypeError(String(it) + ' is not a function');
1284
- } return it;
1285
- };
1286
-
1287
- var SPECIES$3 = wellKnownSymbol('species');
1288
-
1289
- // `SpeciesConstructor` abstract operation
1290
- // https://tc39.es/ecma262/#sec-speciesconstructor
1291
- var speciesConstructor = function (O, defaultConstructor) {
1292
- var C = anObject(O).constructor;
1293
- var S;
1294
- return C === undefined || (S = anObject(C)[SPECIES$3]) == undefined ? defaultConstructor : aFunction$1(S);
1295
- };
1296
-
1297
- var arrayPush = [].push;
1298
- var min$2 = Math.min;
1299
- var MAX_UINT32 = 0xFFFFFFFF;
1300
-
1301
- // babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
1302
- var SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); });
1303
-
1304
- // @@split logic
1305
- fixRegexpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCallNative) {
1306
- var internalSplit;
1307
- if (
1308
- 'abbc'.split(/(b)*/)[1] == 'c' ||
1309
- // eslint-disable-next-line regexp/no-empty-group -- required for testing
1310
- 'test'.split(/(?:)/, -1).length != 4 ||
1311
- 'ab'.split(/(?:ab)*/).length != 2 ||
1312
- '.'.split(/(.?)(.?)/).length != 4 ||
1313
- // eslint-disable-next-line regexp/no-assertion-capturing-group, regexp/no-empty-group -- required for testing
1314
- '.'.split(/()()/).length > 1 ||
1315
- ''.split(/.?/).length
1316
- ) {
1317
- // based on es5-shim implementation, need to rework it
1318
- internalSplit = function (separator, limit) {
1319
- var string = String(requireObjectCoercible(this));
1320
- var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
1321
- if (lim === 0) return [];
1322
- if (separator === undefined) return [string];
1323
- // If `separator` is not a regex, use native split
1324
- if (!isRegexp(separator)) {
1325
- return nativeSplit.call(string, separator, lim);
1326
- }
1327
- var output = [];
1328
- var flags = (separator.ignoreCase ? 'i' : '') +
1329
- (separator.multiline ? 'm' : '') +
1330
- (separator.unicode ? 'u' : '') +
1331
- (separator.sticky ? 'y' : '');
1332
- var lastLastIndex = 0;
1333
- // Make `global` and avoid `lastIndex` issues by working with a copy
1334
- var separatorCopy = new RegExp(separator.source, flags + 'g');
1335
- var match, lastIndex, lastLength;
1336
- while (match = regexpExec.call(separatorCopy, string)) {
1337
- lastIndex = separatorCopy.lastIndex;
1338
- if (lastIndex > lastLastIndex) {
1339
- output.push(string.slice(lastLastIndex, match.index));
1340
- if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));
1341
- lastLength = match[0].length;
1342
- lastLastIndex = lastIndex;
1343
- if (output.length >= lim) break;
1344
- }
1345
- if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
1346
- }
1347
- if (lastLastIndex === string.length) {
1348
- if (lastLength || !separatorCopy.test('')) output.push('');
1349
- } else output.push(string.slice(lastLastIndex));
1350
- return output.length > lim ? output.slice(0, lim) : output;
1351
- };
1352
- // Chakra, V8
1353
- } else if ('0'.split(undefined, 0).length) {
1354
- internalSplit = function (separator, limit) {
1355
- return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);
1356
- };
1357
- } else internalSplit = nativeSplit;
1358
-
1359
- return [
1360
- // `String.prototype.split` method
1361
- // https://tc39.es/ecma262/#sec-string.prototype.split
1362
- function split(separator, limit) {
1363
- var O = requireObjectCoercible(this);
1364
- var splitter = separator == undefined ? undefined : separator[SPLIT];
1365
- return splitter !== undefined
1366
- ? splitter.call(separator, O, limit)
1367
- : internalSplit.call(String(O), separator, limit);
1368
- },
1369
- // `RegExp.prototype[@@split]` method
1370
- // https://tc39.es/ecma262/#sec-regexp.prototype-@@split
1371
- //
1372
- // NOTE: This cannot be properly polyfilled in engines that don't support
1373
- // the 'y' flag.
1374
- function (regexp, limit) {
1375
- var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);
1376
- if (res.done) return res.value;
1377
-
1378
- var rx = anObject(regexp);
1379
- var S = String(this);
1380
- var C = speciesConstructor(rx, RegExp);
1381
-
1382
- var unicodeMatching = rx.unicode;
1383
- var flags = (rx.ignoreCase ? 'i' : '') +
1384
- (rx.multiline ? 'm' : '') +
1385
- (rx.unicode ? 'u' : '') +
1386
- (SUPPORTS_Y ? 'y' : 'g');
1387
-
1388
- // ^(? + rx + ) is needed, in combination with some S slicing, to
1389
- // simulate the 'y' flag.
1390
- var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);
1391
- var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
1392
- if (lim === 0) return [];
1393
- if (S.length === 0) return regexpExecAbstract(splitter, S) === null ? [S] : [];
1394
- var p = 0;
1395
- var q = 0;
1396
- var A = [];
1397
- while (q < S.length) {
1398
- splitter.lastIndex = SUPPORTS_Y ? q : 0;
1399
- var z = regexpExecAbstract(splitter, SUPPORTS_Y ? S : S.slice(q));
1400
- var e;
1401
- if (
1402
- z === null ||
1403
- (e = min$2(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p
1404
- ) {
1405
- q = advanceStringIndex(S, q, unicodeMatching);
1406
- } else {
1407
- A.push(S.slice(p, q));
1408
- if (A.length === lim) return A;
1409
- for (var i = 1; i <= z.length - 1; i++) {
1410
- A.push(z[i]);
1411
- if (A.length === lim) return A;
1412
- }
1413
- q = p = e;
1414
- }
1415
- }
1416
- A.push(S.slice(p));
1417
- return A;
1418
- }
1419
- ];
1420
- }, !SUPPORTS_Y);
1421
-
1422
- /**
1423
- * Append a class to an element
1424
- *
1425
- * @api private
1426
- * @method _addClass
1427
- * @param {Object} element
1428
- * @param {String} className
1429
- * @returns null
1430
- */
1431
-
1432
- function addClass(element, className) {
1433
- if (element instanceof SVGElement) {
1434
- // svg
1435
- var pre = element.getAttribute("class") || "";
1436
-
1437
- if (!pre.match(className)) {
1438
- // check if element doesn't already have className
1439
- element.setAttribute("class", "".concat(pre, " ").concat(className));
1440
- }
1441
- } else {
1442
- if (element.classList !== undefined) {
1443
- // check for modern classList property
1444
- var classes = className.split(" ");
1445
- forEach(classes, function (cls) {
1446
- element.classList.add(cls);
1447
- });
1448
- } else if (!element.className.match(className)) {
1449
- // check if element doesn't already have className
1450
- element.className += " ".concat(className);
1451
- }
1452
- }
1453
- }
1454
-
1455
- /**
1456
- * Get an element CSS property on the page
1457
- * Thanks to JavaScript Kit: http://www.javascriptkit.com/dhtmltutors/dhtmlcascade4.shtml
1458
- *
1459
- * @api private
1460
- * @method _getPropValue
1461
- * @param {Object} element
1462
- * @param {String} propName
1463
- * @returns string property value
1464
- */
1465
- function getPropValue(element, propName) {
1466
- var propValue = "";
1467
-
1468
- if (element.currentStyle) {
1469
- //IE
1470
- propValue = element.currentStyle[propName];
1471
- } else if (document.defaultView && document.defaultView.getComputedStyle) {
1472
- //Others
1473
- propValue = document.defaultView.getComputedStyle(element, null).getPropertyValue(propName);
1474
- } //Prevent exception in IE
1475
-
1476
-
1477
- if (propValue && propValue.toLowerCase) {
1478
- return propValue.toLowerCase();
1479
- } else {
1480
- return propValue;
1481
- }
1482
- }
1483
-
1484
- /**
1485
- * To set the show element
1486
- * This function set a relative (in most cases) position and changes the z-index
1487
- *
1488
- * @api private
1489
- * @method _setShowElement
1490
- * @param {Object} targetElement
1491
- */
1492
-
1493
- function setShowElement(_ref) {
1494
- var element = _ref.element;
1495
- addClass(element, "introjs-showElement");
1496
- var currentElementPosition = getPropValue(element, "position");
1497
-
1498
- if (currentElementPosition !== "absolute" && currentElementPosition !== "relative" && currentElementPosition !== "sticky" && currentElementPosition !== "fixed") {
1499
- //change to new intro item
1500
- addClass(element, "introjs-relativePosition");
1501
- }
1502
- }
1503
-
1504
- /**
1505
- * Find the nearest scrollable parent
1506
- * copied from https://stackoverflow.com/questions/35939886/find-first-scrollable-parent
1507
- *
1508
- * @param Element element
1509
- * @return Element
1510
- */
1511
- function getScrollParent(element) {
1512
- var style = window.getComputedStyle(element);
1513
- var excludeStaticParent = style.position === "absolute";
1514
- var overflowRegex = /(auto|scroll)/;
1515
- if (style.position === "fixed") return document.body;
1516
-
1517
- for (var parent = element; parent = parent.parentElement;) {
1518
- style = window.getComputedStyle(parent);
1519
-
1520
- if (excludeStaticParent && style.position === "static") {
1521
- continue;
1522
- }
1523
-
1524
- if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) return parent;
1525
- }
1526
-
1527
- return document.body;
1528
- }
1529
-
1530
- /**
1531
- * scroll a scrollable element to a child element
1532
- *
1533
- * @param {Object} targetElement
1534
- */
1535
-
1536
- function scrollParentToElement(targetElement) {
1537
- var element = targetElement.element;
1538
- if (!this._options.scrollToElement) return;
1539
- var parent = getScrollParent(element);
1540
- if (parent === document.body) return;
1541
- parent.scrollTop = element.offsetTop - parent.offsetTop;
1542
- }
1543
-
1544
- /**
1545
- * Provides a cross-browser way to get the screen dimensions
1546
- * via: http://stackoverflow.com/questions/5864467/internet-explorer-innerheight
1547
- *
1548
- * @api private
1549
- * @method _getWinSize
1550
- * @returns {Object} width and height attributes
1551
- */
1552
- function getWinSize() {
1553
- if (window.innerWidth !== undefined) {
1554
- return {
1555
- width: window.innerWidth,
1556
- height: window.innerHeight
1557
- };
1558
- } else {
1559
- var D = document.documentElement;
1560
- return {
1561
- width: D.clientWidth,
1562
- height: D.clientHeight
1563
- };
1564
- }
1565
- }
1566
-
1567
- /**
1568
- * Check to see if the element is in the viewport or not
1569
- * http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
1570
- *
1571
- * @api private
1572
- * @method _elementInViewport
1573
- * @param {Object} el
1574
- */
1575
- function elementInViewport(el) {
1576
- var rect = el.getBoundingClientRect();
1577
- return rect.top >= 0 && rect.left >= 0 && rect.bottom + 80 <= window.innerHeight && // add 80 to get the text right
1578
- rect.right <= window.innerWidth;
1579
- }
1580
-
1581
- /**
1582
- * To change the scroll of `window` after highlighting an element
1583
- *
1584
- * @api private
1585
- * @param {String} scrollTo
1586
- * @param {Object} targetElement
1587
- * @param {Object} tooltipLayer
1588
- */
1589
-
1590
- function scrollTo(scrollTo, _ref, tooltipLayer) {
1591
- var element = _ref.element;
1592
- if (scrollTo === "off") return;
1593
- var rect;
1594
- if (!this._options.scrollToElement) return;
1595
-
1596
- if (scrollTo === "tooltip") {
1597
- rect = tooltipLayer.getBoundingClientRect();
1598
- } else {
1599
- rect = element.getBoundingClientRect();
1600
- }
1601
-
1602
- if (!elementInViewport(element)) {
1603
- var winHeight = getWinSize().height;
1604
- var top = rect.bottom - (rect.bottom - rect.top); // TODO (afshinm): do we need scroll padding now?
1605
- // I have changed the scroll option and now it scrolls the window to
1606
- // the center of the target element or tooltip.
1607
-
1608
- if (top < 0 || element.clientHeight > winHeight) {
1609
- window.scrollBy(0, rect.top - (winHeight / 2 - rect.height / 2) - this._options.scrollPadding); // 30px padding from edge to look nice
1610
- //Scroll down
1611
- } else {
1612
- window.scrollBy(0, rect.top - (winHeight / 2 - rect.height / 2) + this._options.scrollPadding); // 30px padding from edge to look nice
1613
- }
1614
- }
1615
- }
1616
-
1617
- /**
1618
- * Setting anchors to behave like buttons
1619
- *
1620
- * @api private
1621
- * @method _setAnchorAsButton
1622
- */
1623
- function setAnchorAsButton(anchor) {
1624
- anchor.setAttribute("role", "button");
1625
- anchor.tabIndex = 0;
1626
- }
1627
-
1628
- // `Object.keys` method
1629
- // https://tc39.es/ecma262/#sec-object.keys
1630
- var objectKeys = Object.keys || function keys(O) {
1631
- return objectKeysInternal(O, enumBugKeys);
1632
- };
1633
-
1634
- var nativeAssign = Object.assign;
1635
- var defineProperty = Object.defineProperty;
1636
-
1637
- // `Object.assign` method
1638
- // https://tc39.es/ecma262/#sec-object.assign
1639
- var objectAssign = !nativeAssign || fails(function () {
1640
- // should have correct order of operations (Edge bug)
1641
- if (descriptors && nativeAssign({ b: 1 }, nativeAssign(defineProperty({}, 'a', {
1642
- enumerable: true,
1643
- get: function () {
1644
- defineProperty(this, 'b', {
1645
- value: 3,
1646
- enumerable: false
1647
- });
1648
- }
1649
- }), { b: 2 })).b !== 1) return true;
1650
- // should work with symbols and should have deterministic property order (V8 bug)
1651
- var A = {};
1652
- var B = {};
1653
- /* global Symbol -- required for testing */
1654
- var symbol = Symbol();
1655
- var alphabet = 'abcdefghijklmnopqrst';
1656
- A[symbol] = 7;
1657
- alphabet.split('').forEach(function (chr) { B[chr] = chr; });
1658
- return nativeAssign({}, A)[symbol] != 7 || objectKeys(nativeAssign({}, B)).join('') != alphabet;
1659
- }) ? function assign(target, source) { // eslint-disable-line no-unused-vars -- required for `.length`
1660
- var T = toObject(target);
1661
- var argumentsLength = arguments.length;
1662
- var index = 1;
1663
- var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
1664
- var propertyIsEnumerable = objectPropertyIsEnumerable.f;
1665
- while (argumentsLength > index) {
1666
- var S = indexedObject(arguments[index++]);
1667
- var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);
1668
- var length = keys.length;
1669
- var j = 0;
1670
- var key;
1671
- while (length > j) {
1672
- key = keys[j++];
1673
- if (!descriptors || propertyIsEnumerable.call(S, key)) T[key] = S[key];
1674
- }
1675
- } return T;
1676
- } : nativeAssign;
1677
-
1678
- // `Object.assign` method
1679
- // https://tc39.es/ecma262/#sec-object.assign
1680
- _export({ target: 'Object', stat: true, forced: Object.assign !== objectAssign }, {
1681
- assign: objectAssign
1682
- });
1683
-
1684
- /**
1685
- * Get an element position on the page relative to another element (or body)
1686
- * Thanks to `meouw`: http://stackoverflow.com/a/442474/375966
1687
- *
1688
- * @api private
1689
- * @method getOffset
1690
- * @param {Object} element
1691
- * @param {Object} relativeEl
1692
- * @returns Element's position info
1693
- */
1694
-
1695
- function getOffset(element, relativeEl) {
1696
- var body = document.body;
1697
- var docEl = document.documentElement;
1698
- var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
1699
- var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
1700
- relativeEl = relativeEl || body;
1701
- var x = element.getBoundingClientRect();
1702
- var xr = relativeEl.getBoundingClientRect();
1703
- var relativeElPosition = getPropValue(relativeEl, "position");
1704
- var obj = {
1705
- width: x.width,
1706
- height: x.height
1707
- };
1708
-
1709
- if (relativeEl.tagName.toLowerCase() !== "body" && relativeElPosition === "relative" || relativeElPosition === "sticky") {
1710
- // when the container of our target element is _not_ body and has either "relative" or "sticky" position, we should not
1711
- // consider the scroll position but we need to include the relative x/y of the container element
1712
- return Object.assign(obj, {
1713
- top: x.top - xr.top,
1714
- left: x.left - xr.left
1715
- });
1716
- } else {
1717
- return Object.assign(obj, {
1718
- top: x.top + scrollTop,
1719
- left: x.left + scrollLeft
1720
- });
1721
- }
1722
- }
1723
-
1724
- /**
1725
- * Checks to see if target element (or parents) position is fixed or not
1726
- *
1727
- * @api private
1728
- * @method _isFixed
1729
- * @param {Object} element
1730
- * @returns Boolean
1731
- */
1732
-
1733
- function isFixed(element) {
1734
- var p = element.parentNode;
1735
-
1736
- if (!p || p.nodeName === "HTML") {
1737
- return false;
1738
- }
1739
-
1740
- if (getPropValue(element, "position") === "fixed") {
1741
- return true;
1742
- }
1743
-
1744
- return isFixed(p);
1745
- }
1746
-
1747
- var floor$1 = Math.floor;
1748
- var replace = ''.replace;
1749
- var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g;
1750
- var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g;
1751
-
1752
- // https://tc39.es/ecma262/#sec-getsubstitution
1753
- var getSubstitution = function (matched, str, position, captures, namedCaptures, replacement) {
1754
- var tailPos = position + matched.length;
1755
- var m = captures.length;
1756
- var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
1757
- if (namedCaptures !== undefined) {
1758
- namedCaptures = toObject(namedCaptures);
1759
- symbols = SUBSTITUTION_SYMBOLS;
1760
- }
1761
- return replace.call(replacement, symbols, function (match, ch) {
1762
- var capture;
1763
- switch (ch.charAt(0)) {
1764
- case '$': return '$';
1765
- case '&': return matched;
1766
- case '`': return str.slice(0, position);
1767
- case "'": return str.slice(tailPos);
1768
- case '<':
1769
- capture = namedCaptures[ch.slice(1, -1)];
1770
- break;
1771
- default: // \d\d?
1772
- var n = +ch;
1773
- if (n === 0) return match;
1774
- if (n > m) {
1775
- var f = floor$1(n / 10);
1776
- if (f === 0) return match;
1777
- if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
1778
- return match;
1779
- }
1780
- capture = captures[n - 1];
1781
- }
1782
- return capture === undefined ? '' : capture;
1783
- });
1784
- };
1785
-
1786
- var max$1 = Math.max;
1787
- var min$3 = Math.min;
1788
-
1789
- var maybeToString = function (it) {
1790
- return it === undefined ? it : String(it);
1791
- };
1792
-
1793
- // @@replace logic
1794
- fixRegexpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative, reason) {
1795
- var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = reason.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE;
1796
- var REPLACE_KEEPS_$0 = reason.REPLACE_KEEPS_$0;
1797
- var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0';
1798
-
1799
- return [
1800
- // `String.prototype.replace` method
1801
- // https://tc39.es/ecma262/#sec-string.prototype.replace
1802
- function replace(searchValue, replaceValue) {
1803
- var O = requireObjectCoercible(this);
1804
- var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
1805
- return replacer !== undefined
1806
- ? replacer.call(searchValue, O, replaceValue)
1807
- : nativeReplace.call(String(O), searchValue, replaceValue);
1808
- },
1809
- // `RegExp.prototype[@@replace]` method
1810
- // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace
1811
- function (regexp, replaceValue) {
1812
- if (
1813
- (!REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE && REPLACE_KEEPS_$0) ||
1814
- (typeof replaceValue === 'string' && replaceValue.indexOf(UNSAFE_SUBSTITUTE) === -1)
1815
- ) {
1816
- var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
1817
- if (res.done) return res.value;
1818
- }
1819
-
1820
- var rx = anObject(regexp);
1821
- var S = String(this);
1822
-
1823
- var functionalReplace = typeof replaceValue === 'function';
1824
- if (!functionalReplace) replaceValue = String(replaceValue);
1825
-
1826
- var global = rx.global;
1827
- if (global) {
1828
- var fullUnicode = rx.unicode;
1829
- rx.lastIndex = 0;
1830
- }
1831
- var results = [];
1832
- while (true) {
1833
- var result = regexpExecAbstract(rx, S);
1834
- if (result === null) break;
1835
-
1836
- results.push(result);
1837
- if (!global) break;
1838
-
1839
- var matchStr = String(result[0]);
1840
- if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
1841
- }
1842
-
1843
- var accumulatedResult = '';
1844
- var nextSourcePosition = 0;
1845
- for (var i = 0; i < results.length; i++) {
1846
- result = results[i];
1847
-
1848
- var matched = String(result[0]);
1849
- var position = max$1(min$3(toInteger(result.index), S.length), 0);
1850
- var captures = [];
1851
- // NOTE: This is equivalent to
1852
- // captures = result.slice(1).map(maybeToString)
1853
- // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
1854
- // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
1855
- // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
1856
- for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
1857
- var namedCaptures = result.groups;
1858
- if (functionalReplace) {
1859
- var replacerArgs = [matched].concat(captures, position, S);
1860
- if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
1861
- var replacement = String(replaceValue.apply(undefined, replacerArgs));
1862
- } else {
1863
- replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
1864
- }
1865
- if (position >= nextSourcePosition) {
1866
- accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
1867
- nextSourcePosition = position + matched.length;
1868
- }
1869
- }
1870
- return accumulatedResult + S.slice(nextSourcePosition);
1871
- }
1872
- ];
1873
- });
1874
-
1875
- /**
1876
- * Remove a class from an element
1877
- *
1878
- * @api private
1879
- * @method _removeClass
1880
- * @param {Object} element
1881
- * @param {RegExp|String} classNameRegex can be regex or string
1882
- * @returns null
1883
- */
1884
- function removeClass(element, classNameRegex) {
1885
- if (element instanceof SVGElement) {
1886
- var pre = element.getAttribute("class") || "";
1887
- element.setAttribute("class", pre.replace(classNameRegex, "").replace(/^\s+|\s+$/g, ""));
1888
- } else {
1889
- element.className = element.className.replace(classNameRegex, "").replace(/^\s+|\s+$/g, "");
1890
- }
1891
- }
1892
-
1893
- /**
1894
- * Sets the style of an DOM element
1895
- *
1896
- * @param {Object} element
1897
- * @param {Object|string} style
1898
- * @return null
1899
- */
1900
- function setStyle(element, style) {
1901
- var cssText = "";
1902
-
1903
- if (element.style.cssText) {
1904
- cssText += element.style.cssText;
1905
- }
1906
-
1907
- if (typeof style === "string") {
1908
- cssText += style;
1909
- } else {
1910
- for (var rule in style) {
1911
- cssText += "".concat(rule, ":").concat(style[rule], ";");
1912
- }
1913
- }
1914
-
1915
- element.style.cssText = cssText;
1916
- }
1917
-
1918
- /**
1919
- * Update the position of the helper layer on the screen
1920
- *
1921
- * @api private
1922
- * @method _setHelperLayerPosition
1923
- * @param {Object} helperLayer
1924
- */
1925
-
1926
- function setHelperLayerPosition(helperLayer) {
1927
- if (helperLayer) {
1928
- //prevent error when `this._currentStep` in undefined
1929
- if (!this._introItems[this._currentStep]) return;
1930
- var currentElement = this._introItems[this._currentStep];
1931
- var elementPosition = getOffset(currentElement.element, this._targetElement);
1932
- var widthHeightPadding = this._options.helperElementPadding; // If the target element is fixed, the tooltip should be fixed as well.
1933
- // Otherwise, remove a fixed class that may be left over from the previous
1934
- // step.
1935
-
1936
- if (isFixed(currentElement.element)) {
1937
- addClass(helperLayer, "introjs-fixedTooltip");
1938
- } else {
1939
- removeClass(helperLayer, "introjs-fixedTooltip");
1940
- }
1941
-
1942
- if (currentElement.position === "floating") {
1943
- widthHeightPadding = 0;
1944
- } //set new position to helper layer
1945
-
1946
-
1947
- setStyle(helperLayer, {
1948
- width: "".concat(elementPosition.width + widthHeightPadding, "px"),
1949
- height: "".concat(elementPosition.height + widthHeightPadding, "px"),
1950
- top: "".concat(elementPosition.top - widthHeightPadding / 2, "px"),
1951
- left: "".concat(elementPosition.left - widthHeightPadding / 2, "px")
1952
- });
1953
- }
1954
- }
1955
-
1956
- // `Object.defineProperties` method
1957
- // https://tc39.es/ecma262/#sec-object.defineproperties
1958
- var objectDefineProperties = descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
1959
- anObject(O);
1960
- var keys = objectKeys(Properties);
1961
- var length = keys.length;
1962
- var index = 0;
1963
- var key;
1964
- while (length > index) objectDefineProperty.f(O, key = keys[index++], Properties[key]);
1965
- return O;
1966
- };
1967
-
1968
- var html = getBuiltIn('document', 'documentElement');
1969
-
1970
- var GT = '>';
1971
- var LT = '<';
1972
- var PROTOTYPE = 'prototype';
1973
- var SCRIPT = 'script';
1974
- var IE_PROTO = sharedKey('IE_PROTO');
1975
-
1976
- var EmptyConstructor = function () { /* empty */ };
1977
-
1978
- var scriptTag = function (content) {
1979
- return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
1980
- };
1981
-
1982
- // Create object with fake `null` prototype: use ActiveX Object with cleared prototype
1983
- var NullProtoObjectViaActiveX = function (activeXDocument) {
1984
- activeXDocument.write(scriptTag(''));
1985
- activeXDocument.close();
1986
- var temp = activeXDocument.parentWindow.Object;
1987
- activeXDocument = null; // avoid memory leak
1988
- return temp;
1989
- };
1990
-
1991
- // Create object with fake `null` prototype: use iframe Object with cleared prototype
1992
- var NullProtoObjectViaIFrame = function () {
1993
- // Thrash, waste and sodomy: IE GC bug
1994
- var iframe = documentCreateElement('iframe');
1995
- var JS = 'java' + SCRIPT + ':';
1996
- var iframeDocument;
1997
- iframe.style.display = 'none';
1998
- html.appendChild(iframe);
1999
- // https://github.com/zloirock/core-js/issues/475
2000
- iframe.src = String(JS);
2001
- iframeDocument = iframe.contentWindow.document;
2002
- iframeDocument.open();
2003
- iframeDocument.write(scriptTag('document.F=Object'));
2004
- iframeDocument.close();
2005
- return iframeDocument.F;
2006
- };
2007
-
2008
- // Check for document.domain and active x support
2009
- // No need to use active x approach when document.domain is not set
2010
- // see https://github.com/es-shims/es5-shim/issues/150
2011
- // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
2012
- // avoid IE GC bug
2013
- var activeXDocument;
2014
- var NullProtoObject = function () {
2015
- try {
2016
- /* global ActiveXObject -- old IE */
2017
- activeXDocument = document.domain && new ActiveXObject('htmlfile');
2018
- } catch (error) { /* ignore */ }
2019
- NullProtoObject = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame();
2020
- var length = enumBugKeys.length;
2021
- while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];
2022
- return NullProtoObject();
2023
- };
2024
-
2025
- hiddenKeys[IE_PROTO] = true;
2026
-
2027
- // `Object.create` method
2028
- // https://tc39.es/ecma262/#sec-object.create
2029
- var objectCreate = Object.create || function create(O, Properties) {
2030
- var result;
2031
- if (O !== null) {
2032
- EmptyConstructor[PROTOTYPE] = anObject(O);
2033
- result = new EmptyConstructor();
2034
- EmptyConstructor[PROTOTYPE] = null;
2035
- // add "__proto__" for Object.getPrototypeOf polyfill
2036
- result[IE_PROTO] = O;
2037
- } else result = NullProtoObject();
2038
- return Properties === undefined ? result : objectDefineProperties(result, Properties);
2039
- };
2040
-
2041
- var UNSCOPABLES = wellKnownSymbol('unscopables');
2042
- var ArrayPrototype = Array.prototype;
2043
-
2044
- // Array.prototype[@@unscopables]
2045
- // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
2046
- if (ArrayPrototype[UNSCOPABLES] == undefined) {
2047
- objectDefineProperty.f(ArrayPrototype, UNSCOPABLES, {
2048
- configurable: true,
2049
- value: objectCreate(null)
2050
- });
2051
- }
2052
-
2053
- // add a key to Array.prototype[@@unscopables]
2054
- var addToUnscopables = function (key) {
2055
- ArrayPrototype[UNSCOPABLES][key] = true;
2056
- };
2057
-
2058
- var $includes = arrayIncludes.includes;
2059
-
2060
-
2061
- // `Array.prototype.includes` method
2062
- // https://tc39.es/ecma262/#sec-array.prototype.includes
2063
- _export({ target: 'Array', proto: true }, {
2064
- includes: function includes(el /* , fromIndex = 0 */) {
2065
- return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
2066
- }
2067
- });
2068
-
2069
- // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
2070
- addToUnscopables('includes');
2071
-
2072
- var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('slice');
2073
-
2074
- var SPECIES$4 = wellKnownSymbol('species');
2075
- var nativeSlice = [].slice;
2076
- var max$2 = Math.max;
2077
-
2078
- // `Array.prototype.slice` method
2079
- // https://tc39.es/ecma262/#sec-array.prototype.slice
2080
- // fallback for not array-like ES3 strings and DOM objects
2081
- _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {
2082
- slice: function slice(start, end) {
2083
- var O = toIndexedObject(this);
2084
- var length = toLength(O.length);
2085
- var k = toAbsoluteIndex(start, length);
2086
- var fin = toAbsoluteIndex(end === undefined ? length : end, length);
2087
- // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible
2088
- var Constructor, result, n;
2089
- if (isArray(O)) {
2090
- Constructor = O.constructor;
2091
- // cross-realm fallback
2092
- if (typeof Constructor == 'function' && (Constructor === Array || isArray(Constructor.prototype))) {
2093
- Constructor = undefined;
2094
- } else if (isObject(Constructor)) {
2095
- Constructor = Constructor[SPECIES$4];
2096
- if (Constructor === null) Constructor = undefined;
2097
- }
2098
- if (Constructor === Array || Constructor === undefined) {
2099
- return nativeSlice.call(O, k, fin);
2100
- }
2101
- }
2102
- result = new (Constructor === undefined ? Array : Constructor)(max$2(fin - k, 0));
2103
- for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);
2104
- result.length = n;
2105
- return result;
2106
- }
2107
- });
2108
-
2109
- var notARegexp = function (it) {
2110
- if (isRegexp(it)) {
2111
- throw TypeError("The method doesn't accept regular expressions");
2112
- } return it;
2113
- };
2114
-
2115
- var MATCH$1 = wellKnownSymbol('match');
2116
-
2117
- var correctIsRegexpLogic = function (METHOD_NAME) {
2118
- var regexp = /./;
2119
- try {
2120
- '/./'[METHOD_NAME](regexp);
2121
- } catch (error1) {
2122
- try {
2123
- regexp[MATCH$1] = false;
2124
- return '/./'[METHOD_NAME](regexp);
2125
- } catch (error2) { /* empty */ }
2126
- } return false;
2127
- };
2128
-
2129
- // `String.prototype.includes` method
2130
- // https://tc39.es/ecma262/#sec-string.prototype.includes
2131
- _export({ target: 'String', proto: true, forced: !correctIsRegexpLogic('includes') }, {
2132
- includes: function includes(searchString /* , position = 0 */) {
2133
- return !!~String(requireObjectCoercible(this))
2134
- .indexOf(notARegexp(searchString), arguments.length > 1 ? arguments[1] : undefined);
2135
- }
2136
- });
2137
-
2138
- var arrayMethodIsStrict = function (METHOD_NAME, argument) {
2139
- var method = [][METHOD_NAME];
2140
- return !!method && fails(function () {
2141
- // eslint-disable-next-line no-useless-call,no-throw-literal -- required for testing
2142
- method.call(null, argument || function () { throw 1; }, 1);
2143
- });
2144
- };
2145
-
2146
- var nativeJoin = [].join;
2147
-
2148
- var ES3_STRINGS = indexedObject != Object;
2149
- var STRICT_METHOD = arrayMethodIsStrict('join', ',');
2150
-
2151
- // `Array.prototype.join` method
2152
- // https://tc39.es/ecma262/#sec-array.prototype.join
2153
- _export({ target: 'Array', proto: true, forced: ES3_STRINGS || !STRICT_METHOD }, {
2154
- join: function join(separator) {
2155
- return nativeJoin.call(toIndexedObject(this), separator === undefined ? ',' : separator);
2156
- }
2157
- });
2158
-
2159
- // optional / simple context binding
2160
- var functionBindContext = function (fn, that, length) {
2161
- aFunction$1(fn);
2162
- if (that === undefined) return fn;
2163
- switch (length) {
2164
- case 0: return function () {
2165
- return fn.call(that);
2166
- };
2167
- case 1: return function (a) {
2168
- return fn.call(that, a);
2169
- };
2170
- case 2: return function (a, b) {
2171
- return fn.call(that, a, b);
2172
- };
2173
- case 3: return function (a, b, c) {
2174
- return fn.call(that, a, b, c);
2175
- };
2176
- }
2177
- return function (/* ...args */) {
2178
- return fn.apply(that, arguments);
2179
- };
2180
- };
2181
-
2182
- var push = [].push;
2183
-
2184
- // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterOut }` methods implementation
2185
- var createMethod$2 = function (TYPE) {
2186
- var IS_MAP = TYPE == 1;
2187
- var IS_FILTER = TYPE == 2;
2188
- var IS_SOME = TYPE == 3;
2189
- var IS_EVERY = TYPE == 4;
2190
- var IS_FIND_INDEX = TYPE == 6;
2191
- var IS_FILTER_OUT = TYPE == 7;
2192
- var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
2193
- return function ($this, callbackfn, that, specificCreate) {
2194
- var O = toObject($this);
2195
- var self = indexedObject(O);
2196
- var boundFunction = functionBindContext(callbackfn, that, 3);
2197
- var length = toLength(self.length);
2198
- var index = 0;
2199
- var create = specificCreate || arraySpeciesCreate;
2200
- var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_OUT ? create($this, 0) : undefined;
2201
- var value, result;
2202
- for (;length > index; index++) if (NO_HOLES || index in self) {
2203
- value = self[index];
2204
- result = boundFunction(value, index, O);
2205
- if (TYPE) {
2206
- if (IS_MAP) target[index] = result; // map
2207
- else if (result) switch (TYPE) {
2208
- case 3: return true; // some
2209
- case 5: return value; // find
2210
- case 6: return index; // findIndex
2211
- case 2: push.call(target, value); // filter
2212
- } else switch (TYPE) {
2213
- case 4: return false; // every
2214
- case 7: push.call(target, value); // filterOut
2215
- }
2216
- }
2217
- }
2218
- return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
2219
- };
2220
- };
2221
-
2222
- var arrayIteration = {
2223
- // `Array.prototype.forEach` method
2224
- // https://tc39.es/ecma262/#sec-array.prototype.foreach
2225
- forEach: createMethod$2(0),
2226
- // `Array.prototype.map` method
2227
- // https://tc39.es/ecma262/#sec-array.prototype.map
2228
- map: createMethod$2(1),
2229
- // `Array.prototype.filter` method
2230
- // https://tc39.es/ecma262/#sec-array.prototype.filter
2231
- filter: createMethod$2(2),
2232
- // `Array.prototype.some` method
2233
- // https://tc39.es/ecma262/#sec-array.prototype.some
2234
- some: createMethod$2(3),
2235
- // `Array.prototype.every` method
2236
- // https://tc39.es/ecma262/#sec-array.prototype.every
2237
- every: createMethod$2(4),
2238
- // `Array.prototype.find` method
2239
- // https://tc39.es/ecma262/#sec-array.prototype.find
2240
- find: createMethod$2(5),
2241
- // `Array.prototype.findIndex` method
2242
- // https://tc39.es/ecma262/#sec-array.prototype.findIndex
2243
- findIndex: createMethod$2(6),
2244
- // `Array.prototype.filterOut` method
2245
- // https://github.com/tc39/proposal-array-filtering
2246
- filterOut: createMethod$2(7)
2247
- };
2248
-
2249
- var $filter = arrayIteration.filter;
2250
-
2251
-
2252
- var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport('filter');
2253
-
2254
- // `Array.prototype.filter` method
2255
- // https://tc39.es/ecma262/#sec-array.prototype.filter
2256
- // with adding support of @@species
2257
- _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$1 }, {
2258
- filter: function filter(callbackfn /* , thisArg */) {
2259
- return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
2260
- }
2261
- });
2262
-
2263
- /**
2264
- * Set tooltip left so it doesn't go off the right side of the window
2265
- *
2266
- * @return boolean true, if tooltipLayerStyleLeft is ok. false, otherwise.
2267
- */
2268
- function checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer) {
2269
- if (targetOffset.left + tooltipLayerStyleLeft + tooltipOffset.width > windowSize.width) {
2270
- // off the right side of the window
2271
- tooltipLayer.style.left = "".concat(windowSize.width - tooltipOffset.width - targetOffset.left, "px");
2272
- return false;
2273
- }
2274
-
2275
- tooltipLayer.style.left = "".concat(tooltipLayerStyleLeft, "px");
2276
- return true;
2277
- }
2278
-
2279
- /**
2280
- * Set tooltip right so it doesn't go off the left side of the window
2281
- *
2282
- * @return boolean true, if tooltipLayerStyleRight is ok. false, otherwise.
2283
- */
2284
- function checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer) {
2285
- if (targetOffset.left + targetOffset.width - tooltipLayerStyleRight - tooltipOffset.width < 0) {
2286
- // off the left side of the window
2287
- tooltipLayer.style.left = "".concat(-targetOffset.left, "px");
2288
- return false;
2289
- }
2290
-
2291
- tooltipLayer.style.right = "".concat(tooltipLayerStyleRight, "px");
2292
- return true;
2293
- }
2294
-
2295
- var HAS_SPECIES_SUPPORT$2 = arrayMethodHasSpeciesSupport('splice');
2296
-
2297
- var max$3 = Math.max;
2298
- var min$4 = Math.min;
2299
- var MAX_SAFE_INTEGER$1 = 0x1FFFFFFFFFFFFF;
2300
- var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded';
2301
-
2302
- // `Array.prototype.splice` method
2303
- // https://tc39.es/ecma262/#sec-array.prototype.splice
2304
- // with adding support of @@species
2305
- _export({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$2 }, {
2306
- splice: function splice(start, deleteCount /* , ...items */) {
2307
- var O = toObject(this);
2308
- var len = toLength(O.length);
2309
- var actualStart = toAbsoluteIndex(start, len);
2310
- var argumentsLength = arguments.length;
2311
- var insertCount, actualDeleteCount, A, k, from, to;
2312
- if (argumentsLength === 0) {
2313
- insertCount = actualDeleteCount = 0;
2314
- } else if (argumentsLength === 1) {
2315
- insertCount = 0;
2316
- actualDeleteCount = len - actualStart;
2317
- } else {
2318
- insertCount = argumentsLength - 2;
2319
- actualDeleteCount = min$4(max$3(toInteger(deleteCount), 0), len - actualStart);
2320
- }
2321
- if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER$1) {
2322
- throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
2323
- }
2324
- A = arraySpeciesCreate(O, actualDeleteCount);
2325
- for (k = 0; k < actualDeleteCount; k++) {
2326
- from = actualStart + k;
2327
- if (from in O) createProperty(A, k, O[from]);
2328
- }
2329
- A.length = actualDeleteCount;
2330
- if (insertCount < actualDeleteCount) {
2331
- for (k = actualStart; k < len - actualDeleteCount; k++) {
2332
- from = k + actualDeleteCount;
2333
- to = k + insertCount;
2334
- if (from in O) O[to] = O[from];
2335
- else delete O[to];
2336
- }
2337
- for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];
2338
- } else if (insertCount > actualDeleteCount) {
2339
- for (k = len - actualDeleteCount; k > actualStart; k--) {
2340
- from = k + actualDeleteCount - 1;
2341
- to = k + insertCount - 1;
2342
- if (from in O) O[to] = O[from];
2343
- else delete O[to];
2344
- }
2345
- }
2346
- for (k = 0; k < insertCount; k++) {
2347
- O[k + actualStart] = arguments[k + 2];
2348
- }
2349
- O.length = len - actualDeleteCount + insertCount;
2350
- return A;
2351
- }
2352
- });
2353
-
2354
- /**
2355
- * Remove an entry from a string array if it's there, does nothing if it isn't there.
2356
- *
2357
- * @param {Array} stringArray
2358
- * @param {String} stringToRemove
2359
- */
2360
- function removeEntry(stringArray, stringToRemove) {
2361
- if (stringArray.includes(stringToRemove)) {
2362
- stringArray.splice(stringArray.indexOf(stringToRemove), 1);
2363
- }
2364
- }
2365
-
2366
- /**
2367
- * auto-determine alignment
2368
- * @param {Integer} offsetLeft
2369
- * @param {Integer} tooltipWidth
2370
- * @param {Object} windowSize
2371
- * @param {String} desiredAlignment
2372
- * @return {String} calculatedAlignment
2373
- */
2374
-
2375
- function _determineAutoAlignment(offsetLeft, tooltipWidth, _ref, desiredAlignment) {
2376
- var width = _ref.width;
2377
- var halfTooltipWidth = tooltipWidth / 2;
2378
- var winWidth = Math.min(width, window.screen.width);
2379
- var possibleAlignments = ["-left-aligned", "-middle-aligned", "-right-aligned"];
2380
- var calculatedAlignment = ""; // valid left must be at least a tooltipWidth
2381
- // away from right side
2382
-
2383
- if (winWidth - offsetLeft < tooltipWidth) {
2384
- removeEntry(possibleAlignments, "-left-aligned");
2385
- } // valid middle must be at least half
2386
- // width away from both sides
2387
-
2388
-
2389
- if (offsetLeft < halfTooltipWidth || winWidth - offsetLeft < halfTooltipWidth) {
2390
- removeEntry(possibleAlignments, "-middle-aligned");
2391
- } // valid right must be at least a tooltipWidth
2392
- // width away from left side
2393
-
2394
-
2395
- if (offsetLeft < tooltipWidth) {
2396
- removeEntry(possibleAlignments, "-right-aligned");
2397
- }
2398
-
2399
- if (possibleAlignments.length) {
2400
- if (possibleAlignments.includes(desiredAlignment)) {
2401
- // the desired alignment is valid
2402
- calculatedAlignment = desiredAlignment;
2403
- } else {
2404
- // pick the first valid position, in order
2405
- calculatedAlignment = possibleAlignments[0];
2406
- }
2407
- } else {
2408
- // if screen width is too small
2409
- // for ANY alignment, middle is
2410
- // probably the best for visibility
2411
- calculatedAlignment = "-middle-aligned";
2412
- }
2413
-
2414
- return calculatedAlignment;
2415
- }
2416
- /**
2417
- * Determines the position of the tooltip based on the position precedence and availability
2418
- * of screen space.
2419
- *
2420
- * @param {Object} targetElement
2421
- * @param {Object} tooltipLayer
2422
- * @param {String} desiredTooltipPosition
2423
- * @return {String} calculatedPosition
2424
- */
2425
-
2426
-
2427
- function _determineAutoPosition(targetElement, tooltipLayer, desiredTooltipPosition) {
2428
- // Take a clone of position precedence. These will be the available
2429
- var possiblePositions = this._options.positionPrecedence.slice();
2430
-
2431
- var windowSize = getWinSize();
2432
- var tooltipHeight = getOffset(tooltipLayer).height + 10;
2433
- var tooltipWidth = getOffset(tooltipLayer).width + 20;
2434
- var targetElementRect = targetElement.getBoundingClientRect(); // If we check all the possible areas, and there are no valid places for the tooltip, the element
2435
- // must take up most of the screen real estate. Show the tooltip floating in the middle of the screen.
2436
-
2437
- var calculatedPosition = "floating";
2438
- /*
2439
- * auto determine position
2440
- */
2441
- // Check for space below
2442
-
2443
- if (targetElementRect.bottom + tooltipHeight > windowSize.height) {
2444
- removeEntry(possiblePositions, "bottom");
2445
- } // Check for space above
2446
-
2447
-
2448
- if (targetElementRect.top - tooltipHeight < 0) {
2449
- removeEntry(possiblePositions, "top");
2450
- } // Check for space to the right
2451
-
2452
-
2453
- if (targetElementRect.right + tooltipWidth > windowSize.width) {
2454
- removeEntry(possiblePositions, "right");
2455
- } // Check for space to the left
2456
-
2457
-
2458
- if (targetElementRect.left - tooltipWidth < 0) {
2459
- removeEntry(possiblePositions, "left");
2460
- } // @var {String} ex: 'right-aligned'
2461
-
2462
-
2463
- var desiredAlignment = function (pos) {
2464
- var hyphenIndex = pos.indexOf("-");
2465
-
2466
- if (hyphenIndex !== -1) {
2467
- // has alignment
2468
- return pos.substr(hyphenIndex);
2469
- }
2470
-
2471
- return "";
2472
- }(desiredTooltipPosition || ""); // strip alignment from position
2473
-
2474
-
2475
- if (desiredTooltipPosition) {
2476
- // ex: "bottom-right-aligned"
2477
- // should return 'bottom'
2478
- desiredTooltipPosition = desiredTooltipPosition.split("-")[0];
2479
- }
2480
-
2481
- if (possiblePositions.length) {
2482
- if (possiblePositions.includes(desiredTooltipPosition)) {
2483
- // If the requested position is in the list, choose that
2484
- calculatedPosition = desiredTooltipPosition;
2485
- } else {
2486
- // Pick the first valid position, in order
2487
- calculatedPosition = possiblePositions[0];
2488
- }
2489
- } // only top and bottom positions have optional alignments
2490
-
2491
-
2492
- if (["top", "bottom"].includes(calculatedPosition)) {
2493
- calculatedPosition += _determineAutoAlignment(targetElementRect.left, tooltipWidth, windowSize, desiredAlignment);
2494
- }
2495
-
2496
- return calculatedPosition;
2497
- }
2498
- /**
2499
- * Render tooltip box in the page
2500
- *
2501
- * @api private
2502
- * @method placeTooltip
2503
- * @param {HTMLElement} targetElement
2504
- * @param {HTMLElement} tooltipLayer
2505
- * @param {HTMLElement} arrowLayer
2506
- * @param {Boolean} hintMode
2507
- */
2508
-
2509
-
2510
- function placeTooltip(targetElement, tooltipLayer, arrowLayer, hintMode) {
2511
- var tooltipCssClass = "";
2512
- var currentStepObj;
2513
- var tooltipOffset;
2514
- var targetOffset;
2515
- var windowSize;
2516
- var currentTooltipPosition;
2517
- hintMode = hintMode || false; //reset the old style
2518
-
2519
- tooltipLayer.style.top = null;
2520
- tooltipLayer.style.right = null;
2521
- tooltipLayer.style.bottom = null;
2522
- tooltipLayer.style.left = null;
2523
- tooltipLayer.style.marginLeft = null;
2524
- tooltipLayer.style.marginTop = null;
2525
- arrowLayer.style.display = "inherit"; //prevent error when `this._currentStep` is undefined
2526
-
2527
- if (!this._introItems[this._currentStep]) return; //if we have a custom css class for each step
2528
-
2529
- currentStepObj = this._introItems[this._currentStep];
2530
-
2531
- if (typeof currentStepObj.tooltipClass === "string") {
2532
- tooltipCssClass = currentStepObj.tooltipClass;
2533
- } else {
2534
- tooltipCssClass = this._options.tooltipClass;
2535
- }
2536
-
2537
- tooltipLayer.className = ["introjs-tooltip", tooltipCssClass].filter(Boolean).join(" ");
2538
- tooltipLayer.setAttribute("role", "dialog");
2539
- currentTooltipPosition = this._introItems[this._currentStep].position; // Floating is always valid, no point in calculating
2540
-
2541
- if (currentTooltipPosition !== "floating" && this._options.autoPosition) {
2542
- currentTooltipPosition = _determineAutoPosition.call(this, targetElement, tooltipLayer, currentTooltipPosition);
2543
- }
2544
-
2545
- var tooltipLayerStyleLeft;
2546
- targetOffset = getOffset(targetElement);
2547
- tooltipOffset = getOffset(tooltipLayer);
2548
- windowSize = getWinSize();
2549
- addClass(tooltipLayer, "introjs-".concat(currentTooltipPosition));
2550
-
2551
- switch (currentTooltipPosition) {
2552
- case "top-right-aligned":
2553
- arrowLayer.className = "introjs-arrow bottom-right";
2554
- var tooltipLayerStyleRight = 0;
2555
- checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer);
2556
- tooltipLayer.style.bottom = "".concat(targetOffset.height + 20, "px");
2557
- break;
2558
-
2559
- case "top-middle-aligned":
2560
- arrowLayer.className = "introjs-arrow bottom-middle";
2561
- var tooltipLayerStyleLeftRight = targetOffset.width / 2 - tooltipOffset.width / 2; // a fix for middle aligned hints
2562
-
2563
- if (hintMode) {
2564
- tooltipLayerStyleLeftRight += 5;
2565
- }
2566
-
2567
- if (checkLeft(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, tooltipLayer)) {
2568
- tooltipLayer.style.right = null;
2569
- checkRight(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, windowSize, tooltipLayer);
2570
- }
2571
-
2572
- tooltipLayer.style.bottom = "".concat(targetOffset.height + 20, "px");
2573
- break;
2574
-
2575
- case "top-left-aligned": // top-left-aligned is the same as the default top
2576
-
2577
- case "top":
2578
- arrowLayer.className = "introjs-arrow bottom";
2579
- tooltipLayerStyleLeft = hintMode ? 0 : 15;
2580
- checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
2581
- tooltipLayer.style.bottom = "".concat(targetOffset.height + 20, "px");
2582
- break;
2583
-
2584
- case "right":
2585
- tooltipLayer.style.left = "".concat(targetOffset.width + 20, "px");
2586
-
2587
- if (targetOffset.top + tooltipOffset.height > windowSize.height) {
2588
- // In this case, right would have fallen below the bottom of the screen.
2589
- // Modify so that the bottom of the tooltip connects with the target
2590
- arrowLayer.className = "introjs-arrow left-bottom";
2591
- tooltipLayer.style.top = "-".concat(tooltipOffset.height - targetOffset.height - 20, "px");
2592
- } else {
2593
- arrowLayer.className = "introjs-arrow left";
2594
- }
2595
-
2596
- break;
2597
-
2598
- case "left":
2599
- if (!hintMode && this._options.showStepNumbers === true) {
2600
- tooltipLayer.style.top = "15px";
2601
- }
2602
-
2603
- if (targetOffset.top + tooltipOffset.height > windowSize.height) {
2604
- // In this case, left would have fallen below the bottom of the screen.
2605
- // Modify so that the bottom of the tooltip connects with the target
2606
- tooltipLayer.style.top = "-".concat(tooltipOffset.height - targetOffset.height - 20, "px");
2607
- arrowLayer.className = "introjs-arrow right-bottom";
2608
- } else {
2609
- arrowLayer.className = "introjs-arrow right";
2610
- }
2611
-
2612
- tooltipLayer.style.right = "".concat(targetOffset.width + 20, "px");
2613
- break;
2614
-
2615
- case "floating":
2616
- arrowLayer.style.display = "none"; //we have to adjust the top and left of layer manually for intro items without element
2617
-
2618
- tooltipLayer.style.left = "50%";
2619
- tooltipLayer.style.top = "50%";
2620
- tooltipLayer.style.marginLeft = "-".concat(tooltipOffset.width / 2, "px");
2621
- tooltipLayer.style.marginTop = "-".concat(tooltipOffset.height / 2, "px");
2622
- break;
2623
-
2624
- case "bottom-right-aligned":
2625
- arrowLayer.className = "introjs-arrow top-right";
2626
- tooltipLayerStyleRight = 0;
2627
- checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer);
2628
- tooltipLayer.style.top = "".concat(targetOffset.height + 20, "px");
2629
- break;
2630
-
2631
- case "bottom-middle-aligned":
2632
- arrowLayer.className = "introjs-arrow top-middle";
2633
- tooltipLayerStyleLeftRight = targetOffset.width / 2 - tooltipOffset.width / 2; // a fix for middle aligned hints
2634
-
2635
- if (hintMode) {
2636
- tooltipLayerStyleLeftRight += 5;
2637
- }
2638
-
2639
- if (checkLeft(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, tooltipLayer)) {
2640
- tooltipLayer.style.right = null;
2641
- checkRight(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, windowSize, tooltipLayer);
2642
- }
2643
-
2644
- tooltipLayer.style.top = "".concat(targetOffset.height + 20, "px");
2645
- break;
2646
- // case 'bottom-left-aligned':
2647
- // Bottom-left-aligned is the same as the default bottom
2648
- // case 'bottom':
2649
- // Bottom going to follow the default behavior
2650
-
2651
- default:
2652
- arrowLayer.className = "introjs-arrow top";
2653
- tooltipLayerStyleLeft = 0;
2654
- checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
2655
- tooltipLayer.style.top = "".concat(targetOffset.height + 20, "px");
2656
- }
2657
- }
2658
-
2659
- /**
2660
- * To remove all show element(s)
2661
- *
2662
- * @api private
2663
- * @method _removeShowElement
2664
- */
2665
-
2666
- function removeShowElement() {
2667
- var elms = document.querySelectorAll(".introjs-showElement");
2668
- forEach(elms, function (elm) {
2669
- removeClass(elm, /introjs-[a-zA-Z]+/g);
2670
- });
2671
- }
2672
-
2673
- function _createElement(tagname, attrs) {
2674
- var element = document.createElement(tagname);
2675
- attrs = attrs || {}; // regex for matching attributes that need to be set with setAttribute
2676
-
2677
- var setAttRegex = /^(?:role|data-|aria-)/;
2678
-
2679
- for (var k in attrs) {
2680
- var v = attrs[k];
2681
-
2682
- if (k === "style") {
2683
- setStyle(element, v);
2684
- } else if (k.match(setAttRegex)) {
2685
- element.setAttribute(k, v);
2686
- } else {
2687
- element[k] = v;
2688
- }
2689
- }
2690
-
2691
- return element;
2692
- }
2693
-
2694
- /**
2695
- * Appends `element` to `parentElement`
2696
- *
2697
- * @param {Element} parentElement
2698
- * @param {Element} element
2699
- * @param {Boolean} [animate=false]
2700
- */
2701
-
2702
- function appendChild(parentElement, element, animate) {
2703
- if (animate) {
2704
- var existingOpacity = element.style.opacity || "1";
2705
- setStyle(element, {
2706
- opacity: "0"
2707
- });
2708
- window.setTimeout(function () {
2709
- setStyle(element, {
2710
- opacity: existingOpacity
2711
- });
2712
- }, 10);
2713
- }
2714
-
2715
- parentElement.appendChild(element);
2716
- }
2717
-
2718
- /**
2719
- * Gets the current progress percentage
2720
- *
2721
- * @api private
2722
- * @method _getProgress
2723
- * @returns current progress percentage
2724
- */
2725
-
2726
- function _getProgress() {
2727
- // Steps are 0 indexed
2728
- var currentStep = parseInt(this._currentStep + 1, 10);
2729
- return currentStep / this._introItems.length * 100;
2730
- }
2731
- /**
2732
- * Add disableinteraction layer and adjust the size and position of the layer
2733
- *
2734
- * @api private
2735
- * @method _disableInteraction
2736
- */
2737
-
2738
-
2739
- function _disableInteraction() {
2740
- var disableInteractionLayer = document.querySelector(".introjs-disableInteraction");
2741
-
2742
- if (disableInteractionLayer === null) {
2743
- disableInteractionLayer = _createElement("div", {
2744
- className: "introjs-disableInteraction"
2745
- });
2746
-
2747
- this._targetElement.appendChild(disableInteractionLayer);
2748
- }
2749
-
2750
- setHelperLayerPosition.call(this, disableInteractionLayer);
2751
- }
2752
- /**
2753
- * Show an element on the page
2754
- *
2755
- * @api private
2756
- * @method _showElement
2757
- * @param {Object} targetElement
2758
- */
2759
-
2760
-
2761
- function _showElement(targetElement) {
2762
- var _this = this;
2763
-
2764
- if (typeof this._introChangeCallback !== "undefined") {
2765
- this._introChangeCallback.call(this, targetElement.element);
2766
- }
2767
-
2768
- var self = this;
2769
- var oldHelperLayer = document.querySelector(".introjs-helperLayer");
2770
- var oldReferenceLayer = document.querySelector(".introjs-tooltipReferenceLayer");
2771
- var highlightClass = "introjs-helperLayer";
2772
- var nextTooltipButton;
2773
- var prevTooltipButton;
2774
- var skipTooltipButton;
2775
-
2776
- if (typeof targetElement.highlightClass === "string") {
2777
- highlightClass += " ".concat(targetElement.highlightClass);
2778
- } //check for options highlight class
2779
-
2780
-
2781
- if (typeof this._options.highlightClass === "string") {
2782
- highlightClass += " ".concat(this._options.highlightClass);
2783
- }
2784
-
2785
- if (oldHelperLayer !== null) {
2786
- var oldHelperNumberLayer = oldReferenceLayer.querySelector(".introjs-helperNumberLayer");
2787
- var oldtooltipLayer = oldReferenceLayer.querySelector(".introjs-tooltiptext");
2788
- var oldTooltipTitleLayer = oldReferenceLayer.querySelector(".introjs-tooltip-title");
2789
- var oldArrowLayer = oldReferenceLayer.querySelector(".introjs-arrow");
2790
- var oldtooltipContainer = oldReferenceLayer.querySelector(".introjs-tooltip");
2791
- skipTooltipButton = oldReferenceLayer.querySelector(".introjs-skipbutton");
2792
- prevTooltipButton = oldReferenceLayer.querySelector(".introjs-prevbutton");
2793
- nextTooltipButton = oldReferenceLayer.querySelector(".introjs-nextbutton"); //update or reset the helper highlight class
2794
-
2795
- oldHelperLayer.className = highlightClass; //hide the tooltip
2796
-
2797
- oldtooltipContainer.style.opacity = 0;
2798
- oldtooltipContainer.style.display = "none"; // if the target element is within a scrollable element
2799
-
2800
- scrollParentToElement.call(self, targetElement); // set new position to helper layer
2801
-
2802
- setHelperLayerPosition.call(self, oldHelperLayer);
2803
- setHelperLayerPosition.call(self, oldReferenceLayer); //remove old classes if the element still exist
2804
-
2805
- removeShowElement(); //we should wait until the CSS3 transition is competed (it's 0.3 sec) to prevent incorrect `height` and `width` calculation
2806
-
2807
- if (self._lastShowElementTimer) {
2808
- window.clearTimeout(self._lastShowElementTimer);
2809
- }
2810
-
2811
- self._lastShowElementTimer = window.setTimeout(function () {
2812
- // set current step to the label
2813
- if (oldHelperNumberLayer !== null) {
2814
- oldHelperNumberLayer.innerHTML = "".concat(targetElement.step, " of ").concat(_this._introItems.length);
2815
- } // set current tooltip text
2816
-
2817
-
2818
- oldtooltipLayer.innerHTML = targetElement.intro; // set current tooltip title
2819
-
2820
- oldTooltipTitleLayer.innerHTML = targetElement.title; //set the tooltip position
2821
-
2822
- oldtooltipContainer.style.display = "block";
2823
- placeTooltip.call(self, targetElement.element, oldtooltipContainer, oldArrowLayer); //change active bullet
2824
-
2825
- if (self._options.showBullets) {
2826
- oldReferenceLayer.querySelector(".introjs-bullets li > a.active").className = "";
2827
- oldReferenceLayer.querySelector(".introjs-bullets li > a[data-stepnumber=\"".concat(targetElement.step, "\"]")).className = "active";
2828
- }
2829
-
2830
- oldReferenceLayer.querySelector(".introjs-progress .introjs-progressbar").style.cssText = "width:".concat(_getProgress.call(self), "%;");
2831
- oldReferenceLayer.querySelector(".introjs-progress .introjs-progressbar").setAttribute("aria-valuenow", _getProgress.call(self)); //show the tooltip
2832
-
2833
- oldtooltipContainer.style.opacity = 1; //reset button focus
2834
-
2835
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null && /introjs-donebutton/gi.test(nextTooltipButton.className)) {
2836
- // skip button is now "done" button
2837
- nextTooltipButton.focus();
2838
- } else if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
2839
- //still in the tour, focus on next
2840
- nextTooltipButton.focus();
2841
- } // change the scroll of the window, if needed
2842
-
2843
-
2844
- scrollTo.call(self, targetElement.scrollTo, targetElement, oldtooltipLayer);
2845
- }, 350); // end of old element if-else condition
2846
- } else {
2847
- var helperLayer = _createElement("div", {
2848
- className: highlightClass
2849
- });
2850
- var referenceLayer = _createElement("div", {
2851
- className: "introjs-tooltipReferenceLayer"
2852
- });
2853
- var arrowLayer = _createElement("div", {
2854
- className: "introjs-arrow"
2855
- });
2856
- var tooltipLayer = _createElement("div", {
2857
- className: "introjs-tooltip"
2858
- });
2859
- var tooltipTextLayer = _createElement("div", {
2860
- className: "introjs-tooltiptext"
2861
- });
2862
- var tooltipHeaderLayer = _createElement("div", {
2863
- className: "introjs-tooltip-header"
2864
- });
2865
- var tooltipTitleLayer = _createElement("h1", {
2866
- className: "introjs-tooltip-title"
2867
- });
2868
- var bulletsLayer = _createElement("div", {
2869
- className: "introjs-bullets"
2870
- });
2871
- var progressLayer = _createElement("div");
2872
- var buttonsLayer = _createElement("div");
2873
- setStyle(helperLayer, {
2874
- "box-shadow": "0 0 1px 2px rgba(33, 33, 33, 0.8), rgba(33, 33, 33, ".concat(self._options.overlayOpacity.toString(), ") 0 0 0 5000px")
2875
- }); // target is within a scrollable element
2876
-
2877
- scrollParentToElement.call(self, targetElement); //set new position to helper layer
2878
-
2879
- setHelperLayerPosition.call(self, helperLayer);
2880
- setHelperLayerPosition.call(self, referenceLayer); //add helper layer to target element
2881
-
2882
- appendChild(this._targetElement, helperLayer, true);
2883
- appendChild(this._targetElement, referenceLayer);
2884
- tooltipTextLayer.innerHTML = targetElement.intro;
2885
- tooltipTitleLayer.innerHTML = targetElement.title;
2886
-
2887
- if (this._options.showBullets === false) {
2888
- bulletsLayer.style.display = "none";
2889
- }
2890
-
2891
- var ulContainer = _createElement("ul");
2892
- ulContainer.setAttribute("role", "tablist");
2893
-
2894
- var anchorClick = function anchorClick() {
2895
- self.goToStep(this.getAttribute("data-stepnumber"));
2896
- };
2897
-
2898
- forEach(this._introItems, function (_ref, i) {
2899
- var step = _ref.step;
2900
- var innerLi = _createElement("li");
2901
- var anchorLink = _createElement("a");
2902
- innerLi.setAttribute("role", "presentation");
2903
- anchorLink.setAttribute("role", "tab");
2904
- anchorLink.onclick = anchorClick;
2905
-
2906
- if (i === targetElement.step - 1) {
2907
- anchorLink.className = "active";
2908
- }
2909
-
2910
- setAnchorAsButton(anchorLink);
2911
- anchorLink.innerHTML = "&nbsp;";
2912
- anchorLink.setAttribute("data-stepnumber", step);
2913
- innerLi.appendChild(anchorLink);
2914
- ulContainer.appendChild(innerLi);
2915
- });
2916
- bulletsLayer.appendChild(ulContainer);
2917
- progressLayer.className = "introjs-progress";
2918
-
2919
- if (this._options.showProgress === false) {
2920
- progressLayer.style.display = "none";
2921
- }
2922
-
2923
- var progressBar = _createElement("div", {
2924
- className: "introjs-progressbar"
2925
- });
2926
-
2927
- if (this._options.progressBarAdditionalClass) {
2928
- progressBar.className += " " + this._options.progressBarAdditionalClass;
2929
- }
2930
-
2931
- progressBar.setAttribute("role", "progress");
2932
- progressBar.setAttribute("aria-valuemin", 0);
2933
- progressBar.setAttribute("aria-valuemax", 100);
2934
- progressBar.setAttribute("aria-valuenow", _getProgress.call(this));
2935
- progressBar.style.cssText = "width:".concat(_getProgress.call(this), "%;");
2936
- progressLayer.appendChild(progressBar);
2937
- buttonsLayer.className = "introjs-tooltipbuttons";
2938
-
2939
- if (this._options.showButtons === false) {
2940
- buttonsLayer.style.display = "none";
2941
- }
2942
-
2943
- tooltipHeaderLayer.appendChild(tooltipTitleLayer);
2944
- tooltipLayer.appendChild(tooltipHeaderLayer);
2945
- tooltipLayer.appendChild(tooltipTextLayer);
2946
- tooltipLayer.appendChild(bulletsLayer);
2947
- tooltipLayer.appendChild(progressLayer); // add helper layer number
2948
-
2949
- var helperNumberLayer = _createElement("div");
2950
-
2951
- if (this._options.showStepNumbers === true) {
2952
- helperNumberLayer.className = "introjs-helperNumberLayer";
2953
- helperNumberLayer.innerHTML = "".concat(targetElement.step, " of ").concat(this._introItems.length);
2954
- tooltipLayer.appendChild(helperNumberLayer);
2955
- }
2956
-
2957
- tooltipLayer.appendChild(arrowLayer);
2958
- referenceLayer.appendChild(tooltipLayer); //next button
2959
-
2960
- nextTooltipButton = _createElement("a");
2961
-
2962
- nextTooltipButton.onclick = function () {
2963
- if (self._introItems.length - 1 !== self._currentStep) {
2964
- nextStep.call(self);
2965
- } else if (/introjs-donebutton/gi.test(nextTooltipButton.className)) {
2966
- if (typeof self._introCompleteCallback === "function") {
2967
- self._introCompleteCallback.call(self);
2968
- }
2969
-
2970
- exitIntro.call(self, self._targetElement);
2971
- }
2972
- };
2973
-
2974
- setAnchorAsButton(nextTooltipButton);
2975
- nextTooltipButton.innerHTML = this._options.nextLabel; //previous button
2976
-
2977
- prevTooltipButton = _createElement("a");
2978
-
2979
- prevTooltipButton.onclick = function () {
2980
- if (self._currentStep !== 0) {
2981
- previousStep.call(self);
2982
- }
2983
- };
2984
-
2985
- setAnchorAsButton(prevTooltipButton);
2986
- prevTooltipButton.innerHTML = this._options.prevLabel; //skip button
2987
-
2988
- skipTooltipButton = _createElement("a", {
2989
- className: "introjs-skipbutton"
2990
- });
2991
- setAnchorAsButton(skipTooltipButton);
2992
- skipTooltipButton.innerHTML = this._options.skipLabel;
2993
-
2994
- skipTooltipButton.onclick = function () {
2995
- if (self._introItems.length - 1 === self._currentStep && typeof self._introCompleteCallback === "function") {
2996
- self._introCompleteCallback.call(self);
2997
- }
2998
-
2999
- if (typeof self._introSkipCallback === "function") {
3000
- self._introSkipCallback.call(self);
3001
- }
3002
-
3003
- exitIntro.call(self, self._targetElement);
3004
- };
3005
-
3006
- tooltipHeaderLayer.appendChild(skipTooltipButton); //in order to prevent displaying previous button always
3007
-
3008
- if (this._introItems.length > 1) {
3009
- buttonsLayer.appendChild(prevTooltipButton);
3010
- } // we always need the next button because this
3011
- // button changes to "Done" in the last step of the tour
3012
-
3013
-
3014
- buttonsLayer.appendChild(nextTooltipButton);
3015
- tooltipLayer.appendChild(buttonsLayer); //set proper position
3016
-
3017
- placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer); // change the scroll of the window, if needed
3018
-
3019
- scrollTo.call(this, targetElement.scrollTo, targetElement, tooltipLayer); //end of new element if-else condition
3020
- } // removing previous disable interaction layer
3021
-
3022
-
3023
- var disableInteractionLayer = self._targetElement.querySelector(".introjs-disableInteraction");
3024
-
3025
- if (disableInteractionLayer) {
3026
- disableInteractionLayer.parentNode.removeChild(disableInteractionLayer);
3027
- } //disable interaction
3028
-
3029
-
3030
- if (targetElement.disableInteraction) {
3031
- _disableInteraction.call(self);
3032
- } // when it's the first step of tour
3033
-
3034
-
3035
- if (this._currentStep === 0 && this._introItems.length > 1) {
3036
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
3037
- nextTooltipButton.className = "".concat(this._options.buttonClass, " introjs-nextbutton");
3038
- nextTooltipButton.innerHTML = this._options.nextLabel;
3039
- }
3040
-
3041
- if (this._options.hidePrev === true) {
3042
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
3043
- prevTooltipButton.className = "".concat(this._options.buttonClass, " introjs-prevbutton introjs-hidden");
3044
- }
3045
-
3046
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
3047
- addClass(nextTooltipButton, "introjs-fullbutton");
3048
- }
3049
- } else {
3050
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
3051
- prevTooltipButton.className = "".concat(this._options.buttonClass, " introjs-prevbutton introjs-disabled");
3052
- }
3053
- }
3054
- } else if (this._introItems.length - 1 === this._currentStep || this._introItems.length === 1) {
3055
- // last step of tour
3056
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
3057
- prevTooltipButton.className = "".concat(this._options.buttonClass, " introjs-prevbutton");
3058
- }
3059
-
3060
- if (this._options.hideNext === true) {
3061
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
3062
- nextTooltipButton.className = "".concat(this._options.buttonClass, " introjs-nextbutton introjs-hidden");
3063
- }
3064
-
3065
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
3066
- addClass(prevTooltipButton, "introjs-fullbutton");
3067
- }
3068
- } else {
3069
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
3070
- if (this._options.nextToDone === true) {
3071
- nextTooltipButton.innerHTML = this._options.doneLabel;
3072
- addClass(nextTooltipButton, "".concat(this._options.buttonClass, " introjs-nextbutton introjs-donebutton"));
3073
- } else {
3074
- nextTooltipButton.className = "".concat(this._options.buttonClass, " introjs-nextbutton introjs-disabled");
3075
- }
3076
- }
3077
- }
3078
- } else {
3079
- // steps between start and end
3080
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
3081
- prevTooltipButton.className = "".concat(this._options.buttonClass, " introjs-prevbutton");
3082
- }
3083
-
3084
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
3085
- nextTooltipButton.className = "".concat(this._options.buttonClass, " introjs-nextbutton");
3086
- nextTooltipButton.innerHTML = this._options.nextLabel;
3087
- }
3088
- }
3089
-
3090
- if (typeof prevTooltipButton !== "undefined" && prevTooltipButton !== null) {
3091
- prevTooltipButton.setAttribute("role", "button");
3092
- }
3093
-
3094
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
3095
- nextTooltipButton.setAttribute("role", "button");
3096
- }
3097
-
3098
- if (typeof skipTooltipButton !== "undefined" && skipTooltipButton !== null) {
3099
- skipTooltipButton.setAttribute("role", "button");
3100
- } //Set focus on "next" button, so that hitting Enter always moves you onto the next step
3101
-
3102
-
3103
- if (typeof nextTooltipButton !== "undefined" && nextTooltipButton !== null) {
3104
- nextTooltipButton.focus();
3105
- }
3106
-
3107
- setShowElement(targetElement);
3108
-
3109
- if (typeof this._introAfterChangeCallback !== "undefined") {
3110
- this._introAfterChangeCallback.call(this, targetElement.element);
3111
- }
3112
- }
3113
-
3114
- /**
3115
- * Go to specific step of introduction
3116
- *
3117
- * @api private
3118
- * @method _goToStep
3119
- */
3120
-
3121
- function goToStep(step) {
3122
- //because steps starts with zero
3123
- this._currentStep = step - 2;
3124
-
3125
- if (typeof this._introItems !== "undefined") {
3126
- nextStep.call(this);
3127
- }
3128
- }
3129
- /**
3130
- * Go to the specific step of introduction with the explicit [data-step] number
3131
- *
3132
- * @api private
3133
- * @method _goToStepNumber
3134
- */
3135
-
3136
- function goToStepNumber(step) {
3137
- this._currentStepNumber = step;
3138
-
3139
- if (typeof this._introItems !== "undefined") {
3140
- nextStep.call(this);
3141
- }
3142
- }
3143
- /**
3144
- * Go to next step on intro
3145
- *
3146
- * @api private
3147
- * @method _nextStep
3148
- */
3149
-
3150
- function nextStep() {
3151
- var _this = this;
3152
-
3153
- this._direction = "forward";
3154
-
3155
- if (typeof this._currentStepNumber !== "undefined") {
3156
- forEach(this._introItems, function (_ref, i) {
3157
- var step = _ref.step;
3158
-
3159
- if (step === _this._currentStepNumber) {
3160
- _this._currentStep = i - 1;
3161
- _this._currentStepNumber = undefined;
3162
- }
3163
- });
3164
- }
3165
-
3166
- if (typeof this._currentStep === "undefined") {
3167
- this._currentStep = 0;
3168
- } else {
3169
- ++this._currentStep;
3170
- }
3171
-
3172
- var nextStep = this._introItems[this._currentStep];
3173
- var continueStep = true;
3174
-
3175
- if (typeof this._introBeforeChangeCallback !== "undefined") {
3176
- continueStep = this._introBeforeChangeCallback.call(this, nextStep && nextStep.element);
3177
- } // if `onbeforechange` returned `false`, stop displaying the element
3178
-
3179
-
3180
- if (continueStep === false) {
3181
- --this._currentStep;
3182
- return false;
3183
- }
3184
-
3185
- if (this._introItems.length <= this._currentStep) {
3186
- //end of the intro
3187
- //check if any callback is defined
3188
- if (typeof this._introCompleteCallback === "function") {
3189
- this._introCompleteCallback.call(this);
3190
- }
3191
-
3192
- exitIntro.call(this, this._targetElement);
3193
- return;
3194
- }
3195
-
3196
- _showElement.call(this, nextStep);
3197
- }
3198
- /**
3199
- * Go to previous step on intro
3200
- *
3201
- * @api private
3202
- * @method _previousStep
3203
- */
3204
-
3205
- function previousStep() {
3206
- this._direction = "backward";
3207
-
3208
- if (this._currentStep === 0) {
3209
- return false;
3210
- }
3211
-
3212
- --this._currentStep;
3213
- var nextStep = this._introItems[this._currentStep];
3214
- var continueStep = true;
3215
-
3216
- if (typeof this._introBeforeChangeCallback !== "undefined") {
3217
- continueStep = this._introBeforeChangeCallback.call(this, nextStep && nextStep.element);
3218
- } // if `onbeforechange` returned `false`, stop displaying the element
3219
-
3220
-
3221
- if (continueStep === false) {
3222
- ++this._currentStep;
3223
- return false;
3224
- }
3225
-
3226
- _showElement.call(this, nextStep);
3227
- }
3228
- /**
3229
- * Returns the current step of the intro
3230
- *
3231
- * @returns {number | boolean}
3232
- */
3233
-
3234
- function currentStep() {
3235
- return this._currentStep;
3236
- }
3237
-
3238
- /**
3239
- * on keyCode:
3240
- * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
3241
- * This feature has been removed from the Web standards.
3242
- * Though some browsers may still support it, it is in
3243
- * the process of being dropped.
3244
- * Instead, you should use KeyboardEvent.code,
3245
- * if it's implemented.
3246
- *
3247
- * jQuery's approach is to test for
3248
- * (1) e.which, then
3249
- * (2) e.charCode, then
3250
- * (3) e.keyCode
3251
- * https://github.com/jquery/jquery/blob/a6b0705294d336ae2f63f7276de0da1195495363/src/event.js#L638
3252
- *
3253
- * @param type var
3254
- * @return type
3255
- */
3256
-
3257
- function onKeyDown(e) {
3258
- var code = e.code === undefined ? e.which : e.code; // if e.which is null
3259
-
3260
- if (code === null) {
3261
- code = e.charCode === null ? e.keyCode : e.charCode;
3262
- }
3263
-
3264
- if ((code === "Escape" || code === 27) && this._options.exitOnEsc === true) {
3265
- //escape key pressed, exit the intro
3266
- //check if exit callback is defined
3267
- exitIntro.call(this, this._targetElement);
3268
- } else if (code === "ArrowLeft" || code === 37) {
3269
- //left arrow
3270
- previousStep.call(this);
3271
- } else if (code === "ArrowRight" || code === 39) {
3272
- //right arrow
3273
- nextStep.call(this);
3274
- } else if (code === "Enter" || code === "NumpadEnter" || code === 13) {
3275
- //srcElement === ie
3276
- var target = e.target || e.srcElement;
3277
-
3278
- if (target && target.className.match("introjs-prevbutton")) {
3279
- //user hit enter while focusing on previous button
3280
- previousStep.call(this);
3281
- } else if (target && target.className.match("introjs-skipbutton")) {
3282
- //user hit enter while focusing on skip button
3283
- if (this._introItems.length - 1 === this._currentStep && typeof this._introCompleteCallback === "function") {
3284
- this._introCompleteCallback.call(this);
3285
- }
3286
-
3287
- exitIntro.call(this, this._targetElement);
3288
- } else if (target && target.getAttribute("data-stepnumber")) {
3289
- // user hit enter while focusing on step bullet
3290
- target.click();
3291
- } else {
3292
- //default behavior for responding to enter
3293
- nextStep.call(this);
3294
- } //prevent default behaviour on hitting Enter, to prevent steps being skipped in some browsers
3295
-
3296
-
3297
- if (e.preventDefault) {
3298
- e.preventDefault();
3299
- } else {
3300
- e.returnValue = false;
3301
- }
3302
- }
3303
- }
3304
-
3305
- /*
3306
- * makes a copy of the object
3307
- * @api private
3308
- * @method _cloneObject
3309
- */
3310
- function cloneObject(object) {
3311
- if (object === null || _typeof(object) !== "object" || typeof object.nodeType !== "undefined") {
3312
- return object;
3313
- }
3314
-
3315
- var temp = {};
3316
-
3317
- for (var key in object) {
3318
- if (typeof window.jQuery !== "undefined" && object[key] instanceof window.jQuery) {
3319
- temp[key] = object[key];
3320
- } else {
3321
- temp[key] = cloneObject(object[key]);
3322
- }
3323
- }
3324
-
3325
- return temp;
3326
- }
3327
-
3328
- /**
3329
- * Get a queryselector within the hint wrapper
3330
- *
3331
- * @param {String} selector
3332
- * @return {NodeList|Array}
3333
- */
3334
-
3335
- function hintQuerySelectorAll(selector) {
3336
- var hintsWrapper = document.querySelector(".introjs-hints");
3337
- return hintsWrapper ? hintsWrapper.querySelectorAll(selector) : [];
3338
- }
3339
- /**
3340
- * Hide a hint
3341
- *
3342
- * @api private
3343
- * @method hideHint
3344
- */
3345
-
3346
- function hideHint(stepId) {
3347
- var hint = hintQuerySelectorAll(".introjs-hint[data-step=\"".concat(stepId, "\"]"))[0];
3348
- removeHintTooltip.call(this);
3349
-
3350
- if (hint) {
3351
- addClass(hint, "introjs-hidehint");
3352
- } // call the callback function (if any)
3353
-
3354
-
3355
- if (typeof this._hintCloseCallback !== "undefined") {
3356
- this._hintCloseCallback.call(this, stepId);
3357
- }
3358
- }
3359
- /**
3360
- * Hide all hints
3361
- *
3362
- * @api private
3363
- * @method hideHints
3364
- */
3365
-
3366
- function hideHints() {
3367
- var _this = this;
3368
-
3369
- var hints = hintQuerySelectorAll(".introjs-hint");
3370
- forEach(hints, function (hint) {
3371
- hideHint.call(_this, hint.getAttribute("data-step"));
3372
- });
3373
- }
3374
- /**
3375
- * Show all hints
3376
- *
3377
- * @api private
3378
- * @method _showHints
3379
- */
3380
-
3381
- function showHints() {
3382
- var _this2 = this;
3383
-
3384
- var hints = hintQuerySelectorAll(".introjs-hint");
3385
-
3386
- if (hints && hints.length) {
3387
- forEach(hints, function (hint) {
3388
- showHint.call(_this2, hint.getAttribute("data-step"));
3389
- });
3390
- } else {
3391
- populateHints.call(this, this._targetElement);
3392
- }
3393
- }
3394
- /**
3395
- * Show a hint
3396
- *
3397
- * @api private
3398
- * @method showHint
3399
- */
3400
-
3401
- function showHint(stepId) {
3402
- var hint = hintQuerySelectorAll(".introjs-hint[data-step=\"".concat(stepId, "\"]"))[0];
3403
-
3404
- if (hint) {
3405
- removeClass(hint, /introjs-hidehint/g);
3406
- }
3407
- }
3408
- /**
3409
- * Removes all hint elements on the page
3410
- * Useful when you want to destroy the elements and add them again (e.g. a modal or popup)
3411
- *
3412
- * @api private
3413
- * @method removeHints
3414
- */
3415
-
3416
- function removeHints() {
3417
- var _this3 = this;
3418
-
3419
- var hints = hintQuerySelectorAll(".introjs-hint");
3420
- forEach(hints, function (hint) {
3421
- removeHint.call(_this3, hint.getAttribute("data-step"));
3422
- });
3423
- }
3424
- /**
3425
- * Remove one single hint element from the page
3426
- * Useful when you want to destroy the element and add them again (e.g. a modal or popup)
3427
- * Use removeHints if you want to remove all elements.
3428
- *
3429
- * @api private
3430
- * @method removeHint
3431
- */
3432
-
3433
- function removeHint(stepId) {
3434
- var hint = hintQuerySelectorAll(".introjs-hint[data-step=\"".concat(stepId, "\"]"))[0];
3435
-
3436
- if (hint) {
3437
- hint.parentNode.removeChild(hint);
3438
- }
3439
- }
3440
- /**
3441
- * Add all available hints to the page
3442
- *
3443
- * @api private
3444
- * @method addHints
3445
- */
3446
-
3447
- function addHints() {
3448
- var _this4 = this;
3449
-
3450
- var self = this;
3451
- var hintsWrapper = document.querySelector(".introjs-hints");
3452
-
3453
- if (hintsWrapper === null) {
3454
- hintsWrapper = _createElement("div", {
3455
- className: "introjs-hints"
3456
- });
3457
- }
3458
- /**
3459
- * Returns an event handler unique to the hint iteration
3460
- *
3461
- * @param {Integer} i
3462
- * @return {Function}
3463
- */
3464
-
3465
-
3466
- var getHintClick = function getHintClick(i) {
3467
- return function (e) {
3468
- var evt = e ? e : window.event;
3469
-
3470
- if (evt.stopPropagation) {
3471
- evt.stopPropagation();
3472
- }
3473
-
3474
- if (evt.cancelBubble !== null) {
3475
- evt.cancelBubble = true;
3476
- }
3477
-
3478
- showHintDialog.call(self, i);
3479
- };
3480
- };
3481
-
3482
- forEach(this._introItems, function (item, i) {
3483
- // avoid append a hint twice
3484
- if (document.querySelector(".introjs-hint[data-step=\"".concat(i, "\"]"))) {
3485
- return;
3486
- }
3487
-
3488
- var hint = _createElement("a", {
3489
- className: "introjs-hint"
3490
- });
3491
- setAnchorAsButton(hint);
3492
- hint.onclick = getHintClick(i);
3493
-
3494
- if (!item.hintAnimation) {
3495
- addClass(hint, "introjs-hint-no-anim");
3496
- } // hint's position should be fixed if the target element's position is fixed
3497
-
3498
-
3499
- if (isFixed(item.element)) {
3500
- addClass(hint, "introjs-fixedhint");
3501
- }
3502
-
3503
- var hintDot = _createElement("div", {
3504
- className: "introjs-hint-dot"
3505
- });
3506
- var hintPulse = _createElement("div", {
3507
- className: "introjs-hint-pulse"
3508
- });
3509
- hint.appendChild(hintDot);
3510
- hint.appendChild(hintPulse);
3511
- hint.setAttribute("data-step", i); // we swap the hint element with target element
3512
- // because _setHelperLayerPosition uses `element` property
3513
-
3514
- item.targetElement = item.element;
3515
- item.element = hint; // align the hint position
3516
-
3517
- alignHintPosition.call(_this4, item.hintPosition, hint, item.targetElement);
3518
- hintsWrapper.appendChild(hint);
3519
- }); // adding the hints wrapper
3520
-
3521
- document.body.appendChild(hintsWrapper); // call the callback function (if any)
3522
-
3523
- if (typeof this._hintsAddedCallback !== "undefined") {
3524
- this._hintsAddedCallback.call(this);
3525
- }
3526
- }
3527
- /**
3528
- * Aligns hint position
3529
- *
3530
- * @api private
3531
- * @method alignHintPosition
3532
- * @param {String} position
3533
- * @param {Object} hint
3534
- * @param {Object} element
3535
- */
3536
-
3537
- function alignHintPosition(position, _ref, element) {
3538
- var style = _ref.style;
3539
- // get/calculate offset of target element
3540
- var offset = getOffset.call(this, element);
3541
- var iconWidth = 20;
3542
- var iconHeight = 20; // align the hint element
3543
-
3544
- switch (position) {
3545
- default:
3546
- case "top-left":
3547
- style.left = "".concat(offset.left, "px");
3548
- style.top = "".concat(offset.top, "px");
3549
- break;
3550
-
3551
- case "top-right":
3552
- style.left = "".concat(offset.left + offset.width - iconWidth, "px");
3553
- style.top = "".concat(offset.top, "px");
3554
- break;
3555
-
3556
- case "bottom-left":
3557
- style.left = "".concat(offset.left, "px");
3558
- style.top = "".concat(offset.top + offset.height - iconHeight, "px");
3559
- break;
3560
-
3561
- case "bottom-right":
3562
- style.left = "".concat(offset.left + offset.width - iconWidth, "px");
3563
- style.top = "".concat(offset.top + offset.height - iconHeight, "px");
3564
- break;
3565
-
3566
- case "middle-left":
3567
- style.left = "".concat(offset.left, "px");
3568
- style.top = "".concat(offset.top + (offset.height - iconHeight) / 2, "px");
3569
- break;
3570
-
3571
- case "middle-right":
3572
- style.left = "".concat(offset.left + offset.width - iconWidth, "px");
3573
- style.top = "".concat(offset.top + (offset.height - iconHeight) / 2, "px");
3574
- break;
3575
-
3576
- case "middle-middle":
3577
- style.left = "".concat(offset.left + (offset.width - iconWidth) / 2, "px");
3578
- style.top = "".concat(offset.top + (offset.height - iconHeight) / 2, "px");
3579
- break;
3580
-
3581
- case "bottom-middle":
3582
- style.left = "".concat(offset.left + (offset.width - iconWidth) / 2, "px");
3583
- style.top = "".concat(offset.top + offset.height - iconHeight, "px");
3584
- break;
3585
-
3586
- case "top-middle":
3587
- style.left = "".concat(offset.left + (offset.width - iconWidth) / 2, "px");
3588
- style.top = "".concat(offset.top, "px");
3589
- break;
3590
- }
3591
- }
3592
- /**
3593
- * Triggers when user clicks on the hint element
3594
- *
3595
- * @api private
3596
- * @method _showHintDialog
3597
- * @param {Number} stepId
3598
- */
3599
-
3600
- function showHintDialog(stepId) {
3601
- var hintElement = document.querySelector(".introjs-hint[data-step=\"".concat(stepId, "\"]"));
3602
- var item = this._introItems[stepId]; // call the callback function (if any)
3603
-
3604
- if (typeof this._hintClickCallback !== "undefined") {
3605
- this._hintClickCallback.call(this, hintElement, item, stepId);
3606
- } // remove all open tooltips
3607
-
3608
-
3609
- var removedStep = removeHintTooltip.call(this); // to toggle the tooltip
3610
-
3611
- if (parseInt(removedStep, 10) === stepId) {
3612
- return;
3613
- }
3614
-
3615
- var tooltipLayer = _createElement("div", {
3616
- className: "introjs-tooltip"
3617
- });
3618
- var tooltipTextLayer = _createElement("div");
3619
- var arrowLayer = _createElement("div");
3620
- var referenceLayer = _createElement("div");
3621
-
3622
- tooltipLayer.onclick = function (e) {
3623
- //IE9 & Other Browsers
3624
- if (e.stopPropagation) {
3625
- e.stopPropagation();
3626
- } //IE8 and Lower
3627
- else {
3628
- e.cancelBubble = true;
3629
- }
3630
- };
3631
-
3632
- tooltipTextLayer.className = "introjs-tooltiptext";
3633
- var tooltipWrapper = _createElement("p");
3634
- tooltipWrapper.innerHTML = item.hint;
3635
- var closeButton = _createElement("a");
3636
- closeButton.className = this._options.buttonClass;
3637
- closeButton.setAttribute("role", "button");
3638
- closeButton.innerHTML = this._options.hintButtonLabel;
3639
- closeButton.onclick = hideHint.bind(this, stepId);
3640
- tooltipTextLayer.appendChild(tooltipWrapper);
3641
- tooltipTextLayer.appendChild(closeButton);
3642
- arrowLayer.className = "introjs-arrow";
3643
- tooltipLayer.appendChild(arrowLayer);
3644
- tooltipLayer.appendChild(tooltipTextLayer); // set current step for _placeTooltip function
3645
-
3646
- this._currentStep = hintElement.getAttribute("data-step"); // align reference layer position
3647
-
3648
- referenceLayer.className = "introjs-tooltipReferenceLayer introjs-hintReference";
3649
- referenceLayer.setAttribute("data-step", hintElement.getAttribute("data-step"));
3650
- setHelperLayerPosition.call(this, referenceLayer);
3651
- referenceLayer.appendChild(tooltipLayer);
3652
- document.body.appendChild(referenceLayer); //set proper position
3653
-
3654
- placeTooltip.call(this, hintElement, tooltipLayer, arrowLayer, true);
3655
- }
3656
- /**
3657
- * Removes open hint (tooltip hint)
3658
- *
3659
- * @api private
3660
- * @method _removeHintTooltip
3661
- */
3662
-
3663
- function removeHintTooltip() {
3664
- var tooltip = document.querySelector(".introjs-hintReference");
3665
-
3666
- if (tooltip) {
3667
- var step = tooltip.getAttribute("data-step");
3668
- tooltip.parentNode.removeChild(tooltip);
3669
- return step;
3670
- }
3671
- }
3672
- /**
3673
- * Start parsing hint items
3674
- *
3675
- * @api private
3676
- * @param {Object} targetElm
3677
- * @method _startHint
3678
- */
3679
-
3680
- function populateHints(targetElm) {
3681
- var _this5 = this;
3682
-
3683
- this._introItems = [];
3684
-
3685
- if (this._options.hints) {
3686
- forEach(this._options.hints, function (hint) {
3687
- var currentItem = cloneObject(hint);
3688
-
3689
- if (typeof currentItem.element === "string") {
3690
- //grab the element with given selector from the page
3691
- currentItem.element = document.querySelector(currentItem.element);
3692
- }
3693
-
3694
- currentItem.hintPosition = currentItem.hintPosition || _this5._options.hintPosition;
3695
- currentItem.hintAnimation = currentItem.hintAnimation || _this5._options.hintAnimation;
3696
-
3697
- if (currentItem.element !== null) {
3698
- _this5._introItems.push(currentItem);
3699
- }
3700
- });
3701
- } else {
3702
- var hints = targetElm.querySelectorAll("*[data-hint]");
3703
-
3704
- if (!hints || !hints.length) {
3705
- return false;
3706
- } //first add intro items with data-step
3707
-
3708
-
3709
- forEach(hints, function (currentElement) {
3710
- // hint animation
3711
- var hintAnimation = currentElement.getAttribute("data-hintanimation");
3712
-
3713
- if (hintAnimation) {
3714
- hintAnimation = hintAnimation === "true";
3715
- } else {
3716
- hintAnimation = _this5._options.hintAnimation;
3717
- }
3718
-
3719
- _this5._introItems.push({
3720
- element: currentElement,
3721
- hint: currentElement.getAttribute("data-hint"),
3722
- hintPosition: currentElement.getAttribute("data-hintposition") || _this5._options.hintPosition,
3723
- hintAnimation: hintAnimation,
3724
- tooltipClass: currentElement.getAttribute("data-tooltipclass"),
3725
- position: currentElement.getAttribute("data-position") || _this5._options.tooltipPosition
3726
- });
3727
- });
3728
- }
3729
-
3730
- addHints.call(this);
3731
- /*
3732
- todo:
3733
- these events should be removed at some point
3734
- */
3735
-
3736
- DOMEvent.on(document, "click", removeHintTooltip, this, false);
3737
- DOMEvent.on(window, "resize", reAlignHints, this, true);
3738
- }
3739
- /**
3740
- * Re-aligns all hint elements
3741
- *
3742
- * @api private
3743
- * @method _reAlignHints
3744
- */
3745
-
3746
- function reAlignHints() {
3747
- var _this6 = this;
3748
-
3749
- forEach(this._introItems, function (_ref2) {
3750
- var targetElement = _ref2.targetElement,
3751
- hintPosition = _ref2.hintPosition,
3752
- element = _ref2.element;
3753
-
3754
- if (typeof targetElement === "undefined") {
3755
- return;
3756
- }
3757
-
3758
- alignHintPosition.call(_this6, hintPosition, element, targetElement);
3759
- });
3760
- }
3761
-
3762
- /**
3763
- * Update placement of the intro objects on the screen
3764
- * @api private
3765
- */
3766
-
3767
- function refresh() {
3768
- // re-align intros
3769
- setHelperLayerPosition.call(this, document.querySelector(".introjs-helperLayer"));
3770
- setHelperLayerPosition.call(this, document.querySelector(".introjs-tooltipReferenceLayer"));
3771
- setHelperLayerPosition.call(this, document.querySelector(".introjs-disableInteraction")); // re-align tooltip
3772
-
3773
- if (this._currentStep !== undefined && this._currentStep !== null) {
3774
- var oldArrowLayer = document.querySelector(".introjs-arrow");
3775
- var oldtooltipContainer = document.querySelector(".introjs-tooltip");
3776
- placeTooltip.call(this, this._introItems[this._currentStep].element, oldtooltipContainer, oldArrowLayer);
3777
- } //re-align hints
3778
-
3779
-
3780
- reAlignHints.call(this);
3781
- return this;
3782
- }
3783
-
3784
- function onResize() {
3785
- refresh.call(this);
3786
- }
3787
-
3788
- /**
3789
- * Removes `element` from `parentElement`
3790
- *
3791
- * @param {Element} element
3792
- * @param {Boolean} [animate=false]
3793
- */
3794
-
3795
- function removeChild(element, animate) {
3796
- if (!element || !element.parentElement) return;
3797
- var parentElement = element.parentElement;
3798
-
3799
- if (animate) {
3800
- setStyle(element, {
3801
- opacity: "0"
3802
- });
3803
- window.setTimeout(function () {
3804
- parentElement.removeChild(element);
3805
- }, 500);
3806
- } else {
3807
- parentElement.removeChild(element);
3808
- }
3809
- }
3810
-
3811
- /**
3812
- * Exit from intro
3813
- *
3814
- * @api private
3815
- * @method _exitIntro
3816
- * @param {Object} targetElement
3817
- * @param {Boolean} force - Setting to `true` will skip the result of beforeExit callback
3818
- */
3819
-
3820
- function exitIntro(targetElement, force) {
3821
- var continueExit = true; // calling onbeforeexit callback
3822
- //
3823
- // If this callback return `false`, it would halt the process
3824
-
3825
- if (this._introBeforeExitCallback !== undefined) {
3826
- continueExit = this._introBeforeExitCallback.call(this);
3827
- } // skip this check if `force` parameter is `true`
3828
- // otherwise, if `onbeforeexit` returned `false`, don't exit the intro
3829
-
3830
-
3831
- if (!force && continueExit === false) return; // remove overlay layers from the page
3832
-
3833
- var overlayLayers = targetElement.querySelectorAll(".introjs-overlay");
3834
-
3835
- if (overlayLayers && overlayLayers.length) {
3836
- forEach(overlayLayers, function (overlayLayer) {
3837
- return removeChild(overlayLayer);
3838
- });
3839
- } //remove all helper layers
3840
-
3841
-
3842
- var helperLayer = targetElement.querySelector(".introjs-helperLayer");
3843
- removeChild(helperLayer, true);
3844
- var referenceLayer = targetElement.querySelector(".introjs-tooltipReferenceLayer");
3845
- removeChild(referenceLayer); //remove disableInteractionLayer
3846
-
3847
- var disableInteractionLayer = targetElement.querySelector(".introjs-disableInteraction");
3848
- removeChild(disableInteractionLayer); //remove intro floating element
3849
-
3850
- var floatingElement = document.querySelector(".introjsFloatingElement");
3851
- removeChild(floatingElement);
3852
- removeShowElement(); //clean listeners
3853
-
3854
- DOMEvent.off(window, "keydown", onKeyDown, this, true);
3855
- DOMEvent.off(window, "resize", onResize, this, true); //check if any callback is defined
3856
-
3857
- if (this._introExitCallback !== undefined) {
3858
- this._introExitCallback.call(this);
3859
- } //set the step to zero
3860
-
3861
-
3862
- this._currentStep = undefined;
3863
- }
3864
-
3865
- /**
3866
- * Add overlay layer to the page
3867
- *
3868
- * @api private
3869
- * @method _addOverlayLayer
3870
- * @param {Object} targetElm
3871
- */
3872
-
3873
- function addOverlayLayer(targetElm) {
3874
- var _this = this;
3875
-
3876
- var overlayLayer = _createElement("div", {
3877
- className: "introjs-overlay"
3878
- });
3879
- setStyle(overlayLayer, {
3880
- top: 0,
3881
- bottom: 0,
3882
- left: 0,
3883
- right: 0,
3884
- position: "fixed"
3885
- });
3886
- targetElm.appendChild(overlayLayer);
3887
-
3888
- if (this._options.exitOnOverlayClick === true) {
3889
- setStyle(overlayLayer, {
3890
- cursor: "pointer"
3891
- });
3892
-
3893
- overlayLayer.onclick = function () {
3894
- exitIntro.call(_this, targetElm);
3895
- };
3896
- }
3897
-
3898
- return true;
3899
- }
3900
-
3901
- /**
3902
- * Initiate a new introduction/guide from an element in the page
3903
- *
3904
- * @api private
3905
- * @method _introForElement
3906
- * @param {Object} targetElm
3907
- * @param {String} group
3908
- * @returns {Boolean} Success or not?
3909
- */
3910
-
3911
- function introForElement(targetElm, group) {
3912
- var _this = this;
3913
-
3914
- var allIntroSteps = targetElm.querySelectorAll("*[data-intro]");
3915
- var introItems = [];
3916
-
3917
- if (this._options.steps) {
3918
- //use steps passed programmatically
3919
- forEach(this._options.steps, function (step) {
3920
- var currentItem = cloneObject(step); //set the step
3921
-
3922
- currentItem.step = introItems.length + 1;
3923
- currentItem.title = currentItem.title || ""; //use querySelector function only when developer used CSS selector
3924
-
3925
- if (typeof currentItem.element === "string") {
3926
- //grab the element with given selector from the page
3927
- currentItem.element = document.querySelector(currentItem.element);
3928
- } //intro without element
3929
-
3930
-
3931
- if (typeof currentItem.element === "undefined" || currentItem.element === null) {
3932
- var floatingElementQuery = document.querySelector(".introjsFloatingElement");
3933
-
3934
- if (floatingElementQuery === null) {
3935
- floatingElementQuery = _createElement("div", {
3936
- className: "introjsFloatingElement"
3937
- });
3938
- document.body.appendChild(floatingElementQuery);
3939
- }
3940
-
3941
- currentItem.element = floatingElementQuery;
3942
- currentItem.position = "floating";
3943
- }
3944
-
3945
- currentItem.scrollTo = currentItem.scrollTo || _this._options.scrollTo;
3946
-
3947
- if (typeof currentItem.disableInteraction === "undefined") {
3948
- currentItem.disableInteraction = _this._options.disableInteraction;
3949
- }
3950
-
3951
- if (currentItem.element !== null) {
3952
- introItems.push(currentItem);
3953
- }
3954
- });
3955
- } else {
3956
- //use steps from data-* annotations
3957
- var elmsLength = allIntroSteps.length;
3958
- var disableInteraction; //if there's no element to intro
3959
-
3960
- if (elmsLength < 1) {
3961
- return false;
3962
- }
3963
-
3964
- forEach(allIntroSteps, function (currentElement) {
3965
- // PR #80
3966
- // start intro for groups of elements
3967
- if (group && currentElement.getAttribute("data-intro-group") !== group) {
3968
- return;
3969
- } // skip hidden elements
3970
-
3971
-
3972
- if (currentElement.style.display === "none") {
3973
- return;
3974
- }
3975
-
3976
- var step = parseInt(currentElement.getAttribute("data-step"), 10);
3977
-
3978
- if (currentElement.hasAttribute("data-disable-interaction")) {
3979
- disableInteraction = !!currentElement.getAttribute("data-disable-interaction");
3980
- } else {
3981
- disableInteraction = _this._options.disableInteraction;
3982
- }
3983
-
3984
- if (step > 0) {
3985
- introItems[step - 1] = {
3986
- element: currentElement,
3987
- title: currentElement.getAttribute("data-title") || "",
3988
- intro: currentElement.getAttribute("data-intro"),
3989
- step: parseInt(currentElement.getAttribute("data-step"), 10),
3990
- tooltipClass: currentElement.getAttribute("data-tooltipclass"),
3991
- highlightClass: currentElement.getAttribute("data-highlightclass"),
3992
- position: currentElement.getAttribute("data-position") || _this._options.tooltipPosition,
3993
- scrollTo: currentElement.getAttribute("data-scrollto") || _this._options.scrollTo,
3994
- disableInteraction: disableInteraction
3995
- };
3996
- }
3997
- }); //next add intro items without data-step
3998
- //todo: we need a cleanup here, two loops are redundant
3999
-
4000
- var _nextStep = 0;
4001
- forEach(allIntroSteps, function (currentElement) {
4002
- // PR #80
4003
- // start intro for groups of elements
4004
- if (group && currentElement.getAttribute("data-intro-group") !== group) {
4005
- return;
4006
- }
4007
-
4008
- if (currentElement.getAttribute("data-step") === null) {
4009
- while (true) {
4010
- if (typeof introItems[_nextStep] === "undefined") {
4011
- break;
4012
- } else {
4013
- _nextStep++;
4014
- }
4015
- }
4016
-
4017
- if (currentElement.hasAttribute("data-disable-interaction")) {
4018
- disableInteraction = !!currentElement.getAttribute("data-disable-interaction");
4019
- } else {
4020
- disableInteraction = _this._options.disableInteraction;
4021
- }
4022
-
4023
- introItems[_nextStep] = {
4024
- element: currentElement,
4025
- title: currentElement.getAttribute("data-title") || "",
4026
- intro: currentElement.getAttribute("data-intro"),
4027
- step: _nextStep + 1,
4028
- tooltipClass: currentElement.getAttribute("data-tooltipclass"),
4029
- highlightClass: currentElement.getAttribute("data-highlightclass"),
4030
- position: currentElement.getAttribute("data-position") || _this._options.tooltipPosition,
4031
- scrollTo: currentElement.getAttribute("data-scrollto") || _this._options.scrollTo,
4032
- disableInteraction: disableInteraction
4033
- };
4034
- }
4035
- });
4036
- } //removing undefined/null elements
4037
-
4038
-
4039
- var tempIntroItems = [];
4040
-
4041
- for (var z = 0; z < introItems.length; z++) {
4042
- if (introItems[z]) {
4043
- // copy non-falsy values to the end of the array
4044
- tempIntroItems.push(introItems[z]);
4045
- }
4046
- }
4047
-
4048
- introItems = tempIntroItems; //Ok, sort all items with given steps
4049
-
4050
- introItems.sort(function (a, b) {
4051
- return a.step - b.step;
4052
- }); //set it to the introJs object
4053
-
4054
- this._introItems = introItems; //add overlay layer to the page
4055
-
4056
- if (addOverlayLayer.call(this, targetElm)) {
4057
- //then, start the show
4058
- nextStep.call(this);
4059
-
4060
- if (this._options.keyboardNavigation) {
4061
- DOMEvent.on(window, "keydown", onKeyDown, this, true);
4062
- } //for window resize
4063
-
4064
-
4065
- DOMEvent.on(window, "resize", onResize, this, true);
4066
- }
4067
-
4068
- return false;
4069
- }
4070
-
4071
- var version$1 = "3.4.0";
4072
-
4073
- /**
4074
- * IntroJs main class
4075
- *
4076
- * @class IntroJs
4077
- */
4078
-
4079
- function IntroJs(obj) {
4080
- this._targetElement = obj;
4081
- this._introItems = [];
4082
- this._options = {
4083
- /* Next button label in tooltip box */
4084
- nextLabel: "Next",
4085
-
4086
- /* Previous button label in tooltip box */
4087
- prevLabel: "Back",
4088
-
4089
- /* Skip button label in tooltip box */
4090
- skipLabel: "×",
4091
-
4092
- /* Done button label in tooltip box */
4093
- doneLabel: "Done",
4094
-
4095
- /* Hide previous button in the first step? Otherwise, it will be disabled button. */
4096
- hidePrev: false,
4097
-
4098
- /* Hide next button in the last step? Otherwise, it will be disabled button (note: this will also hide the "Done" button) */
4099
- hideNext: false,
4100
-
4101
- /* Change the Next button to Done in the last step of the intro? otherwise, it will render a disabled button */
4102
- nextToDone: true,
4103
-
4104
- /* Default tooltip box position */
4105
- tooltipPosition: "bottom",
4106
-
4107
- /* Next CSS class for tooltip boxes */
4108
- tooltipClass: "",
4109
-
4110
- /* CSS class that is added to the helperLayer */
4111
- highlightClass: "",
4112
-
4113
- /* Close introduction when pressing Escape button? */
4114
- exitOnEsc: true,
4115
-
4116
- /* Close introduction when clicking on overlay layer? */
4117
- exitOnOverlayClick: true,
4118
-
4119
- /* Show step numbers in introduction? */
4120
- showStepNumbers: false,
4121
-
4122
- /* Let user use keyboard to navigate the tour? */
4123
- keyboardNavigation: true,
4124
-
4125
- /* Show tour control buttons? */
4126
- showButtons: true,
4127
-
4128
- /* Show tour bullets? */
4129
- showBullets: true,
4130
-
4131
- /* Show tour progress? */
4132
- showProgress: false,
4133
-
4134
- /* Scroll to highlighted element? */
4135
- scrollToElement: true,
4136
-
4137
- /*
4138
- * Should we scroll the tooltip or target element?
4139
- *
4140
- * Options are: 'element' or 'tooltip'
4141
- */
4142
- scrollTo: "element",
4143
-
4144
- /* Padding to add after scrolling when element is not in the viewport (in pixels) */
4145
- scrollPadding: 30,
4146
-
4147
- /* Set the overlay opacity */
4148
- overlayOpacity: 0.5,
4149
-
4150
- /* To determine the tooltip position automatically based on the window.width/height */
4151
- autoPosition: true,
4152
-
4153
- /* Precedence of positions, when auto is enabled */
4154
- positionPrecedence: ["bottom", "top", "right", "left"],
4155
-
4156
- /* Disable an interaction with element? */
4157
- disableInteraction: false,
4158
-
4159
- /* Set how much padding to be used around helper element */
4160
- helperElementPadding: 10,
4161
-
4162
- /* Default hint position */
4163
- hintPosition: "top-middle",
4164
-
4165
- /* Hint button label */
4166
- hintButtonLabel: "Got it",
4167
-
4168
- /* Adding animation to hints? */
4169
- hintAnimation: true,
4170
-
4171
- /* additional classes to put on the buttons */
4172
- buttonClass: "introjs-button",
4173
-
4174
- /* additional classes to put on progress bar */
4175
- progressBarAdditionalClass: false
4176
- };
4177
- }
4178
-
4179
- var introJs = function introJs(targetElm) {
4180
- var instance;
4181
-
4182
- if (_typeof(targetElm) === "object") {
4183
- //Ok, create a new instance
4184
- instance = new IntroJs(targetElm);
4185
- } else if (typeof targetElm === "string") {
4186
- //select the target element with query selector
4187
- var targetElement = document.querySelector(targetElm);
4188
-
4189
- if (targetElement) {
4190
- instance = new IntroJs(targetElement);
4191
- } else {
4192
- throw new Error("There is no element with given selector.");
4193
- }
4194
- } else {
4195
- instance = new IntroJs(document.body);
4196
- } // add instance to list of _instances
4197
- // passing group to stamp to increment
4198
- // from 0 onward somewhat reliably
4199
-
4200
-
4201
- introJs.instances[stamp(instance, "introjs-instance")] = instance;
4202
- return instance;
4203
- };
4204
- /**
4205
- * Current IntroJs version
4206
- *
4207
- * @property version
4208
- * @type String
4209
- */
4210
-
4211
-
4212
- introJs.version = version$1;
4213
- /**
4214
- * key-val object helper for introJs instances
4215
- *
4216
- * @property instances
4217
- * @type Object
4218
- */
4219
-
4220
- introJs.instances = {}; //Prototype
4221
-
4222
- introJs.fn = IntroJs.prototype = {
4223
- clone: function clone() {
4224
- return new IntroJs(this);
4225
- },
4226
- setOption: function setOption(option, value) {
4227
- this._options[option] = value;
4228
- return this;
4229
- },
4230
- setOptions: function setOptions(options) {
4231
- this._options = mergeOptions(this._options, options);
4232
- return this;
4233
- },
4234
- start: function start(group) {
4235
- introForElement.call(this, this._targetElement, group);
4236
- return this;
4237
- },
4238
- goToStep: function goToStep$1(step) {
4239
- goToStep.call(this, step);
4240
-
4241
- return this;
4242
- },
4243
- addStep: function addStep(options) {
4244
- if (!this._options.steps) {
4245
- this._options.steps = [];
4246
- }
4247
-
4248
- this._options.steps.push(options);
4249
-
4250
- return this;
4251
- },
4252
- addSteps: function addSteps(steps) {
4253
- if (!steps.length) return;
4254
-
4255
- for (var index = 0; index < steps.length; index++) {
4256
- this.addStep(steps[index]);
4257
- }
4258
-
4259
- return this;
4260
- },
4261
- goToStepNumber: function goToStepNumber$1(step) {
4262
- goToStepNumber.call(this, step);
4263
-
4264
- return this;
4265
- },
4266
- nextStep: function nextStep$1() {
4267
- nextStep.call(this);
4268
-
4269
- return this;
4270
- },
4271
- previousStep: function previousStep$1() {
4272
- previousStep.call(this);
4273
-
4274
- return this;
4275
- },
4276
- currentStep: function currentStep$1() {
4277
- return currentStep.call(this);
4278
- },
4279
- exit: function exit(force) {
4280
- exitIntro.call(this, this._targetElement, force);
4281
- return this;
4282
- },
4283
- refresh: function refresh$1() {
4284
- refresh.call(this);
4285
-
4286
- return this;
4287
- },
4288
- onbeforechange: function onbeforechange(providedCallback) {
4289
- if (typeof providedCallback === "function") {
4290
- this._introBeforeChangeCallback = providedCallback;
4291
- } else {
4292
- throw new Error("Provided callback for onbeforechange was not a function");
4293
- }
4294
-
4295
- return this;
4296
- },
4297
- onchange: function onchange(providedCallback) {
4298
- if (typeof providedCallback === "function") {
4299
- this._introChangeCallback = providedCallback;
4300
- } else {
4301
- throw new Error("Provided callback for onchange was not a function.");
4302
- }
4303
-
4304
- return this;
4305
- },
4306
- onafterchange: function onafterchange(providedCallback) {
4307
- if (typeof providedCallback === "function") {
4308
- this._introAfterChangeCallback = providedCallback;
4309
- } else {
4310
- throw new Error("Provided callback for onafterchange was not a function");
4311
- }
4312
-
4313
- return this;
4314
- },
4315
- oncomplete: function oncomplete(providedCallback) {
4316
- if (typeof providedCallback === "function") {
4317
- this._introCompleteCallback = providedCallback;
4318
- } else {
4319
- throw new Error("Provided callback for oncomplete was not a function.");
4320
- }
4321
-
4322
- return this;
4323
- },
4324
- onhintsadded: function onhintsadded(providedCallback) {
4325
- if (typeof providedCallback === "function") {
4326
- this._hintsAddedCallback = providedCallback;
4327
- } else {
4328
- throw new Error("Provided callback for onhintsadded was not a function.");
4329
- }
4330
-
4331
- return this;
4332
- },
4333
- onhintclick: function onhintclick(providedCallback) {
4334
- if (typeof providedCallback === "function") {
4335
- this._hintClickCallback = providedCallback;
4336
- } else {
4337
- throw new Error("Provided callback for onhintclick was not a function.");
4338
- }
4339
-
4340
- return this;
4341
- },
4342
- onhintclose: function onhintclose(providedCallback) {
4343
- if (typeof providedCallback === "function") {
4344
- this._hintCloseCallback = providedCallback;
4345
- } else {
4346
- throw new Error("Provided callback for onhintclose was not a function.");
4347
- }
4348
-
4349
- return this;
4350
- },
4351
- onexit: function onexit(providedCallback) {
4352
- if (typeof providedCallback === "function") {
4353
- this._introExitCallback = providedCallback;
4354
- } else {
4355
- throw new Error("Provided callback for onexit was not a function.");
4356
- }
4357
-
4358
- return this;
4359
- },
4360
- onskip: function onskip(providedCallback) {
4361
- if (typeof providedCallback === "function") {
4362
- this._introSkipCallback = providedCallback;
4363
- } else {
4364
- throw new Error("Provided callback for onskip was not a function.");
4365
- }
4366
-
4367
- return this;
4368
- },
4369
- onbeforeexit: function onbeforeexit(providedCallback) {
4370
- if (typeof providedCallback === "function") {
4371
- this._introBeforeExitCallback = providedCallback;
4372
- } else {
4373
- throw new Error("Provided callback for onbeforeexit was not a function.");
4374
- }
4375
-
4376
- return this;
4377
- },
4378
- addHints: function addHints() {
4379
- populateHints.call(this, this._targetElement);
4380
- return this;
4381
- },
4382
- hideHint: function hideHint$1(stepId) {
4383
- hideHint.call(this, stepId);
4384
-
4385
- return this;
4386
- },
4387
- hideHints: function hideHints$1() {
4388
- hideHints.call(this);
4389
-
4390
- return this;
4391
- },
4392
- showHint: function showHint$1(stepId) {
4393
- showHint.call(this, stepId);
4394
-
4395
- return this;
4396
- },
4397
- showHints: function showHints$1() {
4398
- showHints.call(this);
4399
-
4400
- return this;
4401
- },
4402
- removeHints: function removeHints$1() {
4403
- removeHints.call(this);
4404
-
4405
- return this;
4406
- },
4407
- removeHint: function removeHint$1(stepId) {
4408
- removeHint().call(this, stepId);
4409
-
4410
- return this;
4411
- },
4412
- showHintDialog: function showHintDialog$1(stepId) {
4413
- showHintDialog.call(this, stepId);
4414
-
4415
- return this;
4416
- }
4417
- };
4418
-
4419
- return introJs;
4420
-
4421
- })));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/node_modules/intro.js/introjs-rtl.css DELETED
@@ -1,23 +0,0 @@
1
- .introjs-tooltipbuttons {
2
- text-align: left; }
3
-
4
- .introjs-skipbutton {
5
- margin-left: 5px;
6
- float: left; }
7
-
8
- .introjs-tooltip-title {
9
- float: right; }
10
-
11
- .introjs-tooltip {
12
- direction: rtl; }
13
-
14
- .introjs-prevbutton {
15
- border: 1px solid #d4d4d4;
16
- float: right; }
17
-
18
- .introjs-nextbutton {
19
- border: 1px solid #d4d4d4;
20
- float: left; }
21
-
22
- .introjs-bullets ul li {
23
- float: right; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/node_modules/intro.js/introjs.css DELETED
@@ -1,436 +0,0 @@
1
- /*
2
- Buttons style by http://nicolasgallagher.com/lab/css3-github-buttons/
3
- Changed by Afshin Mehrabani
4
- */
5
- /* overrides extra padding on button elements in Firefox */
6
- @-webkit-keyframes introjspulse {
7
- 0% {
8
- -webkit-transform: scale(0);
9
- transform: scale(0);
10
- opacity: 0; }
11
- 25% {
12
- -webkit-transform: scale(0);
13
- transform: scale(0);
14
- opacity: 0.1; }
15
- 50% {
16
- -webkit-transform: scale(0.1);
17
- transform: scale(0.1);
18
- opacity: 0.3; }
19
- 75% {
20
- -webkit-transform: scale(0.5);
21
- transform: scale(0.5);
22
- opacity: 0.5; }
23
- 100% {
24
- -webkit-transform: scale(1);
25
- transform: scale(1);
26
- opacity: 0; } }
27
- @keyframes introjspulse {
28
- 0% {
29
- -webkit-transform: scale(0);
30
- transform: scale(0);
31
- opacity: 0; }
32
- 25% {
33
- -webkit-transform: scale(0);
34
- transform: scale(0);
35
- opacity: 0.1; }
36
- 50% {
37
- -webkit-transform: scale(0.1);
38
- transform: scale(0.1);
39
- opacity: 0.3; }
40
- 75% {
41
- -webkit-transform: scale(0.5);
42
- transform: scale(0.5);
43
- opacity: 0.5; }
44
- 100% {
45
- -webkit-transform: scale(1);
46
- transform: scale(1);
47
- opacity: 0; } }
48
-
49
- .introjs-overlay {
50
- position: absolute;
51
- -webkit-box-sizing: content-box;
52
- box-sizing: content-box;
53
- z-index: 999999;
54
- opacity: 0;
55
- -webkit-transition: all 0.3s ease-out;
56
- -o-transition: all 0.3s ease-out;
57
- transition: all 0.3s ease-out; }
58
-
59
- .introjs-showElement {
60
- z-index: 9999999 !important; }
61
-
62
- tr.introjs-showElement > td {
63
- z-index: 9999999 !important;
64
- position: relative; }
65
-
66
- tr.introjs-showElement > th {
67
- z-index: 9999999 !important;
68
- position: relative; }
69
-
70
- .introjs-disableInteraction {
71
- z-index: 99999999 !important;
72
- position: absolute;
73
- background-color: #ffffff;
74
- opacity: 0;
75
- filter: alpha(opacity=0); }
76
-
77
- .introjs-relativePosition {
78
- position: relative; }
79
-
80
- .introjs-helperLayer {
81
- -webkit-box-sizing: content-box;
82
- box-sizing: content-box;
83
- position: absolute;
84
- z-index: 9999998;
85
- border-radius: 4px;
86
- -webkit-transition: all 0.3s ease-out;
87
- -o-transition: all 0.3s ease-out;
88
- transition: all 0.3s ease-out; }
89
- .introjs-helperLayer * {
90
- -webkit-box-sizing: content-box;
91
- box-sizing: content-box; }
92
- .introjs-helperLayer *:before {
93
- -webkit-box-sizing: content-box;
94
- box-sizing: content-box; }
95
- .introjs-helperLayer *:after {
96
- -webkit-box-sizing: content-box;
97
- box-sizing: content-box; }
98
-
99
- .introjs-tooltipReferenceLayer {
100
- font-family: "Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif;
101
- -webkit-box-sizing: content-box;
102
- box-sizing: content-box;
103
- position: absolute;
104
- visibility: hidden;
105
- z-index: 100000000;
106
- background-color: transparent;
107
- -webkit-transition: all 0.3s ease-out;
108
- -o-transition: all 0.3s ease-out;
109
- transition: all 0.3s ease-out; }
110
- .introjs-tooltipReferenceLayer * {
111
- font-family: "Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif; }
112
-
113
- .introjs-helperNumberLayer {
114
- font-family: "Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif;
115
- color: #9e9e9e;
116
- text-align: center;
117
- padding-top: 10px;
118
- padding-bottom: 10px; }
119
-
120
- .introjs-arrow {
121
- border: 5px solid transparent;
122
- content: "";
123
- position: absolute; }
124
-
125
- .introjs-arrow.top {
126
- top: -10px;
127
- left: 10px;
128
- border-bottom-color: #ffffff; }
129
-
130
- .introjs-arrow.top-right {
131
- top: -10px;
132
- right: 10px;
133
- border-bottom-color: #ffffff; }
134
-
135
- .introjs-arrow.top-middle {
136
- top: -10px;
137
- left: 50%;
138
- margin-left: -5px;
139
- border-bottom-color: #ffffff; }
140
-
141
- .introjs-arrow.right {
142
- right: -10px;
143
- top: 10px;
144
- border-left-color: #ffffff; }
145
-
146
- .introjs-arrow.right-bottom {
147
- bottom: 10px;
148
- right: -10px;
149
- border-left-color: #ffffff; }
150
-
151
- .introjs-arrow.bottom {
152
- bottom: -10px;
153
- left: 10px;
154
- border-top-color: #ffffff; }
155
-
156
- .introjs-arrow.bottom-right {
157
- bottom: -10px;
158
- right: 10px;
159
- border-top-color: #ffffff; }
160
-
161
- .introjs-arrow.bottom-middle {
162
- bottom: -10px;
163
- left: 50%;
164
- margin-left: -5px;
165
- border-top-color: #ffffff; }
166
-
167
- .introjs-arrow.left {
168
- left: -10px;
169
- top: 10px;
170
- border-right-color: #ffffff; }
171
-
172
- .introjs-arrow.left-bottom {
173
- left: -10px;
174
- bottom: 10px;
175
- border-right-color: #ffffff; }
176
-
177
- .introjs-tooltip {
178
- -webkit-box-sizing: content-box;
179
- box-sizing: content-box;
180
- position: absolute;
181
- visibility: visible;
182
- background-color: #ffffff;
183
- min-width: 250px;
184
- max-width: 300px;
185
- border-radius: 5px;
186
- -webkit-box-shadow: 0 3px 30px rgba(33, 33, 33, 0.3);
187
- box-shadow: 0 3px 30px rgba(33, 33, 33, 0.3);
188
- -webkit-transition: opacity 0.1s ease-out;
189
- -o-transition: opacity 0.1s ease-out;
190
- transition: opacity 0.1s ease-out; }
191
-
192
- .introjs-tooltiptext {
193
- padding: 20px; }
194
-
195
- .introjs-tooltip-title {
196
- font-size: 18px;
197
- margin: 0;
198
- padding: 0;
199
- font-weight: 700;
200
- float: left;
201
- line-height: 32px; }
202
-
203
- .introjs-tooltip-header {
204
- padding-left: 20px;
205
- padding-right: 20px;
206
- padding-top: 10px; }
207
- .introjs-tooltip-header:after {
208
- content: ".";
209
- visibility: hidden;
210
- display: block;
211
- height: 0;
212
- clear: both; }
213
-
214
- .introjs-tooltipbuttons {
215
- border-top: 1px solid #e0e0e0;
216
- padding: 10px;
217
- text-align: right;
218
- white-space: nowrap; }
219
- .introjs-tooltipbuttons:after {
220
- content: "";
221
- visibility: hidden;
222
- display: block;
223
- height: 0;
224
- clear: both; }
225
-
226
- .introjs-button {
227
- -webkit-box-sizing: content-box;
228
- box-sizing: content-box;
229
- position: relative;
230
- overflow: visible;
231
- display: inline-block;
232
- padding: 0.5rem 1rem;
233
- border: 1px solid #bdbdbd;
234
- text-decoration: none;
235
- text-shadow: 1px 1px 0 #ffffff;
236
- font-size: 14px;
237
- color: #424242;
238
- white-space: nowrap;
239
- cursor: pointer;
240
- outline: none;
241
- background-color: #f4f4f4;
242
- border-radius: 0.2em;
243
- zoom: 1;
244
- *display: inline; }
245
- .introjs-button:hover {
246
- outline: none;
247
- text-decoration: none;
248
- border-color: #9e9e9e;
249
- background-color: #e0e0e0;
250
- color: #212121; }
251
- .introjs-button:focus {
252
- outline: none;
253
- text-decoration: none;
254
- background-color: #eeeeee;
255
- -webkit-box-shadow: 0 0 0 0.2rem rgba(158, 158, 158, 0.5);
256
- box-shadow: 0 0 0 0.2rem rgba(158, 158, 158, 0.5);
257
- border: 1px solid #616161;
258
- color: #212121; }
259
- .introjs-button:active {
260
- outline: none;
261
- text-decoration: none;
262
- background-color: #e0e0e0;
263
- border-color: #9e9e9e;
264
- color: #212121; }
265
- .introjs-button::-moz-focus-inner {
266
- padding: 0;
267
- border: 0; }
268
-
269
- .introjs-skipbutton {
270
- -webkit-box-sizing: content-box;
271
- box-sizing: content-box;
272
- color: #616161;
273
- float: right;
274
- font-size: 20px;
275
- cursor: pointer;
276
- font-weight: bold;
277
- line-height: 1;
278
- text-align: center;
279
- padding: 7px 10px; }
280
- .introjs-skipbutton:hover, .introjs-skipbutton:focus {
281
- color: #212121;
282
- outline: none;
283
- text-decoration: none; }
284
-
285
- .introjs-prevbutton {
286
- float: left; }
287
-
288
- .introjs-nextbutton {
289
- float: right; }
290
-
291
- .introjs-disabled {
292
- color: #9e9e9e;
293
- border-color: #bdbdbd;
294
- -webkit-box-shadow: none;
295
- box-shadow: none;
296
- cursor: default;
297
- background-color: #f4f4f4;
298
- background-image: none;
299
- text-decoration: none; }
300
- .introjs-disabled:hover, .introjs-disabled:focus {
301
- color: #9e9e9e;
302
- border-color: #bdbdbd;
303
- -webkit-box-shadow: none;
304
- box-shadow: none;
305
- cursor: default;
306
- background-color: #f4f4f4;
307
- background-image: none;
308
- text-decoration: none; }
309
-
310
- .introjs-hidden {
311
- display: none; }
312
-
313
- .introjs-bullets {
314
- text-align: center;
315
- padding-top: 10px;
316
- padding-bottom: 10px; }
317
- .introjs-bullets ul {
318
- -webkit-box-sizing: content-box;
319
- box-sizing: content-box;
320
- clear: both;
321
- margin: 0 auto 0;
322
- padding: 0;
323
- display: inline-block; }
324
- .introjs-bullets ul li {
325
- -webkit-box-sizing: content-box;
326
- box-sizing: content-box;
327
- list-style: none;
328
- float: left;
329
- margin: 0 2px; }
330
- .introjs-bullets ul li a {
331
- -webkit-transition: width 0.1s ease-in;
332
- -o-transition: width 0.1s ease-in;
333
- transition: width 0.1s ease-in;
334
- -webkit-box-sizing: content-box;
335
- box-sizing: content-box;
336
- display: block;
337
- width: 6px;
338
- height: 6px;
339
- background: #ccc;
340
- border-radius: 10px;
341
- text-decoration: none;
342
- cursor: pointer; }
343
- .introjs-bullets ul li a:hover, .introjs-bullets ul li a:focus {
344
- width: 15px;
345
- background: #999;
346
- text-decoration: none;
347
- outline: none; }
348
- .introjs-bullets ul li a.active {
349
- width: 15px;
350
- background: #999; }
351
-
352
- .introjs-progress {
353
- -webkit-box-sizing: content-box;
354
- box-sizing: content-box;
355
- overflow: hidden;
356
- height: 10px;
357
- margin: 10px;
358
- border-radius: 4px;
359
- background-color: #e0e0e0; }
360
-
361
- .introjs-progressbar {
362
- -webkit-box-sizing: content-box;
363
- box-sizing: content-box;
364
- float: left;
365
- width: 0%;
366
- height: 100%;
367
- font-size: 10px;
368
- line-height: 10px;
369
- text-align: center;
370
- background-color: #08c; }
371
-
372
- .introjsFloatingElement {
373
- position: absolute;
374
- height: 0;
375
- width: 0;
376
- left: 50%;
377
- top: 50%; }
378
-
379
- .introjs-fixedTooltip {
380
- position: fixed; }
381
-
382
- .introjs-hint {
383
- -webkit-box-sizing: content-box;
384
- box-sizing: content-box;
385
- position: absolute;
386
- background: transparent;
387
- width: 20px;
388
- height: 15px;
389
- cursor: pointer; }
390
- .introjs-hint:focus {
391
- border: 0;
392
- outline: 0; }
393
- .introjs-hint:hover > .introjs-hint-pulse {
394
- border: 5px solid rgba(60, 60, 60, 0.57); }
395
-
396
- .introjs-hidehint {
397
- display: none; }
398
-
399
- .introjs-fixedhint {
400
- position: fixed; }
401
-
402
- .introjs-hint-pulse {
403
- -webkit-box-sizing: content-box;
404
- box-sizing: content-box;
405
- width: 10px;
406
- height: 10px;
407
- border: 5px solid rgba(60, 60, 60, 0.27);
408
- border-radius: 30px;
409
- background-color: rgba(136, 136, 136, 0.24);
410
- z-index: 10;
411
- position: absolute;
412
- -webkit-transition: all 0.2s ease-out;
413
- -o-transition: all 0.2s ease-out;
414
- transition: all 0.2s ease-out; }
415
-
416
- .introjs-hint-no-anim .introjs-hint-dot {
417
- -webkit-animation: none;
418
- animation: none; }
419
-
420
- .introjs-hint-dot {
421
- -webkit-box-sizing: content-box;
422
- box-sizing: content-box;
423
- border: 10px solid rgba(146, 146, 146, 0.36);
424
- background: transparent;
425
- border-radius: 60px;
426
- height: 50px;
427
- width: 50px;
428
- -webkit-animation: introjspulse 3s ease-out;
429
- animation: introjspulse 3s ease-out;
430
- -webkit-animation-iteration-count: infinite;
431
- animation-iteration-count: infinite;
432
- position: absolute;
433
- top: -25px;
434
- left: -25px;
435
- z-index: 1;
436
- opacity: 0; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Admin/Conditional_Content/Black_Friday.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Tribe\Admin\Conditional_Content;
3
+
4
+ use Tribe__Date_Utils as Dates;
5
+
6
+ /**
7
+ * Set up for Black Friday promo.
8
+ *
9
+ * @since 4.14.7
10
+ */
11
+ class Black_Friday extends Datetime_Conditional_Abstract {
12
+ /**
13
+ * Promo slug.
14
+ *
15
+ * @since 4.14.7
16
+ */
17
+ protected $slug = 'black_friday';
18
+
19
+ /**
20
+ * Start Date.
21
+ *
22
+ * @since 4.14.7
23
+ */
24
+ protected $start_date = 'fourth Thursday of November';
25
+
26
+ /**
27
+ * End Date.
28
+ *
29
+ * @since 4.14.7
30
+ */
31
+ protected $end_date = 'November 30th';
32
+
33
+ /**
34
+ * Register actions and filters.
35
+ *
36
+ * @since 4.14.7
37
+ * @return void
38
+ */
39
+ public function hook() {
40
+ add_action( 'tribe_general_settings_tab_fields', [ $this, 'add_conditional_content' ] );
41
+ }
42
+
43
+ /**
44
+ * Start the Monday before Thanksgiving.
45
+ *
46
+ * @since 4.14.7
47
+ * @return int - Unix timestamp
48
+ */
49
+ protected function get_start_time() {
50
+ $date = parent::get_start_time();
51
+ $date = $date->modify( '-3 days' );
52
+
53
+ return $date;
54
+ }
55
+
56
+ /**
57
+ * Replace the opening markup for the general settings info box.
58
+ *
59
+ * @since 4.14.7
60
+ * @return void
61
+ */
62
+ public function add_conditional_content( $fields ) {
63
+ // Check if the content should currently be displayed.
64
+ if( ! $this->should_display() ) {
65
+ return $fields;
66
+ }
67
+
68
+ // Set up template variables.
69
+ $images_dir = \Tribe__Main::instance()->plugin_url . 'src/resources/images/';
70
+ $template_args = [
71
+ 'branding_logo' => $images_dir . 'logo/tec-brand.svg',
72
+ 'background_image' => $images_dir . 'marketing/bf-promo.png',
73
+ 'button_link' => 'https://evnt.is/1aqi',
74
+ ];
75
+
76
+ // Get the Black Friday promo content.
77
+ $content = $this->get_template()->template( 'conditional_content/black-friday', $template_args, false );
78
+
79
+ // Replace starting info box markup.
80
+ $fields['info-start']['html'] = '<div id="modern-tribe-info">' . $content;
81
+
82
+ return $fields;
83
+ }
84
+ }
common/src/Tribe/Admin/Conditional_Content/Datetime_Conditional_Abstract.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Tribe\Admin\Conditional_Content;
3
+
4
+ use Tribe__Date_Utils as Dates;
5
+
6
+ /**
7
+ * Abstract class for conditional content.
8
+ *
9
+ * @since 4.14.7
10
+ */
11
+ abstract class Datetime_Conditional_Abstract {
12
+ /**
13
+ * Item slug.
14
+ *
15
+ * @since 4.14.7
16
+ */
17
+ protected $slug = '';
18
+
19
+ /**
20
+ * Start date.
21
+ *
22
+ * @since 4.14.7
23
+ */
24
+ protected $start_date;
25
+
26
+ /**
27
+ * Start time.
28
+ *
29
+ * @since 4.14.7
30
+ */
31
+ protected $start_time;
32
+
33
+ /**
34
+ * End date.
35
+ *
36
+ * @since 4.14.7
37
+ */
38
+ protected $end_date;
39
+
40
+ /**
41
+ * End time.
42
+ *
43
+ * @since 4.14.7
44
+ */
45
+ protected $end_time;
46
+
47
+ /**
48
+ * Stores the instance of the template engine that we will use for rendering the page.
49
+ *
50
+ * @since 4.14.7
51
+ *
52
+ * @var \Tribe__Template
53
+ */
54
+ protected $template;
55
+
56
+ /**
57
+ * Register actions and filters.
58
+ *
59
+ * @since 4.14.7
60
+ * @return void
61
+ */
62
+ abstract function hook();
63
+
64
+ /**
65
+ * Unix datetime for content start.
66
+ *
67
+ * @since 4.14.7
68
+ * @return int - Unix timestamp
69
+ */
70
+ protected function get_start_time() {
71
+ $date = Dates::build_date_object( $this->start_date, 'UTC' );
72
+ $date = $date->setTime( $this->start_time, 0 );
73
+
74
+ /**
75
+ * Allow filtering of the start date for testing.
76
+ *
77
+ * @since 4.14.7
78
+ * @param \DateTime $date - Unix timestamp for start date
79
+ * @param object $this
80
+ */
81
+ $date = apply_filters( "tec_admin_conditional_content_{$this->slug}_start_date", $date, $this );
82
+
83
+ return $date;
84
+ }
85
+
86
+ /**
87
+ * Unix datetime for content end.
88
+ *
89
+ * @since 4.14.7
90
+ * @return int - Unix timestamp
91
+ */
92
+ protected function get_end_time() {
93
+ $date = Dates::build_date_object( $this->end_date, 'UTC' );
94
+ $date = $date->setTime( $this->end_time, 0 );
95
+
96
+ /**
97
+ * Allow filtering of the end date for testing.
98
+ *
99
+ * @since 4.14.7
100
+ * @param \DateTime $date - Unix timestamp for end date
101
+ * @param object $this
102
+ */
103
+ $date = apply_filters( "tec_admin_conditional_content_{$this->slug}_end_date", $date, $this );
104
+
105
+ return $date;
106
+ }
107
+
108
+ /**
109
+ * Whether the content should display.
110
+ *
111
+ * @since 4.14.7
112
+ * @return boolean - Whether the content should display
113
+ */
114
+ protected function should_display() {
115
+ $now = Dates::build_date_object( 'now', 'UTC' );
116
+ $notice_start = $this->get_start_time();
117
+ $notice_end = $this->get_end_time();
118
+ $display = $notice_start <= $now && $now < $notice_end;
119
+
120
+ /**
121
+ * Allow filtering whether the content should display.
122
+ *
123
+ * @since 4.14.7
124
+ * @param bool $should_display - whether the content should display
125
+ * @param object $this - the conditional content object
126
+ */
127
+ $should_display = apply_filters( "tec_admin_conditional_content_{$this->slug}_should_display", $display, $this );
128
+
129
+ return $should_display;
130
+ }
131
+
132
+ /**
133
+ * Gets the template instance used to setup the rendering of the page.
134
+ *
135
+ * @since 4.14.7
136
+ *
137
+ * @return \Tribe__Template
138
+ */
139
+ public function get_template() {
140
+ if ( empty( $this->template ) ) {
141
+ $this->template = new \Tribe__Template();
142
+ $this->template->set_template_origin( \Tribe__Main::instance() );
143
+ $this->template->set_template_folder( 'src/admin-views' );
144
+ $this->template->set_template_context_extract( true );
145
+ $this->template->set_template_folder_lookup( false );
146
+ }
147
+
148
+ return $this->template;
149
+ }
150
+ }
common/src/Tribe/Admin/Conditional_Content/Service_Provider.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles admin conditional content.
4
+ *
5
+ * @since 4.14.7
6
+ * @package Tribe\Admin\Conditional_Content;
7
+ */
8
+
9
+ namespace Tribe\Admin\Conditional_Content;
10
+
11
+ /**
12
+ * Conditional Content Provider.
13
+ *
14
+ * @since 4.14.7
15
+ */
16
+ class Service_Provider extends \tad_DI52_ServiceProvider {
17
+
18
+ /**
19
+ * Registers the required objects and filters.
20
+ *
21
+ * @since 4.14.7
22
+ */
23
+ public function register() {
24
+ $this->container->singleton( Black_Friday::class, Black_Friday::class, [ 'hook' ] );
25
+ $this->hooks();
26
+ }
27
+
28
+ /**
29
+ * Set up hooks for classes.
30
+ *
31
+ * @since 4.14.7
32
+ */
33
+ protected function hooks() {
34
+ add_action( 'tribe_plugins_loaded', [ $this, 'plugins_loaded' ] );
35
+ }
36
+
37
+ /**
38
+ * Setup for things that require plugins loaded first.
39
+ *
40
+ * @since 4.14.7
41
+ */
42
+ public function plugins_loaded() {
43
+ $this->container->make( Black_Friday::class );
44
+ }
45
+ }
common/src/Tribe/Admin/Notice/Date_Based.php CHANGED
@@ -64,6 +64,15 @@ abstract class Date_Based {
64
  */
65
  public $tec_is_active;
66
 
 
 
 
 
 
 
 
 
 
67
  /**
68
  * Whether or not Event Tickets is active.
69
  *
@@ -146,7 +155,7 @@ abstract class Date_Based {
146
  return false;
147
  }
148
 
149
- $now = Dates::build_date_object( 'now', 'UTC' )->format( 'U' );
150
  $notice_start = $this->get_start_time();
151
  $notice_end = $this->get_end_time();
152
 
@@ -182,9 +191,9 @@ abstract class Date_Based {
182
  *
183
  * @param \DateTime $date Date object for the notice start.
184
  */
185
- $date = apply_filters( "tribe_{$this->slug}_notice_start_date", $date );
186
 
187
- return $date->format( 'U' );
188
  }
189
 
190
  /**
@@ -206,8 +215,27 @@ abstract class Date_Based {
206
  *
207
  * @param \DateTime $date Date object for the notice end.
208
  */
209
- $date = apply_filters( "tribe_{$this->slug}_notice_end_date", $date );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
 
211
- return $date->format( 'U' );
212
  }
213
  }
64
  */
65
  public $tec_is_active;
66
 
67
+ /**
68
+ * Stores the instance of the template engine that we will use for rendering the page.
69
+ *
70
+ * @since 4.14.7
71
+ *
72
+ * @var \Tribe__Template
73
+ */
74
+ protected $template;
75
+
76
  /**
77
  * Whether or not Event Tickets is active.
78
  *
155
  return false;
156
  }
157
 
158
+ $now = Dates::build_date_object( 'now', 'UTC' );
159
  $notice_start = $this->get_start_time();
160
  $notice_end = $this->get_end_time();
161
 
191
  *
192
  * @param \DateTime $date Date object for the notice start.
193
  */
194
+ $date = apply_filters( "tribe_{$this->slug}_notice_start_date", $date, $this );
195
 
196
+ return $date;
197
  }
198
 
199
  /**
215
  *
216
  * @param \DateTime $date Date object for the notice end.
217
  */
218
+ $date = apply_filters( "tribe_{$this->slug}_notice_end_date", $date, $this );
219
+
220
+ return $date;
221
+ }
222
+
223
+ /**
224
+ * Gets the template instance used to setup the rendering of the page.
225
+ *
226
+ * @since 4.14.7
227
+ *
228
+ * @return \Tribe__Template
229
+ */
230
+ public function get_template() {
231
+ if ( empty( $this->template ) ) {
232
+ $this->template = new \Tribe__Template();
233
+ $this->template->set_template_origin( \Tribe__Main::instance() );
234
+ $this->template->set_template_folder( 'src/admin-views' );
235
+ $this->template->set_template_context_extract( true );
236
+ $this->template->set_template_folder_lookup( false );
237
+ }
238
 
239
+ return $this->template;
240
  }
241
  }
common/src/Tribe/Admin/Notice/Marketing/Black_Friday.php CHANGED
@@ -29,15 +29,13 @@ class Black_Friday extends \Tribe\Admin\Notice\Date_Based {
29
 
30
  /**
31
  * {@inheritDoc}
32
- *
33
- * 11am UTC is 3am PST and 5am EST
34
  */
35
- public $start_time = 11;
36
 
37
  /**
38
  * {@inheritDoc}
39
  */
40
- public $end_date = 'December 1st';
41
 
42
  /**
43
  * {@inheritDoc}
@@ -45,41 +43,30 @@ class Black_Friday extends \Tribe\Admin\Notice\Date_Based {
45
  public function display_notice() {
46
  \Tribe__Assets::instance()->enqueue( [ 'tribe-common-admin' ] );
47
 
48
- // Used in the template.
49
- $cta_url = 'https://evnt.is/1aqi';
50
- $icon_url = \Tribe__Main::instance()->plugin_url . 'src/resources/images/icons/sale-burst.svg';
51
-
52
- ob_start();
 
53
 
54
- include \Tribe__Main::instance()->plugin_path . 'src/admin-views/notices/tribe-bf-general.php';
 
55
 
56
- return ob_get_clean();
57
  }
58
 
59
  /**
60
  * Unix time for notice start.
61
- * Note: we could instead use the ...notice_start_date filter to modify the date
62
- * but this seemed more straightforward for now.
63
  *
64
  * @since 4.14.2
65
  *
66
  * @return int $end_time The date & time the notice should start displaying, as a Unix timestamp.
67
  */
68
  public function get_start_time() {
69
- $date = Dates::build_date_object( $this->start_date, 'UTC' );
70
  $date = $date->modify( '-3 days' );
71
- $date = $date->setTime( $this->start_time, 0 );
72
-
73
- /**
74
- * Allow filtering of the start date DateTime object,
75
- * to allow for things like "the day before" ( $date->modify( '-1 day' ) ) and such.
76
- *
77
- * @since 4.14.2
78
- *
79
- * @param \DateTime $date Date object for the notice start.
80
- */
81
- $date = apply_filters( "tribe_{$this->slug}_notice_start_date", $date );
82
 
83
- return $date->format( 'U' );
84
  }
85
  }
29
 
30
  /**
31
  * {@inheritDoc}
 
 
32
  */
33
+ public $end_date = 'November 29';
34
 
35
  /**
36
  * {@inheritDoc}
37
  */
38
+ public $end_time = 23;
39
 
40
  /**
41
  * {@inheritDoc}
43
  public function display_notice() {
44
  \Tribe__Assets::instance()->enqueue( [ 'tribe-common-admin' ] );
45
 
46
+ // Set up template variables.
47
+ $template_args = [
48
+ 'icon_url' => \Tribe__Main::instance()->plugin_url . 'src/resources/images/icons/sale-burst.svg',
49
+ 'cta_url' => 'https://evnt.is/1aqi',
50
+ 'end_date' => $this->get_end_time()->format_i18n( 'F jS' ),
51
+ ];
52
 
53
+ // Get the Black Friday notice content.
54
+ $content = $this->get_template()->template( 'notices/tribe-bf-general', $template_args, false );
55
 
56
+ return $content;
57
  }
58
 
59
  /**
60
  * Unix time for notice start.
 
 
61
  *
62
  * @since 4.14.2
63
  *
64
  * @return int $end_time The date & time the notice should start displaying, as a Unix timestamp.
65
  */
66
  public function get_start_time() {
67
+ $date = parent::get_start_time();
68
  $date = $date->modify( '-3 days' );
 
 
 
 
 
 
 
 
 
 
 
69
 
70
+ return $date;
71
  }
72
  }
common/src/Tribe/Ajax/Dropdown.php CHANGED
@@ -89,7 +89,7 @@ class Tribe__Ajax__Dropdown {
89
  }
90
 
91
  foreach ( $results as $result ) {
92
- $result->text = wp_specialchars_decode( wp_kses( $result->text, [] ) );
93
  }
94
 
95
  $data['results'] = $results;
89
  }
90
 
91
  foreach ( $results as $result ) {
92
+ $result->text = wp_kses_post( htmlspecialchars_decode( $result->text ) );
93
  }
94
 
95
  $data['results'] = $results;
common/src/Tribe/Editor.php CHANGED
@@ -29,7 +29,7 @@ class Tribe__Editor {
29
  public function should_load_blocks() {
30
  $gutenberg = $this->is_gutenberg_active() || $this->is_wp_version();
31
  $blocks = $this->is_blocks_editor_active();
32
- $classic = $this->is_classic_plugin_active() || $this->is_classic_option_active();
33
 
34
  $should_load_blocks = $gutenberg && $blocks && ! $classic;
35
 
@@ -173,7 +173,16 @@ class Tribe__Editor {
173
  * @return bool
174
  */
175
  public function is_classic_plugin_active() {
176
- $is_plugin_active = function_exists( 'classic_editor_replace' ) || class_exists( 'Classic_Editor' );
 
 
 
 
 
 
 
 
 
177
  /**
178
  * Filter to change the output of calling: `is_classic_plugin_active`
179
  *
@@ -196,6 +205,11 @@ class Tribe__Editor {
196
  * @return bool
197
  */
198
  public function is_classic_option_active() {
 
 
 
 
 
199
  $valid_values = [ 'replace', 'classic' ];
200
 
201
  return in_array( (string) get_option( 'classic-editor-replace' ), $valid_values, true );
29
  public function should_load_blocks() {
30
  $gutenberg = $this->is_gutenberg_active() || $this->is_wp_version();
31
  $blocks = $this->is_blocks_editor_active();
32
+ $classic = $this->is_classic_option_active();
33
 
34
  $should_load_blocks = $gutenberg && $blocks && ! $classic;
35
 
173
  * @return bool
174
  */
175
  public function is_classic_plugin_active() {
176
+ // Timing means we can't rely on `is_plugin_active()` here.
177
+ $classic_editor_active = in_array(
178
+ 'classic-editor/classic-editor.php',
179
+ apply_filters( 'active_plugins', get_option( 'active_plugins', [] ) )
180
+ );
181
+
182
+ $is_plugin_active = $classic_editor_active
183
+ || class_exists( 'Classic_Editor' )
184
+ || function_exists( 'classic_editor_replace' );
185
+
186
  /**
187
  * Filter to change the output of calling: `is_classic_plugin_active`
188
  *
205
  * @return bool
206
  */
207
  public function is_classic_option_active() {
208
+ // Since the plugin leaves the `classic-editor-replace` value in the database on deactivation, let's make sure it's active first.
209
+ if ( ! $this->is_classic_plugin_active() ) {
210
+ return false;
211
+ }
212
+
213
  $valid_values = [ 'replace', 'classic' ];
214
 
215
  return in_array( (string) get_option( 'classic-editor-replace' ), $valid_values, true );
common/src/Tribe/Main.php CHANGED
@@ -20,7 +20,7 @@ class Tribe__Main {
20
  const OPTIONNAME = 'tribe_events_calendar_options';
21
  const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
22
 
23
- const VERSION = '4.14.5';
24
 
25
  const FEED_URL = 'https://theeventscalendar.com/feed/';
26
 
@@ -654,8 +654,8 @@ class Tribe__Main {
654
  tribe_register_provider( Tribe\Log\Service_Provider::class );
655
  tribe_register_provider( Tribe\Service_Providers\Crons::class );
656
  tribe_register_provider( Tribe\Service_Providers\Widgets::class );
657
- tribe_register_provider( Tribe\Service_Providers\Onboarding::class );
658
  tribe_register_provider( Tribe\Admin\Notice\Service_Provider::class );
 
659
  }
660
 
661
  /**
20
  const OPTIONNAME = 'tribe_events_calendar_options';
21
  const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
22
 
23
+ const VERSION = '4.14.7';
24
 
25
  const FEED_URL = 'https://theeventscalendar.com/feed/';
26
 
654
  tribe_register_provider( Tribe\Log\Service_Provider::class );
655
  tribe_register_provider( Tribe\Service_Providers\Crons::class );
656
  tribe_register_provider( Tribe\Service_Providers\Widgets::class );
 
657
  tribe_register_provider( Tribe\Admin\Notice\Service_Provider::class );
658
+ tribe_register_provider( Tribe\Admin\Conditional_Content\Service_Provider::class );
659
  }
660
 
661
  /**
common/src/Tribe/Onboarding/Hints_Abstract.php DELETED
@@ -1,98 +0,0 @@
1
- <?php
2
- namespace Tribe\Onboarding;
3
-
4
- /**
5
- * Class Hints Abstract.
6
- *
7
- * @since TBD
8
- */
9
- abstract class Hints_Abstract {
10
-
11
- /**
12
- * The hints ID.
13
- *
14
- * @since TBD
15
- *
16
- * @var string
17
- */
18
- public $hints_id;
19
-
20
- /**
21
- * Times to display the hints.
22
- *
23
- * @since TBD
24
- *
25
- * @var int
26
- */
27
- public $times_to_display;
28
-
29
- /**
30
- * Return if it's on page where it should be displayed.
31
- *
32
- * @since TBD
33
- *
34
- * @return bool True if it is on page.
35
- */
36
- public function is_on_page() {
37
- return false;
38
- }
39
-
40
- /**
41
- * Should the hints display.
42
- *
43
- * @since TBD
44
- *
45
- * @return boolean True if it should display.
46
- */
47
- public function should_display() {
48
- // Bail if it's not on the page we want to display.
49
- if ( ! $this->is_on_page() ) {
50
- return false;
51
- }
52
-
53
- // Bail if the `Times to display` is set and it was reached.
54
- if (
55
- is_numeric( $this->times_to_display )
56
- && ( tribe( 'onboarding' )->get_views( $this->hints_id ) > $this->times_to_display )
57
- ) {
58
- return false;
59
- }
60
-
61
- return true;
62
- }
63
-
64
- /**
65
- * Return the hints data.
66
- *
67
- * @since TBD
68
- *
69
- * @return array The hints.
70
- */
71
- abstract function hints();
72
-
73
- /**
74
- * Return the CSS classes.
75
- *
76
- * @since TBD
77
- *
78
- * @return array The CSS classes.
79
- */
80
- public function css_classes() {
81
- return [];
82
- }
83
-
84
- /**
85
- * The hints data, publicly accessible.
86
- *
87
- * @since TBD.
88
- *
89
- * @param array $data An array with the hints data.
90
- * @return array
91
- */
92
- public function hints_data( array $data = [] ) {
93
- $data['hints'] = $this->hints();
94
- $data['classes'] = $this->css_classes();
95
-
96
- return $data;
97
- }
98
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Onboarding/Main.php DELETED
@@ -1,223 +0,0 @@
1
- <?php
2
- namespace Tribe\Onboarding;
3
-
4
- /**
5
- * Class
6
- *
7
- * @since TBD
8
- */
9
- class Main {
10
-
11
- /**
12
- * Get the tour steps.
13
- *
14
- * @since TBD
15
- *
16
- * @return array $steps The tour data.
17
- */
18
- private function tour_data() {
19
- $data = [];
20
- $registered_tours = $this->get_registered_tours();
21
-
22
- // Try to populate, if it should display.
23
- foreach ( $registered_tours as $tour => $class_name ) {
24
- $tour_class = new $class_name();
25
-
26
- if ( $tour_class->should_display() ) {
27
- // Increment the views when the tour is displayed.
28
- $this->increment_views( $tour_class->tour_id );
29
- $data = $tour_class->tour_data( $data );
30
-
31
- /**
32
- * We're displaying the tour.
33
- *
34
- * @since TBD.
35
- *
36
- * @param string $tour_id The tour id.
37
- */
38
- do_action( 'tribe_onboarding_tour_display', $tour_class->tour_id );
39
-
40
- break;
41
- }
42
- }
43
-
44
- /**
45
- * Filter the data we're using to localize the tour steps.
46
- *
47
- * Since TBD
48
- *
49
- * @param array $data An array with the tour data.
50
- *
51
- * @return array $data An array with the tour data.
52
- */
53
- $data = apply_filters( 'tribe_onboarding_tour_data', $data );
54
-
55
- return $data;
56
- }
57
-
58
- /**
59
- * Get the hints.
60
- *
61
- * @since TBD
62
- *
63
- * @return array $steps The hints data.
64
- */
65
- private function hints_data() {
66
- $data = [];
67
- $registered_hints = $this->get_registered_hints();
68
-
69
- // Try to populate, and check if it should display.
70
- foreach ( $registered_hints as $hints => $class_name ) {
71
- $hints_class = new $class_name();
72
-
73
- if ( $hints_class->should_display() ) {
74
- // Increment the views when the tour is displayed.
75
- $this->increment_views( $hints_class->tour_id );
76
- $data = $hints_class->hints_data( $data );
77
-
78
- /**
79
- * We're displaying the hints.
80
- *
81
- * @since TBD.
82
- *
83
- * @param string $hints_id The hints id.
84
- */
85
- do_action( 'tribe_onboarding_hints_display', $hints_class->hints_id );
86
-
87
- break;
88
- }
89
- }
90
-
91
- /**
92
- * Filter the data we're using to localize the hints.
93
- *
94
- * Since TBD
95
- *
96
- * @param array $data An array with the hints data.
97
- *
98
- * @return array $data An array with the hints data.
99
- */
100
- $data = apply_filters( 'tribe_onboarding_hints_data', $data );
101
-
102
- return $data;
103
- }
104
-
105
- /**
106
- * Localize tour data.
107
- *
108
- * @since TBD
109
- *
110
- * @param string $hook The current admin page.
111
- */
112
- public function localize_tour( $hook ) {
113
- $data = $this->tour_data();
114
-
115
- wp_localize_script( 'tribe-onboarding-js', 'TribeOnboardingTour', $data );
116
- }
117
-
118
- /**
119
- * Localize hints data.
120
- *
121
- * @since TBD
122
- *
123
- * @param string $hook The current admin page.
124
- */
125
- public function localize_hints( $hook ) {
126
- $data = $this->hints_data();
127
-
128
- wp_localize_script( 'tribe-onboarding-js', 'TribeOnboardingHints', $data );
129
- }
130
-
131
- /**
132
- * Get the views for an onboarding element.
133
- *
134
- * @since TBD
135
- *
136
- * @param string $id The onboarding ID (tour or hint).
137
- *
138
- * @return mixed The views for the given ID.
139
- */
140
- public function get_views( $id = '' ) {
141
-
142
- if ( empty( $id ) ) {
143
- return;
144
- }
145
-
146
- $option = tribe_get_option( 'tribe_onboarding_views', [] );
147
-
148
- if ( ! isset( $option[ $id ] ) ) {
149
- return;
150
- }
151
-
152
- return intval( $option[ $id ] );
153
- }
154
-
155
- /**
156
- * Increment views for an onboarding element.
157
- *
158
- * @since TBD
159
- *
160
- * @param string $id The onboarding ID (tour or hint).
161
- * @return int The views count for the particular `$id`.
162
- */
163
- public function increment_views( $id ) {
164
- $option = tribe_get_option( 'tribe_onboarding_views', [] );
165
- $views = 0;
166
-
167
- if ( isset( $option[ $id ] ) ) {
168
- $views = intval( $option[ $id ] );
169
- }
170
-
171
- // Increment views and save.
172
- $views++;
173
- $option[ $id ] = $views;
174
-
175
- tribe_update_option( 'tribe_onboarding_views', $option );
176
-
177
- return $views;
178
- }
179
-
180
- /**
181
- * Get the list of tours available for handling.
182
- *
183
- * @since TBD
184
- *
185
- * @return array An associative array of shortcodes in the shape `[ <slug> => <class> ]`
186
- */
187
- public function get_registered_tours() {
188
- $tours = [];
189
-
190
- /**
191
- * Allow the registering of tours into our plugins.
192
- *
193
- * @since TBD
194
- *
195
- * @var array An associative array of tours in the shape `[ <id> => <class> ]`.
196
- */
197
- $tours = apply_filters( 'tribe_onboarding_tours', $tours );
198
-
199
- return $tours;
200
- }
201
-
202
- /**
203
- * Get the list of hints available for handling.
204
- *
205
- * @since TBD
206
- *
207
- * @return array An associative array of hints in the shape `[ <id> => <class> ]`
208
- */
209
- public function get_registered_hints() {
210
- $hints = [];
211
-
212
- /**
213
- * Allow the registering of tours into our plugins.
214
- *
215
- * @since TBD
216
- *
217
- * @var array An associative array of hints in the shape `[ <id> => <class> ]`.
218
- */
219
- $tours = apply_filters( 'tribe_onboarding_hints', $hints );
220
-
221
- return $hints;
222
- }
223
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Onboarding/README.md DELETED
@@ -1,242 +0,0 @@
1
- # Onboarding
2
-
3
- Onboarding consists of two components. Tours & Hints. The idea of this components is to enhance the onboarding experience and add some contextual help for elements.
4
-
5
- These components work as a wrapper of [IntroJS](https://introjs.com/).
6
-
7
- If for any reason you want to disable the Onboarding library, you can use the following filter:
8
-
9
- `add_filter( 'tribe_onboarding_disable, '__return_true' );`
10
-
11
- ## Tours
12
-
13
- **Tours** provides an easy way to onboard users on a step by step basis. The information is provided to the user on a modal.
14
-
15
- Users can navigate through the different steps and close the modal at any time by clicking outside of it.
16
-
17
- Setting up tours is fairly simple. It all comes down to hooking onto `tribe_onboarding_tour_data`.
18
-
19
- The information to be sent there is an array in the following format:
20
-
21
- ```
22
- $tour_data = [
23
- 'steps' = [], // An array of the steps you'd like for the tour.
24
- 'classes' = [], // An array of CSS classes to apply to the modal. (Optional)
25
- ];
26
- ```
27
-
28
- The format of each step can contain the following:
29
-
30
- ```
31
- $step = [
32
- 'title' => __( 'Welcome to this screen' ), // The step title.
33
- 'intro' => __( 'This is the description of the "Welcome to this screen" message.' );
34
- 'element' => '#my-html-id', // If you want to highlight a certain part of the HTML for this step. If not defined, it'll show just the modal with the information. (Optional)
35
- ];
36
- ```
37
-
38
- So for example, if you want to add a simple welcome tour for a settings panel you could add the following.
39
-
40
- ```
41
- add_filter( 'tribe_onboarding_tour_data', 'my_fancy_tour' );
42
-
43
- function my_fancy_tour( $data ) {
44
-
45
- // Here you can do some checks to see if you're in the page you want to show to tour.
46
-
47
- $steps = [
48
- [
49
- 'title' => __( '🤘 Welcome to the settings panel' ),
50
- 'intro' => __( 'It is actually great that you are using our plugins! From this settings panel you should be able to access all the settings to configure your site.' ),
51
- ],
52
- [
53
- 'title' => __( '⚙️ Different sections' ),
54
- 'element' => '#tribe-settings-tabs',
55
- 'intro' => __( 'On this section you can access all of the different settings of our plugins, if you have questions about which settings we have you can go to <a href="#whatever">our knowledgebase article</a>' ),
56
- ],
57
- [
58
- 'title' => __( '🛠️ Change the settings' ),
59
- 'element' => '#tribe-field-postsPerPage',
60
- 'intro' => __( 'If you need to change any configuration, you can do it! If you have questions about which settings we have you can go to <a href="#whatever">our knowledgebase article</a>' ),
61
- ],
62
- [
63
- 'title' => __( '💡 Save the Settings' ),
64
- 'element' => '#tribeSaveSettings',
65
- 'intro' => __( 'Please remember to save the settings, if you have questions about which settings we have you can go to <a href="#whatever">our knowledgebase article</a>' ),
66
- ],
67
- ];
68
-
69
- $data['steps'] = $steps;
70
- $data['classes'] = [ 'my__fancy-css-class', 'my__fancy-css-class--modifier' ];
71
-
72
- return $data;
73
- }
74
- ```
75
-
76
- ### Setting up Tours from TEC plugins
77
-
78
- Setting up new tours from our plugins should be easy with the abstract classes we have in place.
79
-
80
- We should be registering the tours we want, hooking them into the `tribe_onboarding_tours` filter.
81
-
82
- The function to hook onto `tribe_onboarding_tours` should have the following format:
83
-
84
- ```
85
- /**
86
- * Register tours.
87
- *
88
- * @see \Tribe\Onboarding\Main::get_registered_tours()
89
- *
90
- * @since TBD
91
- *
92
- * @param array $tours An associative array of tours in the shape `[ <tour_id> => <class> ]`.
93
- *
94
- * @return array
95
- */
96
- public function filter_register_tours( array $tours ) {
97
- $tours['my_awesome_tour_id'] = MyAwesomeTourClass::class;
98
-
99
- return $tours;
100
- }
101
- ```
102
-
103
- And then `MyAwesomeTourClass` should have the following format:
104
-
105
- ```
106
- use Tribe\Onboarding\Tour_Abstract;
107
- /**
108
- * Class MyAwesomeTourClass
109
- */
110
- class MyAwesomeTourClass extends Tour_Abstract {
111
-
112
- /**
113
- * The tour ID.
114
- *
115
- * @var string
116
- */
117
- public $tour_id = 'my_awesome_tour_id';
118
-
119
- /**
120
- * Times to display the tour.
121
- * If you set '5', then it'll be displayed FIVE times.
122
- *
123
- * @var int
124
- */
125
- public $times_to_display = 5;
126
-
127
- /**
128
- * Returns if it's on the page we want to display the tour for.
129
- *
130
- * @return bool True if it's on page.
131
- */
132
- public function is_on_page() {
133
-
134
- // Perform any check you want, to see if the tour should display or not.
135
- return $admin_helpers->is_screen( 'tribe_events_page_tribe-common' );
136
- }
137
-
138
- /**
139
- * Tour steps.
140
- *
141
- * @since TBD
142
- *
143
- * @return array $steps The tour steps
144
- */
145
- public function steps() {
146
-
147
- $steps = [
148
- [
149
- 'title' => __( '🤘 Welcome to the settings panel' ),
150
- 'intro' => __( 'It is actually great that you are using our plugins! From this settings panel you should be able to access all the settings to configure your site.' ),
151
- ],
152
- [
153
- 'title' => __( '⚙️ Different sections' ),
154
- 'element' => '#tribe-settings-tabs',
155
- 'intro' => __( 'On this section you can access all of the different settings of our plugins, if you have questions about which settings we have you can go to <a href="#whatever">our knowledgebase article</a>' ),
156
- ],
157
- [
158
- 'title' => __( '🛠️ Change the settings' ),
159
- 'element' => '#tribe-field-postsPerPage',
160
- 'intro' => __( 'If you need to change any configuration, you can do it! If you have questions about which settings we have you can go to <a href="#whatever">our knowledgebase article</a>' ),
161
- ],
162
- [
163
- 'title' => __( '💡 Save the Settings' ),
164
- 'element' => '#tribeSaveSettings',
165
- 'intro' => __( 'Please remember to save the settings, if you have questions about which settings we have you can go to <a href="#whatever">our knowledgebase article</a>' ),
166
- ],
167
- ];
168
-
169
- return $steps;
170
- }
171
-
172
- /**
173
- * Tour CSS Classes.
174
- *
175
- * Here you can set additional CSS classes for the particular tour.
176
- *
177
- * @return array $css_classes The tour extra CSS classes.
178
- */
179
- public function css_classes() {
180
-
181
- return [ 'my-awesome-css-class' ];
182
- }
183
- }
184
-
185
- ```
186
-
187
- ## Hints
188
-
189
- **Hints** are great for providing non-intrusive contextual help. Each hing will be associated to a particular HTML element (which you can define by a CSS class or an ID) and it'll add kind of a "infinite bouncing dot" besides that element. When clicked you'll have some more context on what's the purpose of that.
190
-
191
- Technically speaking **Hints** work pretty similarly to how **Tours** do. The mechanics of adding a set of hints is almost the same.
192
-
193
- It comes down to hooking onto `tribe_onboarding_hints_data`.
194
-
195
- The information to be sent there is an array in the following format:
196
-
197
- ```
198
- $hints_data = [
199
- 'hints' = [], // An array of the hints you'd like to have.
200
- 'classes' = [], // An array of CSS classes to apply to the modal/tooltip. (Optional)
201
- ];
202
- ```
203
-
204
- So for example, if you want to add a hint for a newly added button:
205
-
206
- ```
207
- add_filter( 'tribe_onboarding_hints_data', 'my_fancy_hints' );
208
-
209
- function my_fancy_hints( $data ) {
210
- $hints = [
211
- [
212
- 'hint' => __( 'You can now add attendees for this event!' ),
213
- 'element' => '.add_attendee',
214
- ],
215
- ];
216
-
217
- $data['hints'] = $hints;
218
- $data['classes'] = [ 'my__fancy-css-class', 'my__fancy-css-class--modifier' ];
219
-
220
- return $data;
221
- }
222
- ```
223
-
224
- ## CSS classes that you may want to use:
225
-
226
- - `.tribe-onboarding__tooltip--large` - Use if if you want your tooltip to be bigger/wider.
227
- - `.tribe-onboarding__tooltip--dark` - Use if if you want your tooltip to have a dark skin (to use an image for the background, or just a plain dark color).
228
- - `.tribe-onboarding__tooltip--squared` - Use it if you want a squared tooltip.
229
- - `.tribe-onboarding__tooltip--no-bullets` - Use it if you want to hide the navigation bullets.
230
- - `.tribe-onboarding__tooltip--title-large` - Use it if you want to have a bigger title.
231
- - `.tribe-onboarding__tooltip--content-centered` - Use it if you want to center the content.
232
- - `.tribe-onboarding__tooltip--button-centered` - Use it if you want to center the buttons.
233
- - `.tribe-onboarding__tooltip--button-large` - Use it if you want to have a bigger button.
234
- - `.tribe-onboarding__tooltip--button-rounded` - Use it if you want to have a rounded button.
235
- - `.tribe-onboarding__tooltip--button-dark-skin` - Use it if you want to have a button for dark skin (white background / dark text button).
236
-
237
-
238
- ### 💡 To-Do's / Ideas:
239
-
240
- - [ ] Add some more styles variations.
241
- - [ ] Maybe add the possibility of having animated GIFs/images on each step.
242
- - [ ] Add some abstraction to extend this anywhere, and make it easier to check if it's in the page, and load the tours and/or hints we would like to add.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Onboarding/Tour_Abstract.php DELETED
@@ -1,98 +0,0 @@
1
- <?php
2
- namespace Tribe\Onboarding;
3
-
4
- /**
5
- * Class Tour Abstract.
6
- *
7
- * @since TBD
8
- */
9
- abstract class Tour_Abstract {
10
-
11
- /**
12
- * The tour ID.
13
- *
14
- * @since TBD
15
- *
16
- * @var string
17
- */
18
- public $tour_id;
19
-
20
- /**
21
- * Times to display the tour.
22
- *
23
- * @since TBD
24
- *
25
- * @var int
26
- */
27
- public $times_to_display;
28
-
29
- /**
30
- * Return if it's on page where it should be displayed.
31
- *
32
- * @since TBD
33
- *
34
- * @return bool True if it is on page.
35
- */
36
- public function is_on_page() {
37
- return false;
38
- }
39
-
40
- /**
41
- * Should the tour display.
42
- *
43
- * @since TBD
44
- *
45
- * @return boolean True if it should display.
46
- */
47
- public function should_display() {
48
- // Bail if it's not on the page we want to display.
49
- if ( ! $this->is_on_page() ) {
50
- return false;
51
- }
52
-
53
- // Bail if the `Times to display` is set and it was reached.
54
- if (
55
- is_numeric( $this->times_to_display )
56
- && ( tribe( 'onboarding' )->get_views( $this->tour_id ) > $this->times_to_display )
57
- ) {
58
- return false;
59
- }
60
-
61
- return true;
62
- }
63
-
64
- /**
65
- * Return the tour steps.
66
- *
67
- * @since TBD
68
- *
69
- * @return array The tour steps.
70
- */
71
- abstract function steps();
72
-
73
- /**
74
- * Return the CSS classes.
75
- *
76
- * @since TBD
77
- *
78
- * @return array The CSS classes.
79
- */
80
- public function css_classes() {
81
- return [];
82
- }
83
-
84
- /**
85
- * The tour data, publicly accessible.
86
- *
87
- * @since TBD.
88
- *
89
- * @param array $data An array with the tour data.
90
- * @return array
91
- */
92
- public function tour_data( array $data = [] ) {
93
- $data['steps'] = $this->steps();
94
- $data['classes'] = $this->css_classes();
95
-
96
- return $data;
97
- }
98
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/PUE/Checker.php CHANGED
@@ -446,8 +446,11 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
446
  $domain = self::$domain;
447
 
448
  if ( empty( $domain ) ) {
449
- if ( isset( $_SERVER['SERVER_NAME'] ) ) {
450
- $domain = $_SERVER['SERVER_NAME'];
 
 
 
451
  }
452
 
453
  if ( is_multisite() ) {
446
  $domain = self::$domain;
447
 
448
  if ( empty( $domain ) ) {
449
+ $url = wp_parse_url( get_option( 'siteurl' ) );
450
+ if ( ! empty( $url ) && isset( $url['host'] ) ) {
451
+ $domain = $url['host'];
452
+ } elseif ( isset( $_SERVER['SERVER_NAME'] ) ) {
453
+ $domain = $_SERVER['SERVER_NAME'];
454
  }
455
 
456
  if ( is_multisite() ) {
common/src/Tribe/Service_Providers/Onboarding.php DELETED
@@ -1,140 +0,0 @@
1
- <?php
2
- namespace Tribe\Service_Providers;
3
-
4
- /**
5
- * Class Onboarding
6
- *
7
- * @since TBD
8
- *
9
- * Handles the registration and creation of our async process handlers.
10
- */
11
- class Onboarding extends \tad_DI52_ServiceProvider {
12
-
13
- /**
14
- * The Onboarding assets group identifier.
15
- *
16
- * @var string
17
- */
18
- public static $group_key = 'tribe-onboarding';
19
-
20
- /**
21
- * Binds and sets up implementations.
22
- *
23
- * @since TBD
24
- */
25
- public function register() {
26
- tribe_singleton( 'onboarding', '\Tribe\Onboarding\Main' );
27
-
28
- $this->hooks();
29
- }
30
-
31
- /**
32
- * Set up hooks for classes.
33
- *
34
- * @since TBD
35
- */
36
- private function hooks() {
37
- add_action( 'tribe_common_loaded', [ $this, 'register_assets' ] );
38
-
39
- add_action( 'admin_enqueue_scripts', tribe_callback( 'onboarding', 'localize_tour' ) );
40
- add_action( 'admin_enqueue_scripts', tribe_callback( 'onboarding', 'localize_hints' ) );
41
- }
42
-
43
- /**
44
- * Register assets associated with onboarding.
45
- *
46
- * @since TBD
47
- */
48
- public function register_assets() {
49
- $main = \Tribe__Main::instance();
50
-
51
- tribe_asset(
52
- $main,
53
- 'intro-js',
54
- 'node_modules/intro.js/intro.js',
55
- [],
56
- [ 'admin_enqueue_scripts' ],
57
- [
58
- 'groups' => self::$group_key,
59
- 'conditionals' => [ $this, 'should_enqueue_assets' ],
60
- ]
61
- );
62
-
63
- tribe_asset(
64
- $main,
65
- 'intro-styles',
66
- 'node_modules/intro.js/introjs.css',
67
- [],
68
- [ 'admin_enqueue_scripts' ],
69
- [
70
- 'groups' => self::$group_key,
71
- 'conditionals' => [ $this, 'should_enqueue_assets' ],
72
- ]
73
- );
74
-
75
- tribe_asset(
76
- $main,
77
- 'tribe-onboarding-styles',
78
- 'onboarding.css',
79
- [ 'intro-styles', 'tec-variables-skeleton', 'tec-variables-full' ],
80
- [ 'admin_enqueue_scripts' ],
81
- [
82
- 'groups' => self::$group_key,
83
- 'conditionals' => [ $this, 'should_enqueue_assets' ],
84
- ]
85
- );
86
-
87
- tribe_asset(
88
- $main,
89
- 'tribe-onboarding-js',
90
- 'onboarding.js',
91
- [
92
- 'tribe-common',
93
- 'intro-js'
94
- ],
95
- [ 'admin_enqueue_scripts' ],
96
- [
97
- 'groups' => self::$group_key,
98
- 'in_footer' => false,
99
- 'localize' => [
100
- 'name' => 'TribeOnboarding',
101
- 'data' => [
102
- 'hintButtonLabel' => __( 'Got it', 'tribe-common' ),
103
- ],
104
- ],
105
- 'conditionals' => [ $this, 'should_enqueue_assets' ],
106
- ]
107
- );
108
- }
109
-
110
- /**
111
- * Define if the assets for `Onboarding` should be enqueued or not.
112
- *
113
- * @since TBD
114
- *
115
- * @return bool If the Onboarding assets should be enqueued or not.
116
- */
117
- public function should_enqueue_assets() {
118
- return $this->is_enabled();
119
- }
120
-
121
- /**
122
- * Check if the onboarding is enabled or not.
123
- *
124
- * @since TBD
125
- *
126
- * @return bool
127
- */
128
- public function is_enabled() {
129
- /**
130
- * Filter to disable tribe onboarding
131
- *
132
- * @since TBD
133
- *
134
- * @param bool $disabled If we want to disable the onboarding.
135
- */
136
- $is_disabled = (bool) apply_filters( 'tribe_onboarding_disable', false );
137
-
138
- return is_admin() && ! $is_disabled;
139
- }
140
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/admin-views/conditional_content/black-friday.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template for Black Friday Promo.
4
+ *
5
+ * @since 4.14.7
6
+ * @var string $background_image - the url of the background image to use
7
+ * @var string $branding_logo - the url of the TEC branding logo
8
+ * @var string $button_link - the url the button links to
9
+ */
10
+ ?>
11
+
12
+ <div class="black-friday-promo">
13
+ <div class="black-friday-promo__branding">
14
+ <img
15
+ src="<?php echo esc_url( $branding_logo ); ?>"
16
+ alt="<?php echo esc_attr__( 'The Events Calendar brand logo', 'tribe-common' ); ?>"
17
+ class="black-friday-promo__branding-image"
18
+ />
19
+ </div>
20
+ <div class="black-friday-promo__promo" style="background-image: url('<?php echo $background_image; ?>')">
21
+ <div class="black-friday-promo__content">
22
+ <p class="black-friday-promo__text">
23
+ <?php _e( 'Our biggest<br/> sale of the<br/> year ends<br/> soon</p>', 'tribe-common' ); ?>
24
+ <a
25
+ href="<?php echo esc_url( $button_link ); ?>"
26
+ class="button black-friday-promo__button"
27
+ rel="noreferrer noopener"
28
+ target="_blank"
29
+ >
30
+ <?php echo esc_html__( 'Save now', 'tribe-common' ); ?>
31
+ </a>
32
+ </p>
33
+ </div>
34
+ </div>
35
+ </div>
common/src/admin-views/notices/tribe-bf-general.php CHANGED
@@ -6,6 +6,7 @@
6
  *
7
  * @var string $icon_url The local URL for the notice's image.
8
  * @var string $cta_url The short URL for black friday.
 
9
  */
10
  ?>
11
  <div class="tribe-marketing-notice">
@@ -13,10 +14,18 @@
13
  <img src="<?php echo esc_url( $icon_url ); ?>"/>
14
  </div>
15
  <div class="tribe-marketing-notice__content">
16
- <h3>Save 40% on Every. Single. Plugin.</h3>
17
  <p>
18
- Black Friday Sale now through November 30.
19
- <span class="tribe-marketing-notice__cta"><a target="_blank" href="<?php echo esc_url( $cta_url ); ?>">Shop now</a></span>
 
 
 
 
 
 
 
 
20
  </p>
21
  </div>
22
  </div>
6
  *
7
  * @var string $icon_url The local URL for the notice's image.
8
  * @var string $cta_url The short URL for black friday.
9
+ * @var string $end_date - the end date of the sale.
10
  */
11
  ?>
12
  <div class="tribe-marketing-notice">
14
  <img src="<?php echo esc_url( $icon_url ); ?>"/>
15
  </div>
16
  <div class="tribe-marketing-notice__content">
17
+ <h3><?php echo esc_html__( 'Save 40% on every single plugin.', 'tribe-common' ); ?></h3>
18
  <p>
19
+ <?php printf( esc_html__( 'Black Friday Sale now through %s.', 'tribe-common' ), $end_date ); ?>
20
+ <span class="tribe-marketing-notice__cta">
21
+ <a
22
+ href="<?php echo esc_url( $cta_url ); ?>"
23
+ rel="noreferrer noopener"
24
+ target="_blank"
25
+ >
26
+ <?php echo esc_html__( 'Shop now', 'tribe-common' ); ?>
27
+ </a>
28
+ </span>
29
  </p>
30
  </div>
31
  </div>
common/src/functions/utils.php CHANGED
@@ -1229,3 +1229,23 @@ if ( ! function_exists( 'tribe_without_filters' ) ) {
1229
  return $result;
1230
  }
1231
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1229
  return $result;
1230
  }
1231
  }
1232
+
1233
+ /**
1234
+ * Get the next increment of a cached incremental value.
1235
+ *
1236
+ * @since 4.14.7
1237
+ *
1238
+ * @param string $key Cache key for the incrementor.
1239
+ * @param string $expiration_trigger The trigger that causes the cache key to expire.
1240
+ * @param int $default The default value of the incrementor.
1241
+ *
1242
+ * @return int
1243
+ **/
1244
+ function tribe_get_next_cached_increment( $key, $expiration_trigger = '', $default = 0 ) {
1245
+ $cache = tribe( 'cache' );
1246
+ $value = (int) $cache->get( $key, $expiration_trigger, $default );
1247
+ $value++;
1248
+ $cache->set( $key, $value, \Tribe__Cache::NON_PERSISTENT, $expiration_trigger );
1249
+
1250
+ return $value;
1251
+ }
common/src/resources/css/common-full.min.css CHANGED
@@ -1 +1 @@
1
- .tribe-common figure{line-height:0}.tribe-common figcaption{line-height:normal}.tribe-common a{background-color:transparent;-webkit-text-decoration-skip:objects}.tribe-common abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.tribe-common code,.tribe-common kbd,.tribe-common pre,.tribe-common samp{font-family:monospace;font-size:1em}.tribe-common b,.tribe-common strong{font-weight:inherit;font-weight:bolder}.tribe-common dfn{font-style:italic}.tribe-common mark{background-color:#ff0;color:#000}.tribe-common small{font-size:80%}.tribe-common sub,.tribe-common sup{font-size:75%;line-height:0}.tribe-common hr{border:0;height:0}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=email],.tribe-common input[type=password],.tribe-common input[type=reset],.tribe-common input[type=search],.tribe-common input[type=submit],.tribe-common input[type=text],.tribe-common input[type=url],.tribe-common textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none}.tribe-common button,.tribe-common input,.tribe-common optgroup,.tribe-common select,.tribe-common textarea{color:inherit;font:inherit;-webkit-font-smoothing:antialiased;line-height:normal}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{border-radius:0;outline:0}.tribe-common select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.tribe-common optgroup{font-weight:700}.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common p{font-weight:400;text-rendering:optimizeLegibility}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{opacity:1}.tribe-theme-twentynineteen .tribe-common h1:before,.tribe-theme-twentynineteen .tribe-common h2:before{content:none}.tribe-theme-twentynineteen .tribe-common button,.tribe-theme-twentynineteen .tribe-common input[type=button],.tribe-theme-twentynineteen .tribe-common input[type=reset],.tribe-theme-twentynineteen .tribe-common input[type=submit]{outline:none}.tribe-theme-twentynineteen .tribe-common td,.tribe-theme-twentynineteen .tribe-common th{word-break:normal}.tribe-theme-twentyseventeen .tribe-common h5{letter-spacing:normal;text-transform:none}.tribe-theme-twentyseventeen .tribe-common input[type=text]{border-radius:0}.tribe-theme-twentytwenty .tribe-common{background-color:var(--tec-color-background-events);letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common input,.tribe-theme-twentytwenty .tribe-common textarea{letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common *{word-break:normal}.tribe-theme-twentytwentyone.tribe-common .tribe-common .button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-button .wp-block-button__link:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-file a.wp-block-file__button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-search .wp-block-search__button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common input[type=reset]:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common input[type=submit]:not(:hover):not(:active):not(.has-background){background-color:transparent;background-color:initial}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{line-height:0}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-form-control-checkbox__label:hover,.tribe-common .tribe-common-form-control-radio__label:hover{opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-default);height:20px;position:relative;width:20px}.tribe-common .tribe-common-form-control-checkbox__input:active,.tribe-common .tribe-common-form-control-checkbox__input:focus,.tribe-common .tribe-common-form-control-checkbox__input:hover,.tribe-common .tribe-common-form-control-radio__input:active,.tribe-common .tribe-common-form-control-radio__input:focus,.tribe-common .tribe-common-form-control-radio__input:hover{border-color:var(--tec-form-color-border-active);opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-checkbox__input:checked,.tribe-common .tribe-common-form-control-radio__input:checked{background-color:var(--tec-form-color-border-active)}.tribe-common .tribe-common-form-control-checkbox__input{border-radius:4px}.tribe-common .tribe-common-form-control-checkbox__input:checked:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='%23fff'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;content:"";display:block;height:9px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}.tribe-common .tribe-common-form-control-checkbox__input:focus+.tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-checkbox__input:hover+.tribe-common-form-control-checkbox__label{opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-radio__input{border-radius:50%}.tribe-common .tribe-common-form-control-radio__input:checked:before{background-color:var(--tec-form-color-background);border-radius:50%;content:"";display:block;height:8px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:8px}.tribe-common .tribe-common-form-control-radio__input:focus+.tribe-common-form-control-radio__label,.tribe-common .tribe-common-form-control-radio__input:hover+.tribe-common-form-control-radio__label{opacity:var(--tec-opacity-icon-hover)}#top .main_color .tribe-common .tribe-common-form-control-checkbox__label,#top .main_color .tribe-common .tribe-common-form-control-radio__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label{font-size:var(--tec-font-size-2);font-weight:var(--tec-font-weight-regular)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-checkbox__input:checked:before{margin:0}.tribe-common .tribe-common-form-control-slider{line-height:0}.tribe-common .tribe-common-form-control-slider__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:var(--tec-transition-background-color);background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-slider__input::-moz-range-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:var(--tec-transition-background-color);background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-slider__input::-ms-track{background-color:transparent;border-color:transparent;border-width:5px 0;color:transparent;height:10px}.tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,.tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper{background-color:var(--tec-form-color-accent-primary);border-radius:10px}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px;-webkit-appearance:none;appearance:none}.tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px}.tribe-common .tribe-common-form-control-slider__input::-ms-thumb{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px;box-shadow:none;margin-top:-1px}.tribe-common .tribe-common-form-control-slider__label{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);line-height:var(--tec-line-height-0);color:var(--tec-color-text-secondary)}#top .main_color .tribe-common .tribe-common-form-control-slider__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label,.tribe-common .tribe-common-form-control-slider__label{font-size:var(--tec-font-size-1);font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-form-control-text__input{font-size:var(--tec-font-size-3);border:0;border-bottom:1px solid var(--tec-color-border-default)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input,.tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{font-size:var(--tec-font-size-2);border:0}.tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder{color:var(--tec-color-text-secondary);font-style:normal;opacity:var(--tec-opacity-default)}.tribe-common .tribe-common-form-control-text__input::placeholder{color:var(--tec-color-text-secondary);font-style:normal;opacity:var(--tec-opacity-default)}.tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:var(--tec-color-border-active);outline:0}.tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-text__input{line-height:inherit}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);background:var(--tec-color-background);border:0;border-bottom:1px solid var(--tec-color-border-default)}#top .main_color .tribe-common .tribe-common-form-control-text__input:focus,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:var(--tec-color-border-active);box-shadow:none}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);border:0}.tribe-common .tribe-common-form-control-toggle{line-height:0;position:relative}.tribe-common .tribe-common-form-control-toggle__input{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:var(--tec-transition-background-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--tec-form-color-border-secondary);width:40px}.tribe-common .tribe-common-form-control-toggle__input::-ms-check{display:none}.tribe-common .tribe-common-form-control-toggle__input+label:before{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;content:"";left:0;position:absolute;top:0;transition:var(--tec-transition-transform)}.tribe-common .tribe-common-form-control-toggle__input:checked{background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-toggle__input:checked+label:before{transform:translateX(20px)}.tribe-common .tribe-common-form-control-toggle__label{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);line-height:var(--tec-line-height-0);color:var(--tec-color-text-secondary)}#top .main_color .tribe-common .tribe-common-form-control-toggle__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label,.tribe-common .tribe-common-form-control-toggle__label{font-size:var(--tec-font-size-1);font-weight:var(--tec-font-weight-regular)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-toggle__input{top:0}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-toggle__input:checked:before{content:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-form-control-toggle__input:after{display:none}.tribe-common a,.tribe-common a:active,.tribe-common a:focus,.tribe-common a:hover,.tribe-common a:visited{color:var(--tec-color-text-primary);outline:0;text-decoration:none}.site-footer .widget-area .tribe-common a,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a,.tribe-theme-twentyseventeen .tribe-common a{box-shadow:none}.site-footer .widget-area .tribe-common a:focus,.site-footer .widget-area .tribe-common a:hover,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a:focus,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a:hover,.tribe-theme-twentyseventeen .tribe-common a:focus,.tribe-theme-twentyseventeen .tribe-common a:hover{box-shadow:none;color:var(--tec-color-text-primary)}.tribe-theme-twentynineteen .entry .tribe-common a,.tribe-theme-twentynineteen .tribe-common a,.tribe-theme-twentytwentyone .entry .tribe-common a,.tribe-theme-twentytwentyone .tribe-common a{text-decoration:none}.main_color .sidebar .tribe-common a,.main_color .sidebar .tribe-common a:active,.main_color .sidebar .tribe-common a:focus,.main_color .sidebar .tribe-common a:hover,.main_color .sidebar .tribe-common a:visited,.tribe-theme-enfold .tribe-common a,.tribe-theme-enfold .tribe-common a:active,.tribe-theme-enfold .tribe-common a:focus,.tribe-theme-enfold .tribe-common a:hover,.tribe-theme-enfold .tribe-common a:visited{color:var(--tec-color-text-primary)}.tribe-common .tribe-common-anchor{border-bottom:2px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-anchor:active,.tribe-common .tribe-common-anchor:focus,.tribe-common .tribe-common-anchor:hover{border-bottom:2px solid currentColor}.tribe-common .tribe-common-anchor-alt{border-bottom:2px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-anchor-alt:active,.tribe-common .tribe-common-anchor-alt:focus,.tribe-common .tribe-common-anchor-alt:hover{border-bottom:2px solid currentColor;color:var(--tec-color-link-accent)}.tribe-common .tribe-common-anchor-thin{border-bottom:1px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-anchor-thin:active,.tribe-common .tribe-common-anchor-thin:focus,.tribe-common .tribe-common-anchor-thin:hover{border-bottom:1px solid var(--tec-color-link-primary)}.tribe-common .tribe-common-anchor-thin-alt{border-bottom:1px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-anchor-thin-alt:active,.tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-common .tribe-common-anchor-thin-alt:hover{border-bottom:1px solid currentColor;color:var(--tec-color-link-accent)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:hover{color:var(--tec-color-accent-primary)}.site-footer .widget-area .tribe-common .tribe-common-anchor,.site-footer .widget-area .tribe-common .tribe-common-anchor-thin,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-thin{transition:var(--tec-transition-border-color)}.site-footer .widget-area .tribe-common .tribe-common-anchor-alt,.site-footer .widget-area .tribe-common .tribe-common-anchor-thin-alt,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-alt,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-thin-alt{transition:var(--tec-transition-color)}.tribe-common .tribe-common-b1{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);font-weight:var(--tec-font-weight-regular);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-b1--bold{font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-b2{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-1);font-weight:var(--tec-font-weight-regular);line-height:var(--tec-line-height-0)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-b2--bold{font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-b3{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-0);font-weight:var(--tec-font-weight-regular);line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-b3--bold{font-weight:var(--tec-font-weight-bold)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3--min-medium,.tribe-common .tribe-common-cta{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-cta{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-regular);font-weight:var(--tec-font-weight-bold);border-bottom:2px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-cta:active,.tribe-common .tribe-common-cta:focus,.tribe-common .tribe-common-cta:hover{border-bottom:2px solid currentColor}.tribe-common .tribe-common-cta--alt{border-bottom:2px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-cta--alt:active,.tribe-common .tribe-common-cta--alt:focus,.tribe-common .tribe-common-cta--alt:hover{border-bottom:2px solid currentColor;color:var(--tec-color-link-accent)}.tribe-common .tribe-common-cta--thin{border-bottom:1px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-cta--thin:active,.tribe-common .tribe-common-cta--thin:focus,.tribe-common .tribe-common-cta--thin:hover{border-bottom:1px solid var(--tec-color-link-primary)}.tribe-common .tribe-common-cta--thin-alt{border-bottom:1px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-cta--thin-alt:active,.tribe-common .tribe-common-cta--thin-alt:focus,.tribe-common .tribe-common-cta--thin-alt:hover{border-bottom:1px solid currentColor;color:var(--tec-color-link-accent)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:hover{color:var(--tec-color-accent-primary)}.tribe-common .tribe-common-h1{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h1{font-size:var(--tec-font-size-10);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-h2{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h2{font-size:var(--tec-font-size-9);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-h3{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-6);line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-common .tribe-common-h4{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-5);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-common .tribe-common-h5{font-size:var(--tec-font-size-4)}.tribe-common .tribe-common-h5,.tribe-common .tribe-common-h6{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);line-height:var(--tec-line-height-2)}.tribe-common .tribe-common-h6{font-size:var(--tec-font-size-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h7{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h7,.tribe-common .tribe-common-h8{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-h8{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3--min-medium{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4--min-medium{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h5--min-medium{font-size:var(--tec-font-size-4);line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h7--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h--alt{font-weight:var(--tec-font-weight-regular)}.tribe-theme-avada #main .tribe-common .tribe-common-h1{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h1{font-size:var(--tec-font-size-10);line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common .tribe-common-h2{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h2{font-size:var(--tec-font-size-9);line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common .tribe-common-h3{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-6);line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common .tribe-common-h4{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-5);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common .tribe-common-h5{font-size:var(--tec-font-size-4)}.tribe-theme-avada #main .tribe-common .tribe-common-h5,.tribe-theme-avada #main .tribe-common .tribe-common-h6{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common .tribe-common-h6{font-size:var(--tec-font-size-3)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h7{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h7,.tribe-theme-avada #main .tribe-common .tribe-common-h8{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold)}.tribe-theme-avada #main .tribe-common .tribe-common-h8{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3--min-medium{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4--min-medium{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h5--min-medium{font-size:var(--tec-font-size-4);line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h7--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h--alt{font-weight:var(--tec-font-weight-regular)}.tribe-common button{border:none}.tribe-common button,.tribe-common button:focus,.tribe-common button:hover,.tribe-theme-twentyseventeen .tribe-common button:focus,.tribe-theme-twentyseventeen .tribe-common button:hover{background-color:transparent}.tribe-theme-twentytwenty .tribe-common button{background-color:transparent;text-transform:inherit}.tribe-theme-twentytwenty .tribe-common button:focus,.tribe-theme-twentytwenty .tribe-common button:hover{text-decoration:none}.tribe-theme-twentytwentyone .tribe-common button:not(:hover):not(:active){background-color:inherit;color:inherit}.tribe-theme-enfold .tribe-common th{letter-spacing:0;text-transform:none}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);font-weight:var(--tec-font-weight-bold);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:var(--tec-color-background);border:1px solid var(--tec-color-accent-primary);border-radius:var(--tec-border-radius-default);text-align:center;transition:var(--tec-transition);color:var(--tec-color-button-primary);padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{width:auto}.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{background-color:var(--tec-color-accent-primary);color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:active{opacity:.9}.tribe-common .tribe-common-c-btn-border--secondary,.tribe-common a.tribe-common-c-btn-border--secondary{border-color:var(--tec-color-button-secondary);color:var(--tec-color-button-secondary)}.tribe-common .tribe-common-c-btn-border--secondary:focus,.tribe-common .tribe-common-c-btn-border--secondary:hover,.tribe-common a.tribe-common-c-btn-border--secondary:focus,.tribe-common a.tribe-common-c-btn-border--secondary:hover{background-color:var(--tec-color-button-secondary)}.tribe-common .tribe-common-c-btn-border--secondary:active,.tribe-common a.tribe-common-c-btn-border--secondary:active{opacity:.9}.tribe-common .tribe-common-c-btn-border--alt,.tribe-common a.tribe-common-c-btn-border--alt{border-color:var(--tec-color-border-secondary);color:var(--tec-color-text-primary);font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-c-btn-border--alt:focus,.tribe-common .tribe-common-c-btn-border--alt:hover,.tribe-common a.tribe-common-c-btn-border--alt:focus,.tribe-common a.tribe-common-c-btn-border--alt:hover{background-color:var(--tec-color-background);border-color:var(--tec-color-border-active);color:var(--tec-color-text-primary)}.tribe-common .tribe-common-c-btn-border--alt:active,.tribe-common a.tribe-common-c-btn-border--alt:active{opacity:.9}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:hover{background-color:var(--tec-color-button-primary)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--secondary:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--secondary:hover{background-color:var(--tec-color-button-secondary)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--alt:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0);font-weight:var(--tec-font-weight-regular);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:var(--tec-color-background);border:1px solid var(--tec-color-border-default);border-radius:var(--tec-border-radius-default);text-align:center;transition:var(--tec-transition-color-border-color)}.tribe-common .tribe-common-c-btn-border-small:focus,.tribe-common .tribe-common-c-btn-border-small:hover,.tribe-common a.tribe-common-c-btn-border-small:focus,.tribe-common a.tribe-common-c-btn-border-small:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border-small:active,.tribe-common a.tribe-common-c-btn-border-small:active{border-color:var(--tec-color-border-active)}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{color:var(--tec-color-text-secondary);padding:14px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border-small,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border-small{padding:6px 15px;width:auto}.tribe-common .tribe-common-c-btn-border-small:active,.tribe-common .tribe-common-c-btn-border-small:focus,.tribe-common .tribe-common-c-btn-border-small:hover,.tribe-common a.tribe-common-c-btn-border-small:active,.tribe-common a.tribe-common-c-btn-border-small:focus,.tribe-common a.tribe-common-c-btn-border-small:hover{color:var(--tec-color-text-primary)}.tribe-common .tribe-common-c-btn-border-small:disabled,.tribe-common a.tribe-common-c-btn-border-small:disabled{color:var(--tec-color-text-disabled)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border-small:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-icon{border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto}.tribe-common .tribe-common-c-btn-icon--caret-left:active .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-left:focus .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-left:hover .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:active .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:focus .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:hover .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-primary)}.tribe-common .tribe-common-c-btn-icon--caret-left:disabled .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:disabled .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-disabled)}.tribe-common .tribe-common-c-btn-icon--caret-left .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-secondary)}.tribe-common .tribe-common-c-btn-icon--border{align-items:center;background-color:var(--tec-color-background);border:1px solid var(--tec-color-border-default);display:inline-flex;height:56px;justify-content:center;transition:none;width:56px}.tribe-common .tribe-common-c-btn-icon--border:focus,.tribe-common .tribe-common-c-btn-icon--border:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-icon--border:active{border-color:var(--tec-color-border-active)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-icon--border:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);font-weight:var(--tec-font-weight-bold);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;border-radius:var(--tec-border-radius-default);color:var(--tec-color-background);text-align:center;transition:var(--tec-transition-background-color);background-color:var(--tec-color-button-primary);padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-btn:focus,.tribe-common .tribe-common-c-btn:hover,.tribe-common a.tribe-common-c-btn:focus,.tribe-common a.tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover)}.tribe-common .tribe-common-c-btn:active,.tribe-common a.tribe-common-c-btn:active{background-color:var(--tec-color-button-primary-active)}.tribe-common .tribe-common-c-btn:disabled,.tribe-common a.tribe-common-c-btn:disabled{background-color:var(--tec-color-button-primary-background)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover);color:var(--tec-color-background)}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn{background-color:var(--tec-color-button-primary)}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover);color:var(--tec-color-background)}.tribe-theme-twentytwentyone .tribe-common .tribe-common-c-btn{outline:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-c-btn:not(:hover):not(:active){background-color:var(--tec-color-button-primary);color:var(--tec-color-background)}.tribe-common .tribe-common-c-loader__dot circle{animation-direction:normal;animation-duration:2.24s;animation-iteration-count:infinite;animation-name:a;fill:currentColor;opacity:var(--tec-opacity-background)}.tribe-common .tribe-common-c-loader__dot--first circle{animation-delay:.45s}.tribe-common .tribe-common-c-loader__dot--second circle{animation-delay:1.05s}.tribe-common .tribe-common-c-loader__dot--third circle{animation-delay:1.35s}@keyframes a{50%{opacity:var(--tec-opacity-default)}}.tribe-common .tribe-common-c-svgicon{color:var(--tec-color-accent-primary)}.tribe-common .tribe-common-c-svgicon--featured path{fill:currentColor}.tribe-common .tribe-common-c-svgicon--recurring path{fill:var(--tec-color-icon-active);stroke:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon--close-alt path,.tribe-common .tribe-common-c-svgicon--close path{stroke:var(--tec-color-icon-secondary)}.tribe-common .tribe-common-c-svgicon--messages-not-found path{stroke:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon--messages-not-found .tribe-common-c-svgicon__svg-stroke{stroke:currentColor}.tribe-common .tribe-common-c-svgicon__svg-fill{fill:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon__svg-stroke{stroke:var(--tec-color-icon-active)}
1
+ .tribe-common figure{line-height:0}.tribe-common figcaption{line-height:normal}.tribe-common a{background-color:transparent;-webkit-text-decoration-skip:objects}.tribe-common abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.tribe-common code,.tribe-common kbd,.tribe-common pre,.tribe-common samp{font-family:monospace;font-size:1em}.tribe-common b,.tribe-common strong{font-weight:inherit;font-weight:bolder}.tribe-common dfn{font-style:italic}.tribe-common mark{background-color:#ff0;color:#000}.tribe-common small{font-size:80%}.tribe-common sub,.tribe-common sup{font-size:75%;line-height:0}.tribe-common hr{border:0;height:0}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=email],.tribe-common input[type=password],.tribe-common input[type=reset],.tribe-common input[type=search],.tribe-common input[type=submit],.tribe-common input[type=text],.tribe-common input[type=url],.tribe-common textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none}.tribe-common button,.tribe-common input,.tribe-common optgroup,.tribe-common select,.tribe-common textarea{color:inherit;font:inherit;-webkit-font-smoothing:antialiased;line-height:normal}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{border-radius:0;outline:0}.tribe-common select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.tribe-common optgroup{font-weight:700}.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common p{font-weight:400;text-rendering:optimizeLegibility}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{opacity:1}.tribe-theme-twentynineteen .tribe-common h1:before,.tribe-theme-twentynineteen .tribe-common h2:before{content:none}.tribe-theme-twentynineteen .tribe-common button,.tribe-theme-twentynineteen .tribe-common input[type=button],.tribe-theme-twentynineteen .tribe-common input[type=reset],.tribe-theme-twentynineteen .tribe-common input[type=submit]{outline:none}.tribe-theme-twentynineteen .tribe-common td,.tribe-theme-twentynineteen .tribe-common th{word-break:normal}.tribe-theme-twentyseventeen .tribe-common h5{letter-spacing:normal;text-transform:none}.tribe-theme-twentyseventeen .tribe-common input[type=text]{border-radius:0}.tribe-theme-twentytwenty .tribe-common{background-color:var(--tec-color-background-events);letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common input,.tribe-theme-twentytwenty .tribe-common textarea{letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common *{word-break:normal}.tribe-theme-twentytwentyone.tribe-common .tribe-common .button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-button .wp-block-button__link:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-file a.wp-block-file__button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common .wp-block-search .wp-block-search__button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common button:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common input[type=reset]:not(:hover):not(:active):not(.has-background),.tribe-theme-twentytwentyone.tribe-common .tribe-common input[type=submit]:not(:hover):not(:active):not(.has-background){background-color:transparent;background-color:initial}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{line-height:0}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-form-control-checkbox__label:hover,.tribe-common .tribe-common-form-control-radio__label:hover{opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-default);height:20px;position:relative;width:20px}.tribe-common .tribe-common-form-control-checkbox__input:active,.tribe-common .tribe-common-form-control-checkbox__input:focus,.tribe-common .tribe-common-form-control-checkbox__input:hover,.tribe-common .tribe-common-form-control-radio__input:active,.tribe-common .tribe-common-form-control-radio__input:focus,.tribe-common .tribe-common-form-control-radio__input:hover{border-color:var(--tec-form-color-border-active);opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-checkbox__input:checked,.tribe-common .tribe-common-form-control-radio__input:checked{background-color:var(--tec-form-color-border-active)}.tribe-common .tribe-common-form-control-checkbox__input{border-radius:4px}.tribe-common .tribe-common-form-control-checkbox__input:checked:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='var(--tec-color-background)'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;content:"";display:block;height:9px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}.tribe-common .tribe-common-form-control-checkbox__input:focus+.tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-checkbox__input:hover+.tribe-common-form-control-checkbox__label{opacity:var(--tec-opacity-icon-hover)}.tribe-common .tribe-common-form-control-radio__input{border-radius:50%}.tribe-common .tribe-common-form-control-radio__input:checked:before{background-color:var(--tec-form-color-background);border-radius:50%;content:"";display:block;height:8px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:8px}.tribe-common .tribe-common-form-control-radio__input:focus+.tribe-common-form-control-radio__label,.tribe-common .tribe-common-form-control-radio__input:hover+.tribe-common-form-control-radio__label{opacity:var(--tec-opacity-icon-hover)}#top .main_color .tribe-common .tribe-common-form-control-checkbox__label,#top .main_color .tribe-common .tribe-common-form-control-radio__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label{font-size:var(--tec-font-size-2);font-weight:var(--tec-font-weight-regular)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-checkbox__input:checked:before{margin:0}.tribe-common .tribe-common-form-control-slider{line-height:0}.tribe-common .tribe-common-form-control-slider__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:var(--tec-transition-background-color);background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-slider__input::-moz-range-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:var(--tec-transition-background-color);background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-slider__input::-ms-track{background-color:transparent;border-color:transparent;border-width:5px 0;color:transparent;height:10px}.tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,.tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper{background-color:var(--tec-form-color-accent-primary);border-radius:10px}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px;-webkit-appearance:none;appearance:none}.tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px}.tribe-common .tribe-common-form-control-slider__input::-ms-thumb{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;margin-top:-5px;box-shadow:none;margin-top:-1px}.tribe-common .tribe-common-form-control-slider__label{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);line-height:var(--tec-line-height-0);color:var(--tec-color-text-secondary)}#top .main_color .tribe-common .tribe-common-form-control-slider__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label,.tribe-common .tribe-common-form-control-slider__label{font-size:var(--tec-font-size-1);font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-form-control-text__input{font-size:var(--tec-font-size-3);border:0;border-bottom:1px solid var(--tec-color-border-default)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input,.tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{font-size:var(--tec-font-size-2);border:0}.tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder{color:var(--tec-color-text-secondary);font-style:normal;opacity:var(--tec-opacity-default)}.tribe-common .tribe-common-form-control-text__input::placeholder{color:var(--tec-color-text-secondary);font-style:normal;opacity:var(--tec-opacity-default)}.tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:var(--tec-color-border-active);outline:0}.tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-text__input{line-height:inherit}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);background:var(--tec-color-background);border:0;border-bottom:1px solid var(--tec-color-border-default)}#top .main_color .tribe-common .tribe-common-form-control-text__input:focus,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:var(--tec-color-border-active);box-shadow:none}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);border:0}.tribe-common .tribe-common-form-control-toggle{line-height:0;position:relative}.tribe-common .tribe-common-form-control-toggle__input{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:var(--tec-transition-background-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--tec-form-color-border-secondary);width:40px}.tribe-common .tribe-common-form-control-toggle__input::-ms-check{display:none}.tribe-common .tribe-common-form-control-toggle__input+label:before{background-color:var(--tec-form-color-background);border:1px solid var(--tec-form-color-border-secondary);border-radius:50%;box-shadow:var(--tec-form-box-shadow-default);height:20px;width:20px;content:"";left:0;position:absolute;top:0;transition:var(--tec-transition-transform)}.tribe-common .tribe-common-form-control-toggle__input:checked{background-color:var(--tec-form-color-accent-primary)}.tribe-common .tribe-common-form-control-toggle__input:checked+label:before{transform:translateX(20px)}.tribe-common .tribe-common-form-control-toggle__label{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);line-height:var(--tec-line-height-0);color:var(--tec-color-text-secondary)}#top .main_color .tribe-common .tribe-common-form-control-toggle__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label,.tribe-common .tribe-common-form-control-toggle__label{font-size:var(--tec-font-size-1);font-weight:var(--tec-font-weight-regular)}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-toggle__input{top:0}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-toggle__input:checked:before{content:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-form-control-toggle__input:after{display:none}.tribe-common a,.tribe-common a:active,.tribe-common a:focus,.tribe-common a:hover,.tribe-common a:visited{color:var(--tec-color-text-primary);outline:0;text-decoration:none}.site-footer .widget-area .tribe-common a,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a,.tribe-theme-twentyseventeen .tribe-common a{box-shadow:none}.site-footer .widget-area .tribe-common a:focus,.site-footer .widget-area .tribe-common a:hover,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a:focus,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common a:hover,.tribe-theme-twentyseventeen .tribe-common a:focus,.tribe-theme-twentyseventeen .tribe-common a:hover{box-shadow:none;color:var(--tec-color-text-primary)}.tribe-theme-twentynineteen .entry .tribe-common a,.tribe-theme-twentynineteen .tribe-common a,.tribe-theme-twentytwentyone .entry .tribe-common a,.tribe-theme-twentytwentyone .tribe-common a{text-decoration:none}.main_color .sidebar .tribe-common a,.main_color .sidebar .tribe-common a:active,.main_color .sidebar .tribe-common a:focus,.main_color .sidebar .tribe-common a:hover,.main_color .sidebar .tribe-common a:visited,.tribe-theme-enfold .tribe-common a,.tribe-theme-enfold .tribe-common a:active,.tribe-theme-enfold .tribe-common a:focus,.tribe-theme-enfold .tribe-common a:hover,.tribe-theme-enfold .tribe-common a:visited{color:var(--tec-color-text-primary)}.tribe-common .tribe-common-anchor{border-bottom:2px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-anchor:active,.tribe-common .tribe-common-anchor:focus,.tribe-common .tribe-common-anchor:hover{border-bottom:2px solid currentColor}.tribe-common .tribe-common-anchor-alt{border-bottom:2px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-anchor-alt:active,.tribe-common .tribe-common-anchor-alt:focus,.tribe-common .tribe-common-anchor-alt:hover{border-bottom:2px solid currentColor;color:var(--tec-color-link-accent)}.tribe-common .tribe-common-anchor-thin{border-bottom:1px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-anchor-thin:active,.tribe-common .tribe-common-anchor-thin:focus,.tribe-common .tribe-common-anchor-thin:hover{border-bottom:1px solid var(--tec-color-link-primary)}.tribe-common .tribe-common-anchor-thin-alt{border-bottom:1px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-anchor-thin-alt:active,.tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-common .tribe-common-anchor-thin-alt:hover{border-bottom:1px solid currentColor;color:var(--tec-color-link-accent)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:hover{color:var(--tec-color-accent-primary)}.site-footer .widget-area .tribe-common .tribe-common-anchor,.site-footer .widget-area .tribe-common .tribe-common-anchor-thin,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-thin{transition:var(--tec-transition-border-color)}.site-footer .widget-area .tribe-common .tribe-common-anchor-alt,.site-footer .widget-area .tribe-common .tribe-common-anchor-thin-alt,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-alt,.tribe-theme-twentyseventeen .site-footer .widget-area .tribe-common .tribe-common-anchor-thin-alt{transition:var(--tec-transition-color)}.tribe-common .tribe-common-b1{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);font-weight:var(--tec-font-weight-regular);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-b1--bold{font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-b2{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-1);font-weight:var(--tec-font-weight-regular);line-height:var(--tec-line-height-0)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-b2--bold{font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-b3{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-0);font-weight:var(--tec-font-weight-regular);line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-b3--bold{font-weight:var(--tec-font-weight-bold)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3--min-medium,.tribe-common .tribe-common-cta{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-cta{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-regular);font-weight:var(--tec-font-weight-bold);border-bottom:2px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-cta:active,.tribe-common .tribe-common-cta:focus,.tribe-common .tribe-common-cta:hover{border-bottom:2px solid currentColor}.tribe-common .tribe-common-cta--alt{border-bottom:2px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-cta--alt:active,.tribe-common .tribe-common-cta--alt:focus,.tribe-common .tribe-common-cta--alt:hover{border-bottom:2px solid currentColor;color:var(--tec-color-link-accent)}.tribe-common .tribe-common-cta--thin{border-bottom:1px solid transparent;transition:var(--tec-transition-border-color)}.tribe-common .tribe-common-cta--thin:active,.tribe-common .tribe-common-cta--thin:focus,.tribe-common .tribe-common-cta--thin:hover{border-bottom:1px solid var(--tec-color-link-primary)}.tribe-common .tribe-common-cta--thin-alt{border-bottom:1px solid var(--tec-color-link-accent);color:var(--tec-color-link-primary);transition:var(--tec-transition-color)}.tribe-common .tribe-common-cta--thin-alt:active,.tribe-common .tribe-common-cta--thin-alt:focus,.tribe-common .tribe-common-cta--thin-alt:hover{border-bottom:1px solid currentColor;color:var(--tec-color-link-accent)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:hover{color:var(--tec-color-accent-primary)}.tribe-common .tribe-common-h1{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h1{font-size:var(--tec-font-size-10);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-h2{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h2{font-size:var(--tec-font-size-9);line-height:var(--tec-line-height-0)}.tribe-common .tribe-common-h3{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-6);line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-common .tribe-common-h4{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-5);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-common .tribe-common-h5{font-size:var(--tec-font-size-4)}.tribe-common .tribe-common-h5,.tribe-common .tribe-common-h6{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);line-height:var(--tec-line-height-2)}.tribe-common .tribe-common-h6{font-size:var(--tec-font-size-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h7{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h7,.tribe-common .tribe-common-h8{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold)}.tribe-common .tribe-common-h8{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3--min-medium{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4--min-medium{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h5--min-medium{font-size:var(--tec-font-size-4);line-height:var(--tec-line-height-2)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h7--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-common .tribe-common-h--alt{font-weight:var(--tec-font-weight-regular)}.tribe-theme-avada #main .tribe-common .tribe-common-h1{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h1{font-size:var(--tec-font-size-10);line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common .tribe-common-h2{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h2{font-size:var(--tec-font-size-9);line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common .tribe-common-h3{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-6);line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common .tribe-common-h4{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);font-size:var(--tec-font-size-5);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common .tribe-common-h5{font-size:var(--tec-font-size-4)}.tribe-theme-avada #main .tribe-common .tribe-common-h5,.tribe-theme-avada #main .tribe-common .tribe-common-h6{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold);line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common .tribe-common-h6{font-size:var(--tec-font-size-3)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h7{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h7,.tribe-theme-avada #main .tribe-common .tribe-common-h8{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-weight:var(--tec-font-weight-bold)}.tribe-theme-avada #main .tribe-common .tribe-common-h8{font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3--min-medium{font-size:var(--tec-font-size-8);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4--min-medium{font-size:var(--tec-font-size-7);line-height:var(--tec-line-height-1)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h5--min-medium{font-size:var(--tec-font-size-4);line-height:var(--tec-line-height-2)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6--min-medium{font-size:var(--tec-font-size-3);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h7--min-medium{font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3)}.tribe-theme-avada #main .tribe-common .tribe-common-h--alt{font-weight:var(--tec-font-weight-regular)}.tribe-common button{border:none}.tribe-common button,.tribe-common button:focus,.tribe-common button:hover,.tribe-theme-twentyseventeen .tribe-common button:focus,.tribe-theme-twentyseventeen .tribe-common button:hover{background-color:transparent}.tribe-theme-twentytwenty .tribe-common button{background-color:transparent;text-transform:inherit}.tribe-theme-twentytwenty .tribe-common button:focus,.tribe-theme-twentytwenty .tribe-common button:hover{text-decoration:none}.tribe-theme-twentytwentyone .tribe-common button:not(:hover):not(:active){background-color:inherit;color:inherit}.tribe-theme-enfold .tribe-common th{letter-spacing:0;text-transform:none}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);font-weight:var(--tec-font-weight-bold);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:var(--tec-color-background);border:1px solid var(--tec-color-accent-primary);border-radius:var(--tec-border-radius-default);text-align:center;transition:var(--tec-transition);color:var(--tec-color-button-primary);padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{width:auto}.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{background-color:var(--tec-color-accent-primary);color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:active{opacity:.9}.tribe-common .tribe-common-c-btn-border--secondary,.tribe-common a.tribe-common-c-btn-border--secondary{border-color:var(--tec-color-button-secondary);color:var(--tec-color-button-secondary)}.tribe-common .tribe-common-c-btn-border--secondary:focus,.tribe-common .tribe-common-c-btn-border--secondary:hover,.tribe-common a.tribe-common-c-btn-border--secondary:focus,.tribe-common a.tribe-common-c-btn-border--secondary:hover{background-color:var(--tec-color-button-secondary)}.tribe-common .tribe-common-c-btn-border--secondary:active,.tribe-common a.tribe-common-c-btn-border--secondary:active{opacity:.9}.tribe-common .tribe-common-c-btn-border--alt,.tribe-common a.tribe-common-c-btn-border--alt{border-color:var(--tec-color-border-secondary);color:var(--tec-color-text-primary);font-weight:var(--tec-font-weight-regular)}.tribe-common .tribe-common-c-btn-border--alt:focus,.tribe-common .tribe-common-c-btn-border--alt:hover,.tribe-common a.tribe-common-c-btn-border--alt:focus,.tribe-common a.tribe-common-c-btn-border--alt:hover{background-color:var(--tec-color-background);border-color:var(--tec-color-border-active);color:var(--tec-color-text-primary)}.tribe-common .tribe-common-c-btn-border--alt:active,.tribe-common a.tribe-common-c-btn-border--alt:active{opacity:.9}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:hover{background-color:var(--tec-color-button-primary)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--secondary:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--secondary:hover{background-color:var(--tec-color-button-secondary)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border--alt:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-1);line-height:var(--tec-line-height-0);font-weight:var(--tec-font-weight-regular);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:var(--tec-color-background);border:1px solid var(--tec-color-border-default);border-radius:var(--tec-border-radius-default);text-align:center;transition:var(--tec-transition-color-border-color)}.tribe-common .tribe-common-c-btn-border-small:focus,.tribe-common .tribe-common-c-btn-border-small:hover,.tribe-common a.tribe-common-c-btn-border-small:focus,.tribe-common a.tribe-common-c-btn-border-small:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-border-small:active,.tribe-common a.tribe-common-c-btn-border-small:active{border-color:var(--tec-color-border-active)}.tribe-common .tribe-common-c-btn-border-small,.tribe-common a.tribe-common-c-btn-border-small{color:var(--tec-color-text-secondary);padding:14px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border-small,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border-small{padding:6px 15px;width:auto}.tribe-common .tribe-common-c-btn-border-small:active,.tribe-common .tribe-common-c-btn-border-small:focus,.tribe-common .tribe-common-c-btn-border-small:hover,.tribe-common a.tribe-common-c-btn-border-small:active,.tribe-common a.tribe-common-c-btn-border-small:focus,.tribe-common a.tribe-common-c-btn-border-small:hover{color:var(--tec-color-text-primary)}.tribe-common .tribe-common-c-btn-border-small:disabled,.tribe-common a.tribe-common-c-btn-border-small:disabled{color:var(--tec-color-text-disabled)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border-small:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-icon{border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto}.tribe-common .tribe-common-c-btn-icon--caret-left:active .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-left:focus .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-left:hover .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:active .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:focus .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:hover .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-primary)}.tribe-common .tribe-common-c-btn-icon--caret-left:disabled .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right:disabled .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-disabled)}.tribe-common .tribe-common-c-btn-icon--caret-left .tribe-common-c-btn-icon__icon-svg path,.tribe-common .tribe-common-c-btn-icon--caret-right .tribe-common-c-btn-icon__icon-svg path{fill:var(--tec-color-icon-secondary)}.tribe-common .tribe-common-c-btn-icon--border{align-items:center;background-color:var(--tec-color-background);border:1px solid var(--tec-color-border-default);display:inline-flex;height:56px;justify-content:center;transition:none;width:56px}.tribe-common .tribe-common-c-btn-icon--border:focus,.tribe-common .tribe-common-c-btn-icon--border:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn-icon--border:active{border-color:var(--tec-color-border-active)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-icon--border:hover{background-color:var(--tec-color-background)}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{color:var(--tec-color-text-primary);font-family:var(--tec-font-family-sans-serif);font-size:var(--tec-font-size-2);line-height:var(--tec-line-height-3);font-weight:var(--tec-font-weight-regular);font-weight:var(--tec-font-weight-bold);border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;border-radius:var(--tec-border-radius-default);color:var(--tec-color-background);text-align:center;transition:var(--tec-transition-background-color);background-color:var(--tec-color-button-primary);padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-btn:focus,.tribe-common .tribe-common-c-btn:hover,.tribe-common a.tribe-common-c-btn:focus,.tribe-common a.tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover)}.tribe-common .tribe-common-c-btn:active,.tribe-common a.tribe-common-c-btn:active{background-color:var(--tec-color-button-primary-active)}.tribe-common .tribe-common-c-btn:disabled,.tribe-common a.tribe-common-c-btn:disabled{background-color:var(--tec-color-button-primary-background)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover);color:var(--tec-color-background)}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn{background-color:var(--tec-color-button-primary)}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:hover{background-color:var(--tec-color-button-primary-hover);color:var(--tec-color-background)}.tribe-theme-twentytwentyone .tribe-common .tribe-common-c-btn{outline:none}.tribe-theme-twentytwentyone .tribe-common .tribe-common-c-btn:not(:hover):not(:active){background-color:var(--tec-color-button-primary);color:var(--tec-color-background)}.tribe-common .tribe-common-c-loader__dot circle{animation-direction:normal;animation-duration:2.24s;animation-iteration-count:infinite;animation-name:a;fill:currentColor;opacity:var(--tec-opacity-background)}.tribe-common .tribe-common-c-loader__dot--first circle{animation-delay:.45s}.tribe-common .tribe-common-c-loader__dot--second circle{animation-delay:1.05s}.tribe-common .tribe-common-c-loader__dot--third circle{animation-delay:1.35s}@keyframes a{50%{opacity:var(--tec-opacity-default)}}.tribe-common .tribe-common-c-svgicon{color:var(--tec-color-accent-primary)}.tribe-common .tribe-common-c-svgicon--featured path{fill:currentColor}.tribe-common .tribe-common-c-svgicon--recurring path{fill:var(--tec-color-icon-active);stroke:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon--close-alt path,.tribe-common .tribe-common-c-svgicon--close path{stroke:var(--tec-color-icon-secondary)}.tribe-common .tribe-common-c-svgicon--messages-not-found path{stroke:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon--messages-not-found .tribe-common-c-svgicon__svg-stroke{stroke:currentColor}.tribe-common .tribe-common-c-svgicon__svg-fill{fill:var(--tec-color-icon-active)}.tribe-common .tribe-common-c-svgicon__svg-stroke{stroke:var(--tec-color-icon-active)}
common/src/resources/css/dialog.min.css CHANGED
@@ -1 +1 @@
1
- .tribe-common .tribe-dialog{--tribe-dialog-background-color:#fff;--tribe-dialog-close-background:#fff;--tribe-dialog-close-border-color:#bababa;--tribe-dialog-close-border-width:1px;--tribe-dialog-close-color:#bababa;--tribe-dialog-close-height:12px;--tribe-dialog-close-height-desktop:16px;--tribe-dialog-overlay-color:transparent;--tribe-modal-overlay-color:rgba(20,24,39,.9);--tribe-dialog-border-radius:4px;--tribe-dialog-padding:16px;--tribe-dialog-padding-top:24px;--tribe-dialog-padding-side:28px}.tribe-common div.tribe-dialog{align-items:center;display:flex;height:100vh;justify-content:center;left:0;position:fixed;top:0;width:100vw;z-index:100}.tribe-common div.tribe-dialog[aria-hidden=true]{display:none}.tribe-common .tribe-dialog__overlay{background-color:var(--tribe-dialog-overlay-color);height:100vh;left:0;opacity:.9;position:fixed;top:0;width:100vw;z-index:100}.tribe-common .tribe-dialog__wrapper{background-color:var(--tribe-dialog-background-color);border-radius:var(--tribe-dialog-border-radius);box-shadow:0 2px 54px 0 var(--tribe-modal-overlay-color);max-height:100vh;max-width:100vw;overflow-y:auto;padding:var(--tribe-dialog-padding);-webkit-perspective:1000;-webkit-transform:translateZ(0);width:800px;z-index:200}.tribe-common .tribe-dialog__wrapper div[role=document]{align-items:flex-end;display:flex;flex-flow:column;justify-content:space-between;position:relative}.tribe-common .tribe-dialog__close-button{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%23bababa' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;cursor:pointer;display:inline-block;font-size:14px;height:var(--tribe-dialog-close-height);line-height:var(--tribe-dialog-close-height);padding:0;position:absolute;width:var(--tribe-dialog-close-height);z-index:1}.tribe-common .tribe-dialog__close-button:focus,.tribe-common .tribe-dialog__close-button:hover{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%235d5d5d' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-size:contain;outline:none}.tribe-common .tribe-dialog__close-button--hidden{display:none}.tribe-common .tribe-dialog__close-button--round{border-radius:50%}.tribe-common .tribe-dialog__close-button--border{border:var(--tribe-dialog-close-border-width) solid var(--tribe-dialog-close-border-color)}.tribe-common h2.tribe-dialog__title{align-self:flex-start;margin:0 0 22px;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:0}.tribe-common .tribe-dialog__content{color:#141827;font-size:14px;line-height:1.64em;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:calc(var(--tribe-dialog-close-height) + .5em);width:100%}.tribe-common .tribe-dialog__title+.tribe-dialog__content{padding:0}.tribe-common .tribe-dialog__content p{font-size:var(--font-size-2)}.tribe-common .tribe-modal__overlay{background-color:var(--tribe-modal-overlay-color)}.tribe-common .tribe-confirm__content{padding-right:0}.tribe-common .tribe-dialog__button_wrap{display:flex;flex-flow:row wrap;justify-content:flex-end;margin-top:1rem}.tribe-common .tribe-dialog__button-cancel,.tribe-common .tribe-dialog__button-continue{margin-left:var(--spacer-1);width:auto}#top .main_color .tribe-common div.tribe-dialog,#top.tribe-theme-enfold .tribe-common div.tribe-dialog,.tribe-theme-avada .tribe-common div.tribe-dialog,.tribe-theme-divi .tribe-common div.tribe-dialog{z-index:99999}@media screen and (min-width:768px){.tribe-common .tribe-dialog__wrapper{max-height:calc(100vh - 160px);padding:var(--tribe-dialog-padding-top) var(--tribe-dialog-padding-side)}.tribe-common .tribe-dialog__close-button{height:var(--tribe-dialog-close-height-desktop);line-height:var(--tribe-dialog-close-height-desktop);width:var(--tribe-dialog-close-height-desktop)}}@media screen and (max-width:768px){.tribe-common .tribe-dialog__content:last-of-type{padding-bottom:36px}}
1
+ .tribe-common .tribe-dialog{--tribe-dialog-background-color:#fff;--tribe-dialog-close-background:#fff;--tribe-dialog-close-border-color:#bababa;--tribe-dialog-close-border-width:1px;--tribe-dialog-close-color:#bababa;--tribe-dialog-close-height:12px;--tribe-dialog-close-height-desktop:16px;--tribe-dialog-overlay-color:transparent;--tribe-modal-overlay-color:rgba(20,24,39,.9);--tribe-dialog-border-radius:4px;--tribe-dialog-padding:16px;--tribe-dialog-padding-top:24px;--tribe-dialog-padding-side:28px}.tribe-common div.tribe-dialog{align-items:center;display:flex;height:100vh;justify-content:center;left:0;position:fixed;top:0;width:100vw;z-index:100}.tribe-common div.tribe-dialog[aria-hidden=true]{display:none}.tribe-common .tribe-dialog__overlay{background-color:var(--tribe-dialog-overlay-color);height:100vh;left:0;opacity:.9;position:fixed;top:0;width:100vw;z-index:100}.tribe-common .tribe-dialog__wrapper{background-color:var(--tribe-dialog-background-color);border-radius:var(--tribe-dialog-border-radius);box-shadow:0 2px 54px 0 var(--tribe-modal-overlay-color);max-height:100vh;max-width:100vw;overflow-y:auto;padding:var(--tribe-dialog-padding);-webkit-perspective:1000;-webkit-transform:translateZ(0);width:800px;z-index:200}.tribe-common .tribe-dialog__wrapper div[role=document]{align-items:flex-end;display:flex;flex-flow:column;justify-content:space-between;position:relative}.tribe-common .tribe-dialog__close-button{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='var(--tec-color-icon-secondary)' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;cursor:pointer;display:inline-block;font-size:14px;height:var(--tribe-dialog-close-height);line-height:var(--tribe-dialog-close-height);padding:0;position:absolute;width:var(--tribe-dialog-close-height);z-index:1}.tribe-common .tribe-dialog__close-button:focus,.tribe-common .tribe-dialog__close-button:hover{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='var(--tec-color-icon-primary)' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-size:contain;outline:none}.tribe-common .tribe-dialog__close-button--hidden{display:none}.tribe-common .tribe-dialog__close-button--round{border-radius:50%}.tribe-common .tribe-dialog__close-button--border{border:var(--tribe-dialog-close-border-width) solid var(--tribe-dialog-close-border-color)}.tribe-common h2.tribe-dialog__title{align-self:flex-start;margin:0 0 22px;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:0}.tribe-common .tribe-dialog__content{color:#141827;font-size:14px;line-height:1.64em;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:calc(var(--tribe-dialog-close-height) + .5em);width:100%}.tribe-common .tribe-dialog__title+.tribe-dialog__content{padding:0}.tribe-common .tribe-dialog__content p{font-size:var(--font-size-2)}.tribe-common .tribe-modal__overlay{background-color:var(--tribe-modal-overlay-color)}.tribe-common .tribe-confirm__content{padding-right:0}.tribe-common .tribe-dialog__button_wrap{display:flex;flex-flow:row wrap;justify-content:flex-end;margin-top:1rem}.tribe-common .tribe-dialog__button-cancel,.tribe-common .tribe-dialog__button-continue{margin-left:var(--spacer-1);width:auto}#top .main_color .tribe-common div.tribe-dialog,#top.tribe-theme-enfold .tribe-common div.tribe-dialog,.tribe-theme-avada .tribe-common div.tribe-dialog,.tribe-theme-divi .tribe-common div.tribe-dialog{z-index:99999}@media screen and (min-width:768px){.tribe-common .tribe-dialog__wrapper{max-height:calc(100vh - 160px);padding:var(--tribe-dialog-padding-top) var(--tribe-dialog-padding-side)}.tribe-common .tribe-dialog__close-button{height:var(--tribe-dialog-close-height-desktop);line-height:var(--tribe-dialog-close-height-desktop);width:var(--tribe-dialog-close-height-desktop)}}@media screen and (max-width:768px){.tribe-common .tribe-dialog__content:last-of-type{padding-bottom:36px}}
common/src/resources/css/onboarding.min.css DELETED
@@ -1 +0,0 @@
1
- .introjs-tooltipbuttons{border-top:none}.introjs-bullets ul li a.active{background-color:var(--tec-color-accent-primary)}.introjs-bullets ul li:only-child{display:none}.introjs-hint-pulse{background-color:transparent}.introjs-hint-dot,.introjs-hint-pulse,.introjs-hint:hover>.introjs-hint-pulse{border-color:var(--tec-color-accent-primary)}.introjs-hintReference .tribe-onboarding__tooltip .introjs-tooltiptext p{font-size:14px;margin-top:0}.introjs-hint:focus{box-shadow:none}.introjs-tooltipReferenceLayer:not(.introjs-hintReference) .tribe-onboarding__tooltip{box-sizing:border-box;max-width:450px;min-width:430px}.tribe-onboarding__tooltip .introjs-button{border:0;text-shadow:none}.tribe-onboarding__tooltip .introjs-button:focus{box-shadow:none}.tribe-onboarding__tooltip .introjs-prevbutton{color:var(--tec-color-icon-disabled)}.tribe-onboarding__tooltip .introjs-prevbutton,.tribe-onboarding__tooltip .introjs-prevbutton:hover{background-color:transparent;border-color:transparent}.tribe-onboarding__tooltip .introjs-nextbutton{background-color:#f7f6f6}.tribe-onboarding__tooltip .introjs-donebutton{background-color:var(--tec-color-accent-primary);color:var(--tec-color-background)}.introjs-tooltipReferenceLayer:not(.introjs-hintReference) .tribe-onboarding__tooltip--large{max-width:100%;min-width:630px}.tribe-onboarding__tooltip--squared{border-radius:1px}.tribe-onboarding__tooltip--rounded{border-radius:5px}.tribe-onboarding__tooltip--dark *,.tribe-onboarding__tooltip--dark h1{color:var(--tec-color-background)}.tribe-onboarding__tooltip--no-bullets .introjs-bullets{display:none}.tribe-onboarding__tooltip--content-centered .introjs-tooltip-title{float:none}.tribe-onboarding__tooltip--content-centered .introjs-tooltip-title,.tribe-onboarding__tooltip--content-centered .introjs-tooltiptext{text-align:center}.tribe-onboarding__tooltip--title-large .introjs-tooltip-title{font-size:20px}.tribe-onboarding__tooltip--button-centered .introjs-tooltipbuttons,.tribe-onboarding__tooltip-only-step--button-centered .introjs-tooltipbuttons{text-align:center}.tribe-onboarding__tooltip--button-centered .introjs-nextbutton,.tribe-onboarding__tooltip-only-step--button-centered .introjs-nextbutton{float:none}.tribe-onboarding__tooltip--button-large .introjs-button{font-size:16px;padding:14px 28px}.tribe-onboarding__tooltip--button-rounded .introjs-button{border-radius:28px}.tribe-onboarding__tooltip--button-dark-skin .introjs-button{background-color:var(--tec-color-background);color:var(--tec-color-text-primary)}
 
common/src/resources/css/tribe-common-admin.min.css CHANGED
@@ -1 +1 @@
1
- .invalid input,input:out-of-range{border:2px solid red!important}.valid input{border:1px solid green}.clearfix{zoom:1}.placeholder{color:#999;cursor:text;padding:4px}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::placeholder,textarea::placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.bubble{background-color:#f9f9f9;border:1px solid #dfdfdf;border-radius:3px;border-spacing:0;padding:10px}.tribe-sticky-tooltip{color:#bbb}td.tribe_message{padding-bottom:10px!important}#tribe_thanks{float:left;margin:5px 0 0;width:200px}.tribe_brand{font-family:Georgia,serif!important;font-size:17px!important;font-weight:400;margin:8px 0}.tribe-rating{color:#3d54ff}.tribe-rating:hover{color:#1c39bb}#tribe-upgrade{background:#f6f6f6;border:1px solid #ccc;border-radius:5px;margin:20px 0 30px;padding:0 20px 20px}#tribe-upgrade .message{background-color:#ffffe0;border:1px solid #e6db55;border-radius:3px;padding:6px 12px}table.plugins .tribe-plugin-update-message{background:#d54e21;color:#fff;display:inline-table;margin:6px 0;padding:10px 12px}table.plugins .tribe-plugin-update-message h4{display:inline;font-weight:700;margin-right:8px}table.plugins .tribe-plugin-update-message h4:after{content:" \00BB "}table.plugins .tribe-plugin-update-message a{color:#fff;text-decoration:underline}.tribe-settings-form{max-width:1000px}.tribe-settings-form fieldset{clear:both;display:inline-block;padding:10px 0}.tribe-settings-form fieldset.tribe-field-license_key legend{width:auto}.tribe-settings-form legend{float:left;font-weight:700;margin-right:20px;width:220px}.tribe-settings-form .tribe-field-wrap{float:left;max-width:500px}.tribe-settings-form .tribe-field-wrap :first-child{margin-top:0}.tribe-settings-form .tribe-field-checkbox_list label,.tribe-settings-form .tribe-field-radio label{display:block;margin:5px 0 5px 20px;text-indent:-20px}.tribe-settings-form .tribe-field-checkbox_list label>p,.tribe-settings-form .tribe-field-radio label>p{margin-left:1px;text-indent:0}.tribe-settings-form .tribe-field-checkbox_list label input,.tribe-settings-form .tribe-field-radio label input{margin-right:5px}.tribe-settings-form .tribe-settings-form-wrap .description,.tribe-settings-form .tribe-settings-form-wrap fieldset,.tribe-settings-form fieldset[id^=tribe-field-geoloc_]{padding-left:12px}.tribe-settings-form .tribe-settings-form-wrap fieldset .description{margin-left:0;max-width:450px;padding-left:0}.tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection{margin-bottom:18px}.tribe-settings-form .tribe-settings-form-wrap #tribe-field-stylesheetOption .description{color:#999;margin-left:1px}.tribe-settings-form .tribe-settings-form-wrap h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}.tribe-settings-form .tribe-settings-form-wrap .contained,.tribe-settings-form .tribe-settings-form-wrap .system-info,.tribe-settings-form .tribe-settings-form-wrap .tribe-sysinfo-optin-msg,.tribe-settings-form .tribe-settings-form-wrap h3+p{margin:0 0 10px;padding-left:12px}.tribe_settings .tribe-field-indent{margin-left:245px}.tribe_settings #pu_dashboard_message{display:none}.tribe_settings .tribe-errors-list{margin-left:15px}.tribe_settings .expiring-license{color:red}.tribe_settings .tribe-error{border:1px solid red}.tribe_settings .tribe-field-description{margin-bottom:0;position:relative;top:-12px}.tribe_settings #ical-link{top:-14px}#modern-tribe-info{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:8px 20px 12px}#modern-tribe-info img{margin:10px 0}#modern-tribe-info ul{list-style:disc;margin-left:20px}#modern-tribe-info ul ul{list-style:circle}.tribe-field-inline-dropdown{margin-left:0;margin-right:0}.tribe-field-inline-text{line-height:28px;margin:0 2px}.tribe-field-textarea.tribe-size-small textarea{height:60px;width:180px}.tribe-field-textarea.tribe-size-medium textarea{height:80px;width:300px}.tribe-field-textarea.tribe-size-large textarea{height:120px;width:450px}.tribe-field-email.tribe-size-small input,.tribe-field-license_key.tribe-size-small input,.tribe-field-text.tribe-size-small input{width:50px}.tribe-field-email.tribe-size-medium input,.tribe-field-license_key.tribe-size-medium input,.tribe-field-text.tribe-size-medium input{width:225px}.tribe-field-email.tribe-size-large input,.tribe-field-license_key.tribe-size-large input,.tribe-field-text.tribe-size-large input{width:450px}.tribe-field-dropdown.tribe-size-small select{width:100px}.tribe-field-dropdown.tribe-size-medium select{width:300px}.tribe-field-dropdown.tribe-size-large select{width:450px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap{max-width:600px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap .description{max-width:100%}.tribe-field-dropdown_chosen.tribe-size-small select{width:100px}.tribe-field-dropdown_chosen.tribe-size-medium select{width:200px}.tribe-field-dropdown_chosen.tribe-size-large select{width:300px}.tribe-field-wrap .tooltip:first-child{font-style:normal}.tribe-field.indent{margin-left:252px;width:75%}.tribe-field.indent legend{font-weight:400;width:auto}.tribe-field.indent .tribe-field-wrap{padding-right:12px}.tribe-field.indent.tribe-field-radio .tribe-field-wrap{clear:left;margin-top:12px}.tribe-field.light-bordered{background-color:#fff;border:1px solid #d3d3d3}.ajax-loading-license,.invalid-key,.valid-key{display:none;margin:0 5px}.ajax-loading-license{position:relative;top:5px}.key-validity{display:inline-block}.invalid-key,.optin-fail{color:red}.optin-success,.valid-key{color:green}.valid-key.service-msg{color:#b72}#additional-field-table{margin-bottom:20px}.tribe-admin-box-left{float:left;width:20%}.tribe-admin-box-left,.tribe-admin-box-right{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:0 20px 15px}.tribe-admin-box-right{float:right;width:68%}.ajax-loader{float:right;margin:10px}.tribe-arrangeable-item{border:1px solid #d3d3d3;border-radius:3px}.tribe-arrangeable-item .ui-state-default{border:none}.tribe-arrangeable-item-top{padding:6px}.tribe-arrangeable-item-top:hover{cursor:move}.tribe-arrangeable-action{float:right}.tribe-arrangeable-child{background-color:#f9f9f9;border-top:1px solid #d3d3d3;display:none;padding:25px}.tribe-arrangeable-child label{display:block;margin:0 0 7px}.tribe_events_active_filter_type_options{margin:10px 0}.tribe_events_active_filter_type_options label{margin:7px 0}#event_organizer td small,.OrganizerInfo td small{display:block;margin:0;max-width:250px}#event_organizer .organizer-email,.OrganizerInfo .organizer-email{vertical-align:top}.tribe-table-field-label{max-width:100%;width:200px}#tribe-help-general,#tribe-help-sidebar{float:left;margin-top:20px}#tribe-help-general p{margin-left:15px}#tribe-help-general ul{list-style-type:square}#tribe-help-general ol,#tribe-help-general ul{margin-bottom:20px;margin-left:35px}#tribe-help-general h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}#tribe-help-general h3~h3{margin-top:2.25em}#tribe-help-general h3+p{margin:0 0 20px;padding-left:12px}#tribe-help-general{width:65%}.tribe-help-section{padding-bottom:10px}.tribe-section-type-box{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;padding:8px 20px 12px}.tribe-section-type-box img{height:auto;margin:10px 0;max-width:300px}.tribe-section-type-box ul{list-style:disc;margin-left:20px}.tribe-section-type-box ul ul{list-style:circle}#tribe-log-controls{padding-bottom:1rem;padding-left:12px}#tribe-log-controls>div{display:inline-block;padding-right:1rem}#tribe-log-controls .working{opacity:1;transition:opacity .2s}#tribe-log-controls .working.hidden{opacity:0;transition:opacity .2s}#tribe-log-viewer,#tribe-system-info dl.support-stats,.template-updates-wrapper{background:#000;border-radius:2px;color:#888;max-height:400px;overflow:scroll;padding:10px}#tribe-system-info dl.support-stats dt,.template-updates-wrapper dt{clear:both;float:left;font-weight:700;text-transform:uppercase;width:25%}#tribe-system-info dl.support-stats dd,.template-updates-wrapper dd{margin-left:25%;padding-left:10px}.system-info-copy .system-info-copy-btn{padding:6px}.system-info-copy .system-info-copy-btn .dashicons{padding-right:10px}.template-updates-wrapper p{margin-top:0}#tribe-help-sidebar{margin:20px 0 0 3%;max-width:225px;width:32%}.tribe-help-plugin-info{border:1px solid #ccc;padding:0 12px 12px}.tribe-help-plugin-info dd,.tribe-help-plugin-info dt{display:inline;margin:0}.tribe-help-plugin-info dt{font-weight:700}.tribe-help-plugin-info dd:after{content:"";display:block;height:.4em}.tribe-help-plugin-info dd:last-child:after{height:0}.tribe-help-plugin-info+.tribe-help-plugin-info{margin-top:20px}.tribe-help-plugin-info>div{line-height:2em}.tribe-help-plugin-info .star-rating{display:inline-block;margin-left:3px;position:relative;top:-2px}.tribe-help-plugin-info .tribe-list-addons{color:#21a6cb;font-size:24px;list-style:circle inside;margin-bottom:10px;margin-top:10px;padding-left:4px}.tribe-help-plugin-info .tribe-list-addons a{font-size:13px;left:-5px;position:relative;top:-5px}.tribe-help-plugin-info .tribe-list-addons .tribe-active-addon{list-style:disc inside}.ui-widget-overlay{background:#666;filter:alpha(opacity=50);opacity:.5}.ui-widget-shadow{background:#000;border-radius:5px;filter:alpha(opacity=20);margin:-5px 0 0 -5px;opacity:.2;padding:5px}.ui-resizable{position:relative}.ui-resizable-handle{display:block;font-size:.1px;position:absolute;z-index:99999}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;left:0;top:-5px;width:100%}.ui-resizable-s{bottom:-5px;cursor:s-resize;height:7px;left:0;width:100%}.ui-resizable-e{cursor:e-resize;height:100%;right:-5px;top:0;width:7px}.ui-resizable-w{cursor:w-resize;height:100%;left:-5px;top:0;width:7px}.ui-resizable-se{bottom:1px;cursor:se-resize;height:12px;right:1px;width:12px}.ui-resizable-sw{bottom:-5px;cursor:sw-resize;height:9px;left:-5px;width:9px}.ui-resizable-nw{cursor:nw-resize;height:9px;left:-5px;top:-5px;width:9px}.ui-resizable-ne{cursor:ne-resize;height:9px;right:-5px;top:-5px;width:9px}.ui-dialog{padding:.2em;position:relative;width:375px}.ui-dialog .ui-dialog-titlebar{padding:.5em .3em .3em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0 .2em}.ui-dialog .ui-dialog-titlebar-close{height:18px;margin:-10px 0 0;padding:1px;position:absolute;right:.3em;top:50%;width:19px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin-left:-8px;margin-top:-8px}.ui-dialog .ui-dialog-titlebar-close:focus,.ui-dialog .ui-dialog-titlebar-close:hover{padding:0}.ui-dialog .ui-dialog-content{background:none;border:0;overflow:auto;padding:.5em 1em;zoom:1}.ui-dialog .ui-dialog-buttonpane{background-image:none;border-width:1px 0 0;margin:.5em 0 0;padding:.3em 1em .5em!important;text-align:right}.ui-dialog .ui-dialog-buttonpane button{cursor:pointer;line-height:1.4em;margin:.5em .4em!important;overflow:visible;padding:.2em .6em .3em;text-shadow:none;width:auto}.ui-dialog .ui-resizable-se{bottom:3px;height:14px;right:3px;width:14px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:none!important;text-align:center}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button .ui-button-text{display:block;line-height:1.4}#ui-datepicker-div{display:none}#tribe-loading{background:#fff;background:hsla(0,0%,100%,.8);display:none;height:100%;left:0;position:absolute;top:0;transition:all 1s linear;width:100%;z-index:4}#tribe-loading span{background:url(../images/tribe-loading.gif) 0 0 no-repeat;background-size:32px 32px;height:32px;left:50%;margin:-16px 0 0 -16px;position:absolute;top:50%;width:32px}.tribe_update_page{max-width:850px}.tribe-half-column{float:left;margin-bottom:30px;margin-right:5%;width:45%}.tribe-row:after,.tribe-row:before{content:"";display:table}.tribe-row,.tribe-row:after{clear:both}.tribe-row .tribe-half-column:last-child{margin-right:0;width:50%}.tribe_update_page h2{font-size:30px;line-height:1.2;margin-bottom:20px}.tribe_update_page h3{font-size:24px;font-weight:400;line-height:24px;margin-top:0}.tribe_update_page h4{font-size:18px;font-weight:600;line-height:18px;margin:0}.tribe_update_page p{font-size:15px}p.tribe-update-message{font-size:18px;font-weight:400}.tribe_update_page h4:before{content:"\f145";font-family:dashicons;font-size:34px;line-height:1;margin-right:5px;position:relative;top:5px}a.tribe-rating-link{text-decoration:none}.tribe-update-links{margin-top:30px}.tribe_update_page li:before{content:"\2022";padding-right:3px}.tribe_update_page .rss-widget{margin:1em 0}.tribe_update_page a.rsswidget{font-size:14px;font-weight:400;line-height:1}.tribe_update_page .rss-widget li:before{display:none}.tribe-events-widget-admin-form__input-section p{margin:0}.tribe-events-widget-admin-form__input-section h4{margin:.5em 0}.tribe-update-bar{display:inline-block}.tribe-update-bar .progress{border:1px solid #ccc;float:left;margin-right:1rem;padding:1px;width:18rem}.tribe-update-bar .progress .bar{background:#7ad03a;height:1rem;width:1%}#tribe-dialog-wrapper>div{padding:1rem}#tribe-dialog-wrapper>div .stage{display:none}#tribe-dialog-wrapper #heading{background:#fff}#tribe-dialog-wrapper label{display:block}#tribe-dialog-wrapper .select-single-container{border:1px solid #888;height:300px;overflow-y:scroll}#tribe-dialog-wrapper .select-single-container label{opacity:1;padding:3px 5px;transition:opacity .2s}#tribe-dialog-wrapper .select-single-container label:nth-child(odd){background:#fff}#tribe-dialog-wrapper .select-single-container label.selected{background:#0073aa;color:#fff;font-weight:700}#tribe-dialog-wrapper .select-single-container label input{display:none}#tribe-dialog-wrapper .select-single-container.updating label{opacity:.35;transition:opacity .2s}.ui-front{z-index:1000000}.wp-list-table.plugins .column-description .update-message{color:#d54e21}.api-check{min-height:100px;padding:1em}.api-check+.notice-dismiss:hover:before{color:#fff}.api-check:after,.api-check:before{content:"";display:table}.api-check:after{clear:both}.api-check .tribe-mascot{bottom:0;display:none;padding:0 1rem 0 0;position:absolute;right:0;top:0}.api-check .tribe-mascot img{display:inline-block;height:100%;max-height:150px;max-width:150px;vertical-align:middle;width:auto}.api-check p{line-height:1.7;margin-bottom:1em}.api-check a{text-decoration:none}.api-check a:hover{text-decoration:underline}.api-check .plugin-list{display:inline;font-weight:600;margin:0;padding:0}.api-check .plugin-list span.plugin-invalid:after{content:", "}.api-check .plugin-list span.plugin-invalid:last-of-type:after{content:""}.tribe-marketing-notice{padding:1em}.tribe-marketing-notice+.notice-dismiss:hover:before{color:#fff}.tribe-marketing-notice:after,.tribe-marketing-notice:before{content:"";display:table}.tribe-marketing-notice:after{clear:both}.tribe-marketing-notice .tribe-marketing-notice__icon{display:none;flex-shrink:0;padding:0;position:static}.tribe-marketing-notice .tribe-marketing-notice__icon img{display:inline-block;max-height:100%;max-width:none;vertical-align:middle;width:100%}.tribe-marketing-notice h3{margin-bottom:.5em;margin-top:.5em}.tribe-marketing-notice p{line-height:1.7;margin-bottom:.5em}.tribe-marketing-notice a{text-decoration:none}.tribe-marketing-notice a:hover{text-decoration:underline}#wpcontent .notice-tribe-banner{align-items:center;background:#161b7d;border:0;box-shadow:none;display:flex;justify-content:flex-start;margin:0 0 16px;padding-right:0}.notice-tribe-banner .tribe-marketing-notice__icon{width:47px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:0;padding:1em 0}.notice-tribe-banner h3{color:#fff;display:block;font-size:.875rem;line-height:1.25;margin:0 0 .25rem}.notice-tribe-banner a{border-bottom:1px solid #fff;line-height:1.25;margin:0;text-decoration:none}.notice-tribe-banner a:hover{text-decoration:none}.notice-tribe-banner a,.notice-tribe-banner p{color:#fff;display:inline-block;font-size:.875rem;line-height:1.25}.notice-tribe-banner p{display:inline-block;margin:0;padding:0}.notice-tribe-banner .tribe-marketing-notice{align-items:center;display:flex;justify-content:flex-start;margin:0 auto;min-height:65px;padding:0 .75rem;width:100%}.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe-welcome .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:100%}.notice-tribe-banner .notice-dismiss{position:static}.notice-tribe-banner .notice-dismiss:before{color:#eaf1ff}.tribe-dropdown,.tribe-ea-dropdown{max-width:100%;width:auto}.tribe-dropdown.select2-container .selection,.tribe-ea-dropdown.select2-container .selection{margin-top:inherit}.tribe-dropdown .select2-selection--single,.tribe-ea-dropdown .select2-selection--single{height:32px}.tribe-dropdown .select2-selection--single .select2-selection__clear,.tribe-ea-dropdown .select2-selection--single .select2-selection__clear{line-height:28px}.tribe-dropdown .select2-selection--single .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--single .select2-selection__rendered{line-height:32px;padding-right:28px}.tribe-dropdown.select2-container--focus .select2-selection--single,.tribe-ea-dropdown.select2-container--focus .select2-selection--single{border-color:#5897fb;box-shadow:0 0 5px rgba(0,0,0,.1)}.tribe-dropdown.select2-container--open .select2-search__field,.tribe-ea-dropdown.select2-container--open .select2-search__field{padding:0}.tribe-dropdown.select2-container--open .select2-dropdown--below,.tribe-ea-dropdown.select2-container--open .select2-dropdown--below{border-top:1px solid #aaa;margin-top:-1px}.tribe-dropdown.select2-container--open .select2-dropdown--above,.tribe-ea-dropdown.select2-container--open .select2-dropdown--above{border-bottom:1px solid #aaa;margin-bottom:-16px}.tribe-dropdown.select2-container--open .select2-selection--single,.tribe-ea-dropdown.select2-container--open .select2-selection--single{border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:#aaa}.tribe-dropdown.select2-container--open .select2-selection__arrow b,.tribe-ea-dropdown.select2-container--open .select2-selection__arrow b{transform:rotate(180deg)}.tribe-dropdown.select2-selection--single,.tribe-ea-dropdown.select2-selection--single{background-image:none;border:1px solid #ccc;border-radius:3px;overflow:hidden}.tribe-dropdown.select2-selection--single>.select2-selection__rendered,.tribe-ea-dropdown.select2-selection--single>.select2-selection__rendered{white-space:normal}.tribe-dropdown.select2-selection--single .select2-selection__arrow,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow{background:transparent;background-image:none;border-left:0;top:2px;width:26px}.tribe-dropdown.select2-selection--single .select2-selection__arrow b,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow b{background:#fff url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E") no-repeat right 5px top 55%;background-size:auto;background-size:16px 16px;border:0;bottom:0;display:block;height:auto;left:0;margin:0;padding:0;right:0;top:0;width:auto}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered{background-image:none;border:1px solid #ccc;border-radius:3px;min-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline{line-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input{padding-bottom:0;padding-top:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice{line-height:19px;margin-top:2px;padding-bottom:0;padding-top:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div{line-height:inherit}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove{left:4px;top:3px;transition-property:border,color}.select2-results .select2-results__option{color:#939393;font-weight:400;margin-bottom:0}.select2-results .select2-results__option[aria-disabled=true]{background-color:#e0e0e0}.select2-results.select2-results__option--highlighted{background-color:#efefef;color:#a1a1a1;cursor:default;display:block}.wp-core-ui .button-red{background-color:#a00;border-color:#9b2124;box-shadow:inset 0 1px 0 rgba(120,200,230,.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red.hover,.wp-core-ui .button-red:focus,.wp-core-ui .button-red:hover{background-color:#a00;border-color:#7f1c1f;box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.3)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red:focus{border-color:#500f0e;box-shadow:inset 0 1px 0 rgba(120,200,230,.6),1px 1px 2px rgba(0,0,0,.4)}.wp-core-ui .button-red.active,.wp-core-ui .button-red.active:focus,.wp-core-ui .button-red.active:hover,.wp-core-ui .button-red:active{background:#7f1c1f;border-color:#601312 #ae2426 #ae2426;box-shadow:inset 0 1px 0 rgba(0,0,0,.1);color:hsla(0,0%,100%,.95);text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red-disabled,.wp-core-ui .button-red:disabled,.wp-core-ui .button-red[disabled]{background:#ba292b!important;border-color:#7f1c1f!important;box-shadow:none!important;color:#e79496!important;cursor:default;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important}.ticket_form .select2-container .select2-selection--single .select2-selection__arrow{display:none}.clear{zoom:1}.clear:after,.clear:before{content:" ";display:table}.clear:after{clear:both}.checkmark:after{border:solid #0ab152;border-width:0 3px 3px 0;content:"";display:block;height:15px;transform:rotate(45deg);width:8px}.checkmark.checkmark-right:after{float:right;margin-right:2em}.checkmark.checkmark-left:after{float:left;margin-left:2em}.checkmark.no-checkmark:after{display:none}.complete,.ok,.on,.yes,[data-status=complete],[data-status=ok],[data-status=on],[data-status=yes]{color:#0ab152}.incomplete,.ko,.no,.off,[data-status=incomplete],[data-status=ko],[data-status=no],[data-status=off]{color:#ff2500}.plugin-card-event-tickets-plus .column-downloaded,.plugin-card-event-tickets-plus .column-rating,.plugin-card-event-tickets-plus .column-updated,.plugin-card-event-tickets .column-downloaded,.plugin-card-event-tickets .column-rating,.plugin-card-event-tickets .column-updated,.plugin-card-events-calendar-pro .column-downloaded,.plugin-card-events-calendar-pro .column-rating,.plugin-card-events-calendar-pro .column-updated,.plugin-card-events-community-tickets .column-downloaded,.plugin-card-events-community-tickets .column-rating,.plugin-card-events-community-tickets .column-updated,.plugin-card-events-community .column-downloaded,.plugin-card-events-community .column-rating,.plugin-card-events-community .column-updated,.plugin-card-image-widget-plus .column-downloaded,.plugin-card-image-widget-plus .column-rating,.plugin-card-image-widget-plus .column-updated,.plugin-card-image-widget .column-downloaded,.plugin-card-image-widget .column-rating,.plugin-card-image-widget .column-updated,.plugin-card-the-events-calendar .column-downloaded,.plugin-card-the-events-calendar .column-rating,.plugin-card-the-events-calendar .column-updated,.plugin-card-tribe-eventbrite .column-downloaded,.plugin-card-tribe-eventbrite .column-rating,.plugin-card-tribe-eventbrite .column-updated,.plugin-card-tribe-filterbar .column-downloaded,.plugin-card-tribe-filterbar .column-rating,.plugin-card-tribe-filterbar .column-updated{display:none}body.tribe-welcome,body.tribe_events_page_tribe-help{background-color:#fff;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body.tribe-welcome .update-nag,body.tribe_events_page_tribe-help .update-nag{display:none}body.tribe-welcome #wpcontent,body.tribe_events_page_tribe-help #wpcontent{padding:0}body.tribe-welcome .tribe_settings,body.tribe_events_page_tribe-help .tribe_settings{margin:0}body.tribe-welcome #wpfooter,body.tribe-welcome .tribe_settings>h1,body.tribe_events_page_tribe-help #wpfooter,body.tribe_events_page_tribe-help .tribe_settings>h1{display:none}body.tribe-welcome #wpbody-content,body.tribe_events_page_tribe-help #wpbody-content{padding-bottom:25px}body.tribe-welcome .tribe-dependency-error,body.tribe_events_page_tribe-help .tribe-dependency-error{display:none}.tribe-events-admin-content-wrapper{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-style:normal;margin:0 auto;padding:0 0 30px;width:calc(100% - 40px)}.tribe-events-admin-card{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;display:block;margin:0 auto 36px;padding:27px;text-align:center}.tribe-events-admin-card--2up .tribe-events-admin-card__title{max-width:260px}.tribe-events-admin-card--3up .tribe-events-admin-card__description{height:71px}.tribe-events-admin-card--3up .tribe-events-admin-card__image{margin-bottom:28px}.tribe-events-admin-card__button{background-color:#fff;border:none;color:#3d54ff;font-size:14px;font-weight:700;letter-spacing:1px;line-height:16px;position:absolute;right:20px;text-transform:uppercase;top:17px}.tribe-events-admin-card__button:hover{color:#161b7d}.tribe-events-admin-card__description{color:#000;font-size:14px;font-style:normal;font-weight:400;line-height:22px;margin-top:16px}.tribe-events-admin-card__image{display:block;height:100px;margin:0 auto}.tribe-events-admin-card__link{color:#3d54ff;display:inline-block;font-size:16px;font-style:normal;font-weight:700;line-height:18px;margin-top:24px;position:relative;text-decoration:none}.tribe-events-admin-card__link:hover{color:#161b7d}.tribe-events-admin-card__link:after{border-style:solid;border-width:0 0 1px;bottom:-4px;content:"";left:0;position:absolute;width:100%}.tribe-events-admin-card__title{color:#0f1031;font-size:20px;font-weight:700;line-height:23px;margin:auto}.tribe-events-admin-card-grid{max-width:1048px}input[type=checkbox].tribe-common-switch__input{display:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label{background:#fff;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;cursor:pointer;display:block;height:18px;outline:0;padding:3px;position:relative;transition:all .2s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:27px}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:after,input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:before{content:"";display:block;height:10px;position:relative;width:10px}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:after{background:#878787;border-radius:2px;content:"";left:0;transition:all .2s ease}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:before{display:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label::-moz-selection{background:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label::selection{background:none}input[type=checkbox].tribe-common-switch__input:checked+.tribe-common-switch__label:after{background:#2e709d;left:50%}.tribe-events-admin-header__logo-word-mark{display:inline-block;height:auto;margin:0 0 26px;vertical-align:middle;width:312px}.tribe-events-admin-header{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding:45px 0 0}.tribe-events-admin-header__right-image{height:280px;position:absolute;right:0;top:0;width:auto;z-index:-1}.tribe-events-admin-header__title{font-size:48px;line-height:48px;margin:0 0 18px}.tribe-events-admin-header__description{font-size:18px;line-height:28px;margin-bottom:44px;max-width:60%}.tribe-events-admin-tab-nav{display:flex;margin:0}.tribe-events-admin-tab-nav li{cursor:pointer;font-size:16px;font-weight:500;margin-bottom:0;margin-right:30px}.tribe-events-admin-tab-nav li:hover{color:#334aff}.tribe-events-admin-tab-nav .selected{border-bottom:3px solid #334aff;color:#334aff;padding-bottom:17px}.tribe-events-admin-tab-nav li:after{background:#334aff;border-radius:100px;bottom:0;content:"";display:block;height:3px;left:0;position:absolute;right:0}.tribe-events-admin__line{border-top:1px solid #e1e1e4}.tribe-events-admin-products-description{color:#0f1031;font-size:14px;line-height:2}.tribe-events-admin-products-card{align-items:center;border:1px solid #e1e1e4;border-radius:20px;display:flex;padding:10px 15px}.tribe-events-admin-products-card__icon{height:40px;-o-object-fit:contain;object-fit:contain;width:40px}.tribe-events-admin-products-card__group{margin:0 20px;max-width:55%}.tribe-events-admin-products-card__group-title{color:#0f1031;font-size:16px;font-weight:700;line-height:1;margin:0}.tribe-events-admin-products-card__group-description{font-size:12px;margin-top:5px}.tribe-events-admin-products-card__button{background-color:#fff;border:1px solid #e1e1e4;border-radius:20px;color:#0f1031;font-size:12px;font-weight:700;letter-spacing:1px;line-height:16px;margin-left:auto;padding:10px 15px;text-decoration:none;text-transform:uppercase}.tribe-events-admin-products-card__button:hover{background-color:#334aff;color:#fff}.tribe-events-admin-products-card__button:active,.tribe-events-admin-products-card__button:focus{box-shadow:none;outline:none}.tribe-events-admin-products-card__button--active,.tribe-events-admin-products-card__button--active:active,.tribe-events-admin-products-card__button--active:focus,.tribe-events-admin-products-card__button--active:hover{background:rgba(61,84,255,.16);color:#334aff;cursor:not-allowed;text-transform:uppercase}.tribe-events-admin-card--1up{width:100%}.tribe-events-admin-card--no-pad{padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__image{display:block;height:152px;margin:0;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{font-size:28px;line-height:34px;text-align:left}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin:0;padding:0;text-align:left}.tribe-events-admin-card--no-pad .tribe-events-admin-card__link{margin:0;padding:0}.tribe-events-admin-card--faq{display:inline-block;font-size:0;height:147px;margin:0 0 0 30px;padding:24px 16px 22px 20px;width:230px}.tribe-events-admin-card--faq:first-child{margin-left:0}.tribe-events-admin-card--faq img{float:left;height:22px;width:16px}.tribe-events-admin-card--faq .tribe-events-admin-faq__question{color:#334aff;font-size:16px;line-height:19px;margin:0 0 12px 26px;text-align:left}.tribe-events-admin-card--faq .tribe-events-admin-faq__answer{font-size:13px;line-height:16px;margin-left:26px;text-align:left}.tribe-events-admin-video{border-radius:16px;height:200px;margin-bottom:72px;-webkit-mask-image:-webkit-radial-gradient(circle,#fff 100%,#000 0);overflow:hidden;-webkit-transform:rotate(.000001deg)}.tribe-events-admin-video iframe{width:100%}.tribe-events-admin-card--promo-blue{background-color:#3d54ff;background-image:url(../images/welcome/promo.jpg)}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{color:#fff;font-size:16px;margin-bottom:16px;text-align:left}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__title{color:#fff;text-align:left}.tribe-events-admin-graphic{position:absolute;right:0;top:106px;z-index:-1}.tribe-events-admin-graphic--desktop-only{display:none}.tribe-events-admin-graphic--mobile-only{display:block}.tribe-events-admin-card__form{position:relative}input[type=email].tribe-events-admin-card__input{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;font-size:14px;height:54px}input[type=email].tribe-events-admin-card__input:-ms-input-placeholder{color:rgba(15,16,49,.72);letter-spacing:.5px;padding-left:10px}input[type=email].tribe-events-admin-card__input::placeholder{color:rgba(15,16,49,.72);letter-spacing:.5px;padding-left:10px}.tribe-events-admin-container,.tribe-events-admin-content-wrapper.tribe-events-admin-container{margin:0 auto;max-width:1024px;width:90%}.tribe-events-admin-2col-grid{display:grid;grid-gap:15px 30px;gap:15px 30px;grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-3col-grid{display:grid;grid-gap:30px;gap:30px;grid-template-areas:". . .";grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-4col-grid{display:grid;grid-gap:30px;gap:30px;grid-template-areas:". . . .";grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-products{margin:10px 0 0}.tribe-events-admin-quick-nav{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;display:block;margin:40px 0 78px;padding:18px 23px 2px}.tribe-events-admin-quick-nav__link{color:#3d54ff;font-size:16px;font-weight:700;line-height:18px;text-align:center;text-decoration:none}.tribe-events-admin-quick-nav__link:hover{color:#161b7d}.tribe-events-admin-quick-nav__link-item{display:block;padding-bottom:19px}.tribe-events-admin-quick-nav__links{display:inline}.tribe-events-admin-quick-nav__title{color:rgba(15,16,49,.72);display:inline-block;font-size:14px;font-weight:400;line-height:16px;padding-bottom:14px;text-transform:uppercase}.tribe-events-admin-title{padding-top:14px}.tribe-events-admin-title__description{color:#0f1031;font-size:16px;font-weight:400;line-height:24px;max-width:584px;padding-top:15px}.tribe-events-admin-title__heading{color:#0f1031;display:inline-block;font-size:24px;font-weight:700;line-height:28px;margin:5px 0 0}.tribe-events-admin-title__logo{margin-right:8px;vertical-align:top;width:34px}.tribe-events-admin-notice{background-color:#3d54ff;height:65px}.tribe-events-admin-notice .tribe-events-admin-content-wrapper{padding-bottom:0;padding-top:8px}.tribe-events-admin-notice p{color:#fff;display:inline-block;font-family:Helvetica,sans-serif;font-size:16px;line-height:18px;margin-top:0;padding-bottom:12px;padding-left:16px;vertical-align:middle;width:calc(100% - 60px)}.tribe-events-admin-notice__logo{display:inline-block}.tribe-events-admin-tickets .tribe-events-admin-section-header{font-size:28px;line-height:32px}.tribe-events-admin-tickets .tribe-events-admin-graphic--desktop-only{width:365px}.tribe-events-admin-tickets .tribe-events-admin-graphic--mobile-only{top:230px;width:300px}.tribe-events-admin-tickets .tribe-events-admin-title__heading{margin-top:0}.tribe-events-admin-tickets .tribe-events-admin-title__logo{margin-right:4px;width:32px}.tribe-events-admin-kb{margin:10px 0 0}.tribe-events-admin-kb-card{border:1px solid #e1e1e4;border-radius:20px}.tribe-events-admin-kb-card__image{height:auto;width:100%}.tribe-events-admin-kb-card__title{color:#0f1031;flex-grow:0;font-size:20px;font-weight:700;line-height:1.2;margin:0;padding:20px 28px 10px}.tribe-events-admin-kb-card__links{margin:0;padding:0 28px 25px}.tribe-events-admin-kb-card__links li{margin:0 0 10px}.tribe-events-admin-kb-card__links li a{color:#334aff;font-size:14px;line-height:1.2;text-decoration:none}.tribe-events-admin-kb-card__links li a:focus{box-shadow:none;outline:none}.tribe-events-admin-kb-card__links li a:hover{color:#1c39bb}.tribe-events-admin-section-header{align-items:center;color:#000;display:flex;font-weight:700;justify-content:space-between;margin:0}.tribe-events-admin-section-header h3{color:#0f1031;font-size:28px;font-weight:700;line-height:1}.tribe-events-admin-section-header a{border-bottom:2px solid #334aff;color:#334aff;font-size:14px;padding-bottom:2px;text-decoration:none}.tribe-events-admin-section-header a:focus{box-shadow:none;outline:none}.tribe-events-admin-section-header a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-faq{margin:10px 0 0}.tribe-events-admin-faq-card{border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;padding:24px 15px 19px 19px}.tribe-events-admin-faq-card a{color:#0f1031}.tribe-events-admin-faq-card a:focus{box-shadow:none;outline:none}.tribe-events-admin-faq-card a:hover{color:#1c39bb}.tribe-events-admin-faq-card__icon img{height:22px;width:16px}.tribe-events-admin-faq-card__content{margin-left:10px}.tribe-events-admin-faq__question,.tribe-events-admin-faq__question a{color:#334aff;font-size:16px;text-decoration:none}.tribe-events-admin-faq__question a:focus{box-shadow:none;outline:none}.tribe-events-admin-faq__question a:hover{color:#1c39bb}.tribe-events-admin-faq__answer{color:#0f1031;font-size:13px;margin-top:18px}.tribe-events-admin-extensions-title{color:#0f1031;font-size:16px;line-height:1.5;margin:0 0 30px;max-width:70%}.tribe-events-admin-extensions{margin:10px 0 0}.tribe-events-admin-extensions-card{border:1px solid #e1e1e4;border-radius:20px;border-top:8px solid #334aff;padding:48px 35px 24px 25px}.tribe-events-admin-extensions-card__title{font-size:20px;margin:0}.tribe-events-admin-extensions-card__title a{color:#0f1031;font-family:Helvetica,sans-serif;font-size:20px;font-weight:700;line-height:1.2;text-decoration:none}.tribe-events-admin-extensions-card__title a:active,.tribe-events-admin-extensions-card__title a:focus,.tribe-events-admin-extensions-card__title a:hover{box-shadow:none;color:#334aff}.tribe-events-admin-extensions-card__description{color:#0f1031;font-family:Helvetica,sans-serif;font-size:14px;line-height:1.43;margin:20px 0}.tribe-events-admin-cta{align-items:center;border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;margin:60px 0}.tribe-events-admin-cta__image{height:152px;-o-object-fit:contain;object-fit:contain;width:auto}.tribe-events-admin-cta__content,.tribe-events-admin__troubleshooting-cta{align-items:center;display:flex;flex-direction:column;justify-content:center;padding:20px 0;width:100%}.tribe-events-admin-cta__content-title{color:#0f1031;font-size:28px;font-weight:700;line-height:normal;margin:0 0 10px;text-align:center}.tribe-events-admin-cta__content-subtitle{color:#0f1031;font-size:16px;line-height:1.5;margin-bottom:10px;text-align:center}.tribe-events-admin-cta__content-description a{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;font-weight:700;padding-bottom:2px;text-decoration:none}.tribe-events-admin-cta__content-description a:focus{box-shadow:none;outline:none}.tribe-events-admin-cta__content-description a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-footer-logo{display:inline-block;vertical-align:middle;width:228px}.tribe-events-admin-step{margin:10px 0 0}.tribe-events-admin-step-card{border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;padding:24px 15px 19px 19px}.tribe-events-admin-step-card a{border-bottom:2px solid #334aff;color:#334aff;padding-bottom:2px;text-decoration:none}.tribe-events-admin-step-card a:focus{box-shadow:none;outline:none}.tribe-events-admin-step-card a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-step-card__icon img{height:43px;margin-right:5px;width:42px}.tribe-events-admin-step-card__content{margin-left:10px}.tribe-events-admin-step__title{color:#0f1031;font-size:20px;font-weight:700;line-height:1.2;margin-bottom:10px}.tribe-events-admin-step__answer{color:#0f1031;font-size:13px;margin-top:18px}.tribe-events-admin__system-information{display:grid;grid-gap:15px 30px;gap:15px 30px;grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:1fr;margin:100px 0;position:relative}.tribe-events-admin__troubleshooting-title{color:#0f1031;font-size:28px;font-weight:700;line-height:1;margin:0}.tribe-events-admin__troubleshooting-description{color:#0f1031;font-size:18px;line-height:1.2;line-height:1.44;margin:20px 0}.tribe-events-admin__system-information-select{display:flex;margin:30px 0 20px}.tribe-events-admin__system-information-select input[type=checkbox]{margin:0 10px 0 0}.tribe-events-admin__system-information-select label{color:#0f1031;font-size:16px;line-height:1.2}.tribe-events-admin__system-information-content small{color:#0f1031;font-size:12px;line-height:1.2}.tribe-events-admin__recent-template-changes .template-updates-wrapper,.tribe-events-admin__system-information-widget{background:#0f1031;border-radius:16px;color:#fff;font-size:14px;line-height:1.14;max-height:280px;overflow:scroll;-ms-overflow-style:none;padding:12px 0 0 27px;scrollbar-width:none}.tribe-events-admin__recent-template-changes .template-updates-wrapper p{color:#fff;font-size:14px;line-height:1.14;margin:0}.tribe-events-admin__system-information-widget a{color:#334aff}.tribe-events-admin__system-information-widget a:hover{opacity:.8}.tribe-events-admin__recent-template-changes .template-updates-wrapper{padding:30px 0 30px 27px}.tribe-events-admin__recent-template-changes .template-updates-wrapper::-webkit-scrollbar,.tribe-events-admin__system-information-widget::-webkit-scrollbar{display:none}.tribe-events-admin__system-information-widget-copy{bottom:10px;position:absolute}.tribe-events-admin__system-information-widget-copy button{background-color:#334aff;border:none;border-radius:100px;color:#fff;cursor:pointer;font-size:16px;font-weight:700;outline:none;padding:18px 25px;text-align:center}.tribe-events-admin__system-information-widget-copy button:hover{background-color:#1c39bb}.tribe-events-admin__system-information-widget-copy button .dashicons,.tribe-events-admin__system-information-widget-copy button .dashicons-before:before{display:none}.tribe-events-admin__system-information-widget-copy button .optin-success{color:#fff;font-size:16px;font-weight:700;text-align:center}.tribe-events-admin__recent-template-changes p{color:#0f1031;font-size:18px;line-height:1.2;line-height:1.44;margin:20px 0}.tribe-events-admin__recent-log{margin-top:50px}.tribe-events-admin__troubleshooting-event-log-wrapper label{color:#0f1031;display:block;font-size:16px;line-height:1.63;margin-bottom:10px}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-controls{margin:20px 0 10px}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-viewer{background:#0f1031;border-radius:16px;color:#fff;font-size:14px;line-height:1.14;max-height:280px;min-height:60px;overflow:scroll;-ms-overflow-style:none;padding:12px 0 0 27px;scrollbar-width:none}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-viewer::-webkit-scrollbar{display:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;padding-bottom:2px;text-decoration:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log:focus{box-shadow:none;outline:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__troubleshooting-event-log-wrapper .tribe-events-admin__recent-log-filters-select-wrapper:after{display:none}.tribe-events-admin__recent-log-filters{display:flex;padding:20px 0 40px}.tribe-events-admin__recent-log-filters-field{margin-right:40px}.tribe-events-admin__recent-log-filters-select-wrapper:after{content:url(../images/help/polygon.svg);height:13px;pointer-events:none;position:absolute;right:22px;top:20px;width:14px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default .select2-selection--single{border:1px solid #e1e1e4!important;border-radius:16px;color:#0f1031;font-size:14px;line-height:1.14;padding:0 25px 0 15px!important}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls{margin-bottom:20px;padding:0}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:first-child,.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(2),.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(3){padding-right:75px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-selection__clear{display:none}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default .select2-selection--single .select2-selection__arrow{right:5px}.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple,.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default.select2-container--open.select2-container--below .select2-selection--single{border-bottom-left-radius:16px;border-bottom-right-radius:16px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container .select2-selection--single .select2-selection__rendered{width:100%}.tribe-events-admin__recent-log-filters-select-wrapper select.focus-visible,.tribe-events-admin__recent-log-filters-select-wrapper select:focus-visible{outline:none}.tribe-events-admin__recent-log-filters-select-wrapper select option{color:#0f1031;font-size:14px;line-height:1.14}.tribe-events-admin__ea-status{margin-top:50px}.tribe-events-admin__issues-found-card{background-color:#f3eee8;border-radius:8px;margin-bottom:20px}.tribe-events-admin__issues-found-card:last-of-type{margin-bottom:100px}.tribe-events-admin__issues-found-card-title{align-items:center;cursor:pointer;display:flex;padding:10px 20px 10px 17px;position:relative}.tribe-events-admin__issues-found-card-title img{height:21px;margin-right:14px;-o-object-fit:contain;object-fit:contain;width:21px}.tribe-events-admin__issues-found-card-title h3{margin:0}.tribe-events-admin__issues-found-card-title span{color:#0f1031;display:block}.tribe-events-admin__issues-found-card-title i{background-image:url(../images/help/arrow-down.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:15px;margin:12px 20px;position:absolute;right:0;top:0;transition:all .3s ease;width:15px}.tribe-events-admin__issues-found-card-title.active i{background-image:url(../images/help/arrow-up.svg);background-repeat:no-repeat;top:5px}.tribe-events-admin__issues-found-card-description{display:none;padding:0 20px 20px 55px}.tribe-events-admin__issues-found-card-description p{color:#0f1031;font-size:16px;margin:0}.tribe-events-admin__issues-found-card-description-actions{display:flex;padding:20px 0 10px}.tribe-events-admin__issues-found-card-description-actions a{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;margin-right:20px;padding-bottom:5px;text-decoration:none}.tribe-events-admin__issues-found-card-description-actions a:focus{box-shadow:none;outline:none}.tribe-events-admin__issues-found-card-description-actions a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__ea-status-table-wrapper{overflow-x:auto}.tribe-events-admin__ea-status-table{border:1px solid #e1e1e4;border-radius:16px;margin:30px 0 40px;overflow:hidden}.tribe-events-admin__ea-status-table a{border-bottom:2px solid #334aff;color:#334aff;padding-bottom:2px;text-decoration:none}.tribe-events-admin__ea-status-table a:focus{box-shadow:none;outline:none}.tribe-events-admin__ea-status-table a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__ea-status-table tr{align-items:center;display:flex}.tribe-events-admin__ea-status-table th{color:#0f1031;font-weight:700;line-height:1.17;margin-top:10px;padding:5px 25px}.tribe-events-admin__ea-status-table td{align-items:center;color:#0f1031;display:flex;font-size:16px;line-height:1.63;padding:10px 25px;width:25%}.tribe-events-admin__ea-status-table td:nth-child(2){width:45%}.tribe-events-admin__ea-status-table td:nth-child(3){display:flex;justify-content:flex-end;width:30%}.tribe-events-admin__ea-status-table-dark{background-color:#f9f7f4}.tribe-events-admin__ea-status-table td img{height:21px;margin-right:14px;-o-object-fit:contain;object-fit:contain;width:21px}.tribe_events_page_tec-troubleshooting{background-color:#fff}#tribe-community,#tribe-ticketing{display:none}.tribe-events-admin__troubleshooting-notice{background-color:#161b7d;color:#fff;font-size:16px;line-height:1;margin-left:-1.55vw;padding:24px 0}.tribe-events-admin__troubleshooting-notice_title{margin:0 auto;max-width:1024px;padding-left:25px;width:90%}.tribe-events-admin__troubleshooting-notice_title a{border-bottom:2px solid #fff;color:#fff;font-size:16px;line-height:1;padding-bottom:2px;text-decoration:none}.tribe-events-admin__troubleshooting-notice_title a:focus{box-shadow:none;outline:none}.tribe-events-admin__troubleshooting-notice_title a:hover{border-bottom:2px solid #f3eee8;color:#f3eee8}.tribe_events_page_tribe-help #tec-help-community,.tribe_events_page_tribe-help #tec-help-ticketing{display:none}.tribe_events_page_tribe-help .tribe-events-admin-title{padding-top:25px}.tribe_events_page_tribe-help .tribe-events-admin-title img{height:67px}body.tribe-welcome #fs_connect{border:1px solid #e1e1e4;border-radius:16px;box-shadow:none;box-sizing:border-box;margin-left:22px}body.tribe-welcome #fs_connect .fs-actions{background-color:transparent}body.tribe-welcome #fs_connect .fs-permissions{border-top:1px solid #e1e1e4;margin:0 16px}body.tribe-welcome #fs_connect button{background-color:#3d54ff;border-color:#3d54ff}body.tribe-welcome #fs_connect .button-secondary{background:#fff;border-color:#3d54ff;color:#3d54ff}body.tribe-welcome #fs_connect a{color:#3d54ff}body.tribe-welcome #fs_connect a:focus{box-shadow:none;outline:none}body.tribe-welcome #fs_connect a:hover{color:#161b7d}@media only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min--moz-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){#tribe-loading span{background-image:url(../images/tribe-loading@2x.gif)}}@media screen and (max-width:782px){.tribe-half-column,.tribe-row .tribe-half-column:last-child{margin:0 0 20px;width:100%}input[type=email]{width:100%}.events-cal .subsubsub{float:none}.events-cal .search-box{width:98%}.events-cal #search-submit{width:100%}.events-cal .tablenav.top{display:none}}@media screen and (min-width:500px){.api-check .tribe-mascot{display:block}.api-check .notice-content{margin-right:180px}}@media screen and (min-width:320px){.tribe-marketing-notice .tribe-marketing-notice__icon{display:block}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px}}@media screen and (min-width:600px) and (max-width:782px){.tribe-marketing-notice .tribe-marketing-notice__content{margin-left:145px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px;padding:0}}@media screen and (min-width:782px){.tribe-marketing-notice .tribe-marketing-notice__content{margin-left:130px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px;padding:0}.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe-welcome .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:642px}}@media screen and (min-width:400px){.notice-tribe-banner .tribe-marketing-notice__icon{width:67px}}@media screen and (min-width:800px){.notice-tribe-banner h3{display:inline-block;font-size:1rem;margin:0 .5rem 0 0}.notice-tribe-banner a{line-height:1.5}.notice-tribe-banner a,.notice-tribe-banner p{font-size:1rem}.notice-tribe-banner p{margin:0 .5rem 0 0}.notice-tribe-banner .tribe-marketing-notice__cta{display:inline-block;margin-left:.5rem}}@media screen and (min-width:1215px){.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:992px}.tribe-welcome .notice-tribe-banner .tribe-marketing-notice{max-width:1036px}}@media screen and (min-width:710px){.tribe-events-admin-content-wrapper{width:670px}.tribe-events-admin-card--2up{display:inline-block;width:calc(50% - 20px)}.tribe-events-admin-card--2up.tribe-events-admin-card--first{margin-right:36px}.tribe-events-admin-card--2up.tribe-events-admin-card--last{margin-right:0}.tribe-events-admin-card--2up .tribe-events-admin-card__image{height:100px;margin-bottom:12px}.tribe-events-admin-card--2up .tribe-events-admin-card__title{margin-bottom:27px;max-width:340px}.tribe-events-admin-card--3up{display:inline-block;margin-bottom:32px;width:calc(50% - 18px)}.tribe-events-admin-card--3up.tribe-events-admin-card--first{margin-right:32px}.tribe-events-admin-card--3up.tribe-events-admin-card--middle{margin-right:0}.tribe-events-admin-card__title{font-size:20px;line-height:23px}.tribe-events-admin-card--1up{display:inline-block;margin-left:32px;width:calc(50% - 18px)}.tribe-events-admin-card--1up .tribe-events-admin-card__description{height:71px}.tribe-events-admin-card--1up .tribe-events-admin-card__image{margin-bottom:28px}.tribe-events-admin-card--no-pad{height:154px;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{margin-left:50%;padding:42px 0 10px}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin-left:50%}.tribe-events-admin-card--promo-blue{display:block;margin-left:0;min-height:170px;width:100%}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{float:left;max-width:300px}.tribe-events-admin-graphic{max-width:250px;top:0}.tribe-events-admin-graphic--desktop-only{display:block}.tribe-events-admin-graphic--mobile-only{display:none}.tribe-events-admin-card__form{float:right;width:300px}input[type=email].tribe-events-admin-card__input{width:300px}.tribe-events-admin-title{padding-top:50px}.tribe-events-admin-title__description{padding-top:15px}.tribe-events-admin-title__heading{font-size:48px;line-height:55px;margin:0}.tribe-events-admin-title__logo{margin-right:14px;padding-top:5px;width:40px}.tribe-events-admin-tickets .tribe-events-admin-card__title{font-size:18px}.tribe-events-admin-tickets .tribe-events-admin-card--2up .tribe-events-admin-card__title{font-size:18px;height:66px}.tribe-events-admin-tickets .tribe-events-admin-title__logo{margin-right:8px;padding-top:4px;width:60px}}@media screen and (min-width:1217px){.tribe-events-admin-content-wrapper{max-width:1060px;width:100%}.tribe-events-admin-card--2up{margin-right:36px;width:486px}.tribe-events-admin-card--3up{width:310px}.tribe-events-admin-card--3up.tribe-events-admin-card--first,.tribe-events-admin-card--3up.tribe-events-admin-card--middle{margin-right:36px}.tribe-events-admin-card--3up.tribe-events-admin-card--last{margin-right:0}.tribe-events-admin-card--1up{margin:0 0 36px;padding:33px 44px 30px;text-align:left;width:1012px}.tribe-events-admin-card--1up .tribe-events-admin-card__description{height:auto}.tribe-events-admin-card--1up .tribe-events-admin-card__image{float:left;margin:0 48px 10px 0}.tribe-events-admin-card--no-pad{padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__image{margin:0;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{margin-left:50%;padding:42px 0 10px}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin-left:50%}.tribe-events-admin-card--promo-blue{min-height:150px}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{max-width:450px}.tribe-events-admin-graphic{max-width:none}.tribe-events-admin-card__form,input[type=email].tribe-events-admin-card__input{width:365px}.tribe-events-admin-quick-nav{border-radius:100px;display:inline-block;height:54px;margin:24px 0 94px;max-width:1010px;padding:0 36px 0 0}.tribe-events-admin-quick-nav__link-item{display:inline-block;padding:18px 10px 0}.tribe-events-admin-quick-nav__title{padding:19px 6px 17px 32px}.tribe-events-admin-tickets .tribe-events-admin-card--2up .tribe-events-admin-card__title{height:auto}}@media screen and (max-width:768px){.tribe-events-admin-header__logo-word-mark{width:285px}.tribe-events-admin-header__right-image{height:160px}.tribe-events-admin-header__description{max-width:100%}.tribe-events-admin-tab-nav li{margin-right:20px}.tribe-events-admin-tab-nav .selected{border-bottom:2px solid #334aff;padding-bottom:10px}.tribe-events-admin-2col-grid{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr))}.tribe-events-admin-3col-grid{grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr))}.tribe-events-admin-extensions-title{max-width:100%}.tribe-events-admin-cta{align-items:flex-start;flex-direction:column;overflow:hidden}.tribe-events-admin-footer-logo{width:225px}.tribe-events-admin__system-information{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr));margin:50px 0}}@media screen and (max-width:480px){.tribe-events-admin-header__logo-word-mark{width:260px}.tribe-events-admin-header__right-image{height:120px}.tribe-events-admin-header__title{font-size:35px}.tribe-events-admin-header__description{max-width:100%}.tribe-events-admin-tab-nav{border:1px solid #e1e1e4;border-radius:20px;flex-direction:column;padding:18px 22px}.tribe-events-admin-tab-nav li{margin-bottom:18px;margin-right:0}.tribe-events-admin-tab-nav .selected{border-bottom:2px solid #334aff;padding-bottom:10px;width:-moz-fit-content;width:fit-content}.tribe-events-admin__line{border:none}.tribe-events-admin-products-card,.tribe-events-admin-products-description{display:none}.tribe-events-admin-container,.tribe-events-admin-content-wrapper.tribe-events-admin-container{max-width:90%}.tribe-events-admin-2col-grid,.tribe-events-admin-3col-grid,.tribe-events-admin-4col-grid{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr))}.tribe-events-admin-extensions-title{max-width:100%}.tribe-events-admin-cta__image{height:auto;width:90%}.tribe-events-admin-cta__content,.tribe-events-admin__troubleshooting-cta{align-items:flex-start;padding:32px 23px 45px;width:auto}.tribe-events-admin-cta__content-title{font-size:22px;text-align:left}.tribe-events-admin-cta__content-subtitle{text-align:left}.tribe-events-admin-footer-logo{width:210px}.tribe-events-admin__system-information{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr));margin:50px 0}.tribe-events-admin__troubleshooting-notice{margin-left:-20px}.tribe-events-admin__troubleshooting-notice_title{max-width:90%}}@media screen and (min-width:1200px){.tribe-events-admin-products-card__group{max-width:47%}}@media screen and (min-width:500px) and (max-width:1080px){.tribe-events-admin-4col-grid{grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr))}}@media screen and (min-width:768px){.tribe-events-admin-section-header{font-size:28px;line-height:1.143;margin:50px 0 21px}}@media screen and (max-width:1080px){.tribe-events-admin-cta__content-title{font-size:24px}}@media only screen and (max-width:1920px){.tribe-events-admin__system-information-widget-copy{right:20.5vw}}@media only screen and (max-width:1280px){.tribe-events-admin__system-information-widget-copy{right:22vw}}@media only screen and (max-width:768px){.tribe-events-admin__system-information-widget-copy{left:10px;right:auto}.tribe-events-admin__recent-log-filters{flex-direction:column}.tribe-events-admin__recent-log-filters-field{margin-bottom:30px;margin-right:0}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:first-child,.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(2),.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(3){padding-right:30px}.tribe-events-admin__issues-found-card-title h3{max-width:90%}}@media only screen and (max-width:480px){.tribe-events-admin__system-information-widget-copy{left:10px;right:auto}.tribe-events-admin__recent-log-filters{flex-direction:column}.tribe-events-admin__recent-log-filters-field{margin-bottom:30px;margin-right:0}.tribe-events-admin__recent-log-filters-select-wrapper:after{right:25px}.tribe-events-admin__issues-found-card-title h3{max-width:80%}.tribe-events-admin__ea-status-table{overflow:scroll}.tribe-events-admin__ea-status-table td{min-width:150px}.tribe-events-admin__ea-status-table td:nth-child(2),.tribe-events-admin__ea-status-table td:nth-child(3){width:100%}}
1
+ .invalid input,input:out-of-range{border:2px solid red!important}.valid input{border:1px solid green}.clearfix{zoom:1}.placeholder{color:#999;cursor:text;padding:4px}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::placeholder,textarea::placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.bubble{background-color:#f9f9f9;border:1px solid #dfdfdf;border-radius:3px;border-spacing:0;padding:10px}.tribe-sticky-tooltip{color:#bbb}td.tribe_message{padding-bottom:10px!important}#tribe_thanks{float:left;margin:5px 0 0;width:200px}.tribe_brand{font-family:Georgia,serif!important;font-size:17px!important;font-weight:400;margin:8px 0}.tribe-rating{color:#3d54ff}.tribe-rating:hover{color:#1c39bb}#tribe-upgrade{background:#f6f6f6;border:1px solid #ccc;border-radius:5px;margin:20px 0 30px;padding:0 20px 20px}#tribe-upgrade .message{background-color:#ffffe0;border:1px solid #e6db55;border-radius:3px;padding:6px 12px}table.plugins .tribe-plugin-update-message{background:#d54e21;color:#fff;display:inline-table;margin:6px 0;padding:10px 12px}table.plugins .tribe-plugin-update-message h4{display:inline;font-weight:700;margin-right:8px}table.plugins .tribe-plugin-update-message h4:after{content:" \00BB "}table.plugins .tribe-plugin-update-message a{color:#fff;text-decoration:underline}.tribe-settings-form{max-width:1000px}.tribe-settings-form fieldset{clear:both;display:inline-block;padding:10px 0}.tribe-settings-form fieldset.tribe-field-license_key legend{width:auto}.tribe-settings-form legend{float:left;font-weight:700;margin-right:20px;width:220px}.tribe-settings-form .tribe-field-wrap{float:left;max-width:500px}.tribe-settings-form .tribe-field-wrap :first-child{margin-top:0}.tribe-settings-form .tribe-field-checkbox_list label,.tribe-settings-form .tribe-field-radio label{display:block;margin:5px 0 5px 20px;text-indent:-20px}.tribe-settings-form .tribe-field-checkbox_list label>p,.tribe-settings-form .tribe-field-radio label>p{margin-left:1px;text-indent:0}.tribe-settings-form .tribe-field-checkbox_list label input,.tribe-settings-form .tribe-field-radio label input{margin-right:5px}.tribe-settings-form .tribe-settings-form-wrap .description,.tribe-settings-form .tribe-settings-form-wrap fieldset,.tribe-settings-form fieldset[id^=tribe-field-geoloc_]{padding-left:12px}.tribe-settings-form .tribe-settings-form-wrap fieldset .description{margin-left:0;max-width:450px;padding-left:0}.tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection{margin-bottom:18px}.tribe-settings-form .tribe-settings-form-wrap #tribe-field-stylesheetOption .description{color:#999;margin-left:1px}.tribe-settings-form .tribe-settings-form-wrap h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}.tribe-settings-form .tribe-settings-form-wrap .contained,.tribe-settings-form .tribe-settings-form-wrap .system-info,.tribe-settings-form .tribe-settings-form-wrap .tribe-sysinfo-optin-msg,.tribe-settings-form .tribe-settings-form-wrap h3+p{margin:0 0 10px;padding-left:12px}.tribe_settings .tribe-field-indent{margin-left:245px}.tribe_settings #pu_dashboard_message{display:none}.tribe_settings .tribe-errors-list{margin-left:15px}.tribe_settings .expiring-license{color:red}.tribe_settings .tribe-error{border:1px solid red}.tribe_settings .tribe-field-description{margin-bottom:0;position:relative;top:-12px}.tribe_settings #ical-link{top:-14px}#modern-tribe-info{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:8px 20px 12px}#modern-tribe-info img{margin:10px 0}#modern-tribe-info ul{list-style:disc;margin-left:20px}#modern-tribe-info ul ul{list-style:circle}.tribe-field-inline-dropdown{margin-left:0;margin-right:0}.tribe-field-inline-text{line-height:28px;margin:0 2px}.tribe-field-textarea.tribe-size-small textarea{height:60px;width:180px}.tribe-field-textarea.tribe-size-medium textarea{height:80px;width:300px}.tribe-field-textarea.tribe-size-large textarea{height:120px;width:450px}.tribe-field-email.tribe-size-small input,.tribe-field-license_key.tribe-size-small input,.tribe-field-text.tribe-size-small input{width:50px}.tribe-field-email.tribe-size-medium input,.tribe-field-license_key.tribe-size-medium input,.tribe-field-text.tribe-size-medium input{width:225px}.tribe-field-email.tribe-size-large input,.tribe-field-license_key.tribe-size-large input,.tribe-field-text.tribe-size-large input{width:450px}.tribe-field-dropdown.tribe-size-small select{width:100px}.tribe-field-dropdown.tribe-size-medium select{width:300px}.tribe-field-dropdown.tribe-size-large select{width:450px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap{max-width:600px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap .description{max-width:100%}.tribe-field-dropdown_chosen.tribe-size-small select{width:100px}.tribe-field-dropdown_chosen.tribe-size-medium select{width:200px}.tribe-field-dropdown_chosen.tribe-size-large select{width:300px}.tribe-field-wrap .tooltip:first-child{font-style:normal}.tribe-field.indent{margin-left:252px;width:75%}.tribe-field.indent legend{font-weight:400;width:auto}.tribe-field.indent .tribe-field-wrap{padding-right:12px}.tribe-field.indent.tribe-field-radio .tribe-field-wrap{clear:left;margin-top:12px}.tribe-field.light-bordered{background-color:#fff;border:1px solid #d3d3d3}.ajax-loading-license,.invalid-key,.valid-key{display:none;margin:0 5px}.ajax-loading-license{position:relative;top:5px}.key-validity{display:inline-block}.invalid-key,.optin-fail{color:red}.optin-success,.valid-key{color:green}.valid-key.service-msg{color:#b72}#additional-field-table{margin-bottom:20px}.tribe-admin-box-left{float:left;width:20%}.tribe-admin-box-left,.tribe-admin-box-right{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:0 20px 15px}.tribe-admin-box-right{float:right;width:68%}.ajax-loader{float:right;margin:10px}.tribe-arrangeable-item{border:1px solid #d3d3d3;border-radius:3px}.tribe-arrangeable-item .ui-state-default{border:none}.tribe-arrangeable-item-top{padding:6px}.tribe-arrangeable-item-top:hover{cursor:move}.tribe-arrangeable-action{float:right}.tribe-arrangeable-child{background-color:#f9f9f9;border-top:1px solid #d3d3d3;display:none;padding:25px}.tribe-arrangeable-child label{display:block;margin:0 0 7px}.tribe_events_active_filter_type_options{margin:10px 0}.tribe_events_active_filter_type_options label{margin:7px 0}#event_organizer td small,.OrganizerInfo td small{display:block;margin:0;max-width:250px}#event_organizer .organizer-email,.OrganizerInfo .organizer-email{vertical-align:top}.tribe-table-field-label{max-width:100%;width:200px}#tribe-help-general,#tribe-help-sidebar{float:left;margin-top:20px}#tribe-help-general p{margin-left:15px}#tribe-help-general ul{list-style-type:square}#tribe-help-general ol,#tribe-help-general ul{margin-bottom:20px;margin-left:35px}#tribe-help-general h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}#tribe-help-general h3~h3{margin-top:2.25em}#tribe-help-general h3+p{margin:0 0 20px;padding-left:12px}#tribe-help-general{width:65%}.tribe-help-section{padding-bottom:10px}.tribe-section-type-box{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;padding:8px 20px 12px}.tribe-section-type-box img{height:auto;margin:10px 0;max-width:300px}.tribe-section-type-box ul{list-style:disc;margin-left:20px}.tribe-section-type-box ul ul{list-style:circle}#tribe-log-controls{padding-bottom:1rem;padding-left:12px}#tribe-log-controls>div{display:inline-block;padding-right:1rem}#tribe-log-controls .working{opacity:1;transition:opacity .2s}#tribe-log-controls .working.hidden{opacity:0;transition:opacity .2s}#tribe-log-viewer,#tribe-system-info dl.support-stats,.template-updates-wrapper{background:#000;border-radius:2px;color:#888;max-height:400px;overflow:scroll;padding:10px}#tribe-system-info dl.support-stats dt,.template-updates-wrapper dt{clear:both;float:left;font-weight:700;text-transform:uppercase;width:25%}#tribe-system-info dl.support-stats dd,.template-updates-wrapper dd{margin-left:25%;padding-left:10px}.system-info-copy .system-info-copy-btn{padding:6px}.system-info-copy .system-info-copy-btn .dashicons{padding-right:10px}.template-updates-wrapper p{margin-top:0}#tribe-help-sidebar{margin:20px 0 0 3%;max-width:225px;width:32%}.tribe-help-plugin-info{border:1px solid #ccc;padding:0 12px 12px}.tribe-help-plugin-info dd,.tribe-help-plugin-info dt{display:inline;margin:0}.tribe-help-plugin-info dt{font-weight:700}.tribe-help-plugin-info dd:after{content:"";display:block;height:.4em}.tribe-help-plugin-info dd:last-child:after{height:0}.tribe-help-plugin-info+.tribe-help-plugin-info{margin-top:20px}.tribe-help-plugin-info>div{line-height:2em}.tribe-help-plugin-info .star-rating{display:inline-block;margin-left:3px;position:relative;top:-2px}.tribe-help-plugin-info .tribe-list-addons{color:#21a6cb;font-size:24px;list-style:circle inside;margin-bottom:10px;margin-top:10px;padding-left:4px}.tribe-help-plugin-info .tribe-list-addons a{font-size:13px;left:-5px;position:relative;top:-5px}.tribe-help-plugin-info .tribe-list-addons .tribe-active-addon{list-style:disc inside}.ui-widget-overlay{background:#666;filter:alpha(opacity=50);opacity:.5}.ui-widget-shadow{background:#000;border-radius:5px;filter:alpha(opacity=20);margin:-5px 0 0 -5px;opacity:.2;padding:5px}.ui-resizable{position:relative}.ui-resizable-handle{display:block;font-size:.1px;position:absolute;z-index:99999}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;left:0;top:-5px;width:100%}.ui-resizable-s{bottom:-5px;cursor:s-resize;height:7px;left:0;width:100%}.ui-resizable-e{cursor:e-resize;height:100%;right:-5px;top:0;width:7px}.ui-resizable-w{cursor:w-resize;height:100%;left:-5px;top:0;width:7px}.ui-resizable-se{bottom:1px;cursor:se-resize;height:12px;right:1px;width:12px}.ui-resizable-sw{bottom:-5px;cursor:sw-resize;height:9px;left:-5px;width:9px}.ui-resizable-nw{cursor:nw-resize;height:9px;left:-5px;top:-5px;width:9px}.ui-resizable-ne{cursor:ne-resize;height:9px;right:-5px;top:-5px;width:9px}.ui-dialog{padding:.2em;position:relative;width:375px}.ui-dialog .ui-dialog-titlebar{padding:.5em .3em .3em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0 .2em}.ui-dialog .ui-dialog-titlebar-close{height:18px;margin:-10px 0 0;padding:1px;position:absolute;right:.3em;top:50%;width:19px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin-left:-8px;margin-top:-8px}.ui-dialog .ui-dialog-titlebar-close:focus,.ui-dialog .ui-dialog-titlebar-close:hover{padding:0}.ui-dialog .ui-dialog-content{background:none;border:0;overflow:auto;padding:.5em 1em;zoom:1}.ui-dialog .ui-dialog-buttonpane{background-image:none;border-width:1px 0 0;margin:.5em 0 0;padding:.3em 1em .5em!important;text-align:right}.ui-dialog .ui-dialog-buttonpane button{cursor:pointer;line-height:1.4em;margin:.5em .4em!important;overflow:visible;padding:.2em .6em .3em;text-shadow:none;width:auto}.ui-dialog .ui-resizable-se{bottom:3px;height:14px;right:3px;width:14px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:none!important;text-align:center}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button .ui-button-text{display:block;line-height:1.4}#ui-datepicker-div{display:none}#tribe-loading{background:#fff;background:hsla(0,0%,100%,.8);display:none;height:100%;left:0;position:absolute;top:0;transition:all 1s linear;width:100%;z-index:4}#tribe-loading span{background:url(../images/tribe-loading.gif) 0 0 no-repeat;background-size:32px 32px;height:32px;left:50%;margin:-16px 0 0 -16px;position:absolute;top:50%;width:32px}.tribe_update_page{max-width:850px}.tribe-half-column{float:left;margin-bottom:30px;margin-right:5%;width:45%}.tribe-row:after,.tribe-row:before{content:"";display:table}.tribe-row,.tribe-row:after{clear:both}.tribe-row .tribe-half-column:last-child{margin-right:0;width:50%}.tribe_update_page h2{font-size:30px;line-height:1.2;margin-bottom:20px}.tribe_update_page h3{font-size:24px;font-weight:400;line-height:24px;margin-top:0}.tribe_update_page h4{font-size:18px;font-weight:600;line-height:18px;margin:0}.tribe_update_page p{font-size:15px}p.tribe-update-message{font-size:18px;font-weight:400}.tribe_update_page h4:before{content:"\f145";font-family:dashicons;font-size:34px;line-height:1;margin-right:5px;position:relative;top:5px}a.tribe-rating-link{text-decoration:none}.tribe-update-links{margin-top:30px}.tribe_update_page li:before{content:"\2022";padding-right:3px}.tribe_update_page .rss-widget{margin:1em 0}.tribe_update_page a.rsswidget{font-size:14px;font-weight:400;line-height:1}.tribe_update_page .rss-widget li:before{display:none}.tribe-events-widget-admin-form__input-section p{margin:0}.tribe-events-widget-admin-form__input-section h4{margin:.5em 0}.tribe-update-bar{display:inline-block}.tribe-update-bar .progress{border:1px solid #ccc;float:left;margin-right:1rem;padding:1px;width:18rem}.tribe-update-bar .progress .bar{background:#7ad03a;height:1rem;width:1%}#tribe-dialog-wrapper>div{padding:1rem}#tribe-dialog-wrapper>div .stage{display:none}#tribe-dialog-wrapper #heading{background:#fff}#tribe-dialog-wrapper label{display:block}#tribe-dialog-wrapper .select-single-container{border:1px solid #888;height:300px;overflow-y:scroll}#tribe-dialog-wrapper .select-single-container label{opacity:1;padding:3px 5px;transition:opacity .2s}#tribe-dialog-wrapper .select-single-container label:nth-child(odd){background:#fff}#tribe-dialog-wrapper .select-single-container label.selected{background:#0073aa;color:#fff;font-weight:700}#tribe-dialog-wrapper .select-single-container label input{display:none}#tribe-dialog-wrapper .select-single-container.updating label{opacity:.35;transition:opacity .2s}.ui-front{z-index:1000000}.wp-list-table.plugins .column-description .update-message{color:#d54e21}.api-check{min-height:100px;padding:1em}.api-check+.notice-dismiss:hover:before{color:#fff}.api-check:after,.api-check:before{content:"";display:table}.api-check:after{clear:both}.api-check .tribe-mascot{bottom:0;display:none;padding:0 1rem 0 0;position:absolute;right:0;top:0}.api-check .tribe-mascot img{display:inline-block;height:100%;max-height:150px;max-width:150px;vertical-align:middle;width:auto}.api-check p{line-height:1.7;margin-bottom:1em}.api-check a{text-decoration:none}.api-check a:hover{text-decoration:underline}.api-check .plugin-list{display:inline;font-weight:600;margin:0;padding:0}.api-check .plugin-list span.plugin-invalid:after{content:", "}.api-check .plugin-list span.plugin-invalid:last-of-type:after{content:""}.tribe-marketing-notice{padding:1em}.tribe-marketing-notice+.notice-dismiss:hover:before{color:#fff}.tribe-marketing-notice:after,.tribe-marketing-notice:before{content:"";display:table}.tribe-marketing-notice:after{clear:both}.tribe-marketing-notice .tribe-marketing-notice__icon{display:none;flex-shrink:0;padding:0;position:static}.tribe-marketing-notice .tribe-marketing-notice__icon img{display:inline-block;max-height:100%;max-width:none;vertical-align:middle;width:100%}.tribe-marketing-notice h3{margin-bottom:.5em;margin-top:.5em}.tribe-marketing-notice p{line-height:1.7;margin-bottom:.5em}.tribe-marketing-notice a{text-decoration:none}.tribe-marketing-notice a:hover{text-decoration:underline}#wpcontent .notice-tribe-banner{align-items:center;background:#161b7d;border:0;box-shadow:none;display:flex;justify-content:flex-start;margin:0 0 16px;padding-right:0}.notice-tribe-banner .tribe-marketing-notice__icon{width:47px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:0;padding:1em 0}.notice-tribe-banner h3{color:#fff;display:block;font-size:.875rem;line-height:1.25;margin:0 0 .25rem}.notice-tribe-banner a{border-bottom:1px solid #fff;line-height:1.25;margin:0;text-decoration:none}.notice-tribe-banner a:hover{text-decoration:none}.notice-tribe-banner a,.notice-tribe-banner p{color:#fff;display:inline-block;font-size:.875rem;line-height:1.25}.notice-tribe-banner p{display:inline-block;margin:0;padding:0}.notice-tribe-banner .tribe-marketing-notice{align-items:center;display:flex;justify-content:flex-start;margin:0 auto;min-height:65px;padding:0 .75rem;width:100%}.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe-welcome .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:100%}.notice-tribe-banner .notice-dismiss{position:static}.notice-tribe-banner .notice-dismiss:before{color:#eaf1ff}.tribe-dropdown,.tribe-ea-dropdown{max-width:100%;width:auto}.tribe-dropdown.select2-container .selection,.tribe-ea-dropdown.select2-container .selection{margin-top:inherit}.tribe-dropdown .select2-selection--single,.tribe-ea-dropdown .select2-selection--single{height:32px}.tribe-dropdown .select2-selection--single .select2-selection__clear,.tribe-ea-dropdown .select2-selection--single .select2-selection__clear{line-height:28px}.tribe-dropdown .select2-selection--single .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--single .select2-selection__rendered{line-height:32px;padding-right:28px}.tribe-dropdown.select2-container--focus .select2-selection--single,.tribe-ea-dropdown.select2-container--focus .select2-selection--single{border-color:#5897fb;box-shadow:0 0 5px rgba(0,0,0,.1)}.tribe-dropdown.select2-container--open .select2-search__field,.tribe-ea-dropdown.select2-container--open .select2-search__field{padding:0}.tribe-dropdown.select2-container--open .select2-dropdown--below,.tribe-ea-dropdown.select2-container--open .select2-dropdown--below{border-top:1px solid #aaa;margin-top:-1px}.tribe-dropdown.select2-container--open .select2-dropdown--above,.tribe-ea-dropdown.select2-container--open .select2-dropdown--above{border-bottom:1px solid #aaa;margin-bottom:-16px}.tribe-dropdown.select2-container--open .select2-selection--single,.tribe-ea-dropdown.select2-container--open .select2-selection--single{border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:#aaa}.tribe-dropdown.select2-container--open .select2-selection__arrow b,.tribe-ea-dropdown.select2-container--open .select2-selection__arrow b{transform:rotate(180deg)}.tribe-dropdown.select2-selection--single,.tribe-ea-dropdown.select2-selection--single{background-image:none;border:1px solid #ccc;border-radius:3px;overflow:hidden}.tribe-dropdown.select2-selection--single>.select2-selection__rendered,.tribe-ea-dropdown.select2-selection--single>.select2-selection__rendered{white-space:normal}.tribe-dropdown.select2-selection--single .select2-selection__arrow,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow{background:transparent;background-image:none;border-left:0;top:2px;width:26px}.tribe-dropdown.select2-selection--single .select2-selection__arrow b,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow b{background:#fff url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E") no-repeat right 5px top 55%;background-size:auto;background-size:16px 16px;border:0;bottom:0;display:block;height:auto;left:0;margin:0;padding:0;right:0;top:0;width:auto}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered{background-image:none;border:1px solid #ccc;border-radius:3px;min-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline{line-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input{padding-bottom:0;padding-top:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice{line-height:19px;margin-top:2px;padding-bottom:0;padding-top:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div{line-height:inherit}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove{left:4px;top:3px;transition-property:border,color}.select2-results .select2-results__option{color:#939393;font-weight:400;margin-bottom:0}.select2-results .select2-results__option[aria-disabled=true]{background-color:#e0e0e0}.select2-results.select2-results__option--highlighted{background-color:#efefef;color:#a1a1a1;cursor:default;display:block}.wp-core-ui .button-red{background-color:#a00;border-color:#9b2124;box-shadow:inset 0 1px 0 rgba(120,200,230,.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red.hover,.wp-core-ui .button-red:focus,.wp-core-ui .button-red:hover{background-color:#a00;border-color:#7f1c1f;box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.3)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red:focus{border-color:#500f0e;box-shadow:inset 0 1px 0 rgba(120,200,230,.6),1px 1px 2px rgba(0,0,0,.4)}.wp-core-ui .button-red.active,.wp-core-ui .button-red.active:focus,.wp-core-ui .button-red.active:hover,.wp-core-ui .button-red:active{background:#7f1c1f;border-color:#601312 #ae2426 #ae2426;box-shadow:inset 0 1px 0 rgba(0,0,0,.1);color:hsla(0,0%,100%,.95);text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red-disabled,.wp-core-ui .button-red:disabled,.wp-core-ui .button-red[disabled]{background:#ba292b!important;border-color:#7f1c1f!important;box-shadow:none!important;color:#e79496!important;cursor:default;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important}.ticket_form .select2-container .select2-selection--single .select2-selection__arrow{display:none}.clear{zoom:1}.clear:after,.clear:before{content:" ";display:table}.clear:after{clear:both}.checkmark:after{border:solid #0ab152;border-width:0 3px 3px 0;content:"";display:block;height:15px;transform:rotate(45deg);width:8px}.checkmark.checkmark-right:after{float:right;margin-right:2em}.checkmark.checkmark-left:after{float:left;margin-left:2em}.checkmark.no-checkmark:after{display:none}.complete,.ok,.on,.yes,[data-status=complete],[data-status=ok],[data-status=on],[data-status=yes]{color:#0ab152}.incomplete,.ko,.no,.off,[data-status=incomplete],[data-status=ko],[data-status=no],[data-status=off]{color:#ff2500}.plugin-card-event-tickets-plus .column-downloaded,.plugin-card-event-tickets-plus .column-rating,.plugin-card-event-tickets-plus .column-updated,.plugin-card-event-tickets .column-downloaded,.plugin-card-event-tickets .column-rating,.plugin-card-event-tickets .column-updated,.plugin-card-events-calendar-pro .column-downloaded,.plugin-card-events-calendar-pro .column-rating,.plugin-card-events-calendar-pro .column-updated,.plugin-card-events-community-tickets .column-downloaded,.plugin-card-events-community-tickets .column-rating,.plugin-card-events-community-tickets .column-updated,.plugin-card-events-community .column-downloaded,.plugin-card-events-community .column-rating,.plugin-card-events-community .column-updated,.plugin-card-image-widget-plus .column-downloaded,.plugin-card-image-widget-plus .column-rating,.plugin-card-image-widget-plus .column-updated,.plugin-card-image-widget .column-downloaded,.plugin-card-image-widget .column-rating,.plugin-card-image-widget .column-updated,.plugin-card-the-events-calendar .column-downloaded,.plugin-card-the-events-calendar .column-rating,.plugin-card-the-events-calendar .column-updated,.plugin-card-tribe-eventbrite .column-downloaded,.plugin-card-tribe-eventbrite .column-rating,.plugin-card-tribe-eventbrite .column-updated,.plugin-card-tribe-filterbar .column-downloaded,.plugin-card-tribe-filterbar .column-rating,.plugin-card-tribe-filterbar .column-updated{display:none}body.tribe-welcome,body.tribe_events_page_tribe-help{background-color:#fff;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body.tribe-welcome .update-nag,body.tribe_events_page_tribe-help .update-nag{display:none}body.tribe-welcome #wpcontent,body.tribe_events_page_tribe-help #wpcontent{padding:0}body.tribe-welcome .tribe_settings,body.tribe_events_page_tribe-help .tribe_settings{margin:0}body.tribe-welcome #wpfooter,body.tribe-welcome .tribe_settings>h1,body.tribe_events_page_tribe-help #wpfooter,body.tribe_events_page_tribe-help .tribe_settings>h1{display:none}body.tribe-welcome #wpbody-content,body.tribe_events_page_tribe-help #wpbody-content{padding-bottom:25px}body.tribe-welcome .tribe-dependency-error,body.tribe_events_page_tribe-help .tribe-dependency-error{display:none}.tribe-events-admin-content-wrapper{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-style:normal;margin:0 auto;padding:0 0 30px;width:calc(100% - 40px)}.tribe-events-admin-card{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;display:block;margin:0 auto 36px;padding:27px;text-align:center}.tribe-events-admin-card--2up .tribe-events-admin-card__title{max-width:260px}.tribe-events-admin-card--3up .tribe-events-admin-card__description{height:71px}.tribe-events-admin-card--3up .tribe-events-admin-card__image{margin-bottom:28px}.tribe-events-admin-card__button{background-color:#fff;border:none;color:#3d54ff;font-size:14px;font-weight:700;letter-spacing:1px;line-height:16px;position:absolute;right:20px;text-transform:uppercase;top:17px}.tribe-events-admin-card__button:hover{color:#161b7d}.tribe-events-admin-card__description{color:#000;font-size:14px;font-style:normal;font-weight:400;line-height:22px;margin-top:16px}.tribe-events-admin-card__image{display:block;height:100px;margin:0 auto}.tribe-events-admin-card__link{color:#3d54ff;display:inline-block;font-size:16px;font-style:normal;font-weight:700;line-height:18px;margin-top:24px;position:relative;text-decoration:none}.tribe-events-admin-card__link:hover{color:#161b7d}.tribe-events-admin-card__link:after{border-style:solid;border-width:0 0 1px;bottom:-4px;content:"";left:0;position:absolute;width:100%}.tribe-events-admin-card__title{color:#0f1031;font-size:20px;font-weight:700;line-height:23px;margin:auto}.tribe-events-admin-card-grid{max-width:1048px}input[type=checkbox].tribe-common-switch__input{display:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label{background:#fff;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;cursor:pointer;display:block;height:18px;outline:0;padding:3px;position:relative;transition:all .2s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:27px}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:after,input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:before{content:"";display:block;height:10px;position:relative;width:10px}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:after{background:#878787;border-radius:2px;content:"";left:0;transition:all .2s ease}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label:before{display:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label::-moz-selection{background:none}input[type=checkbox].tribe-common-switch__input+.tribe-common-switch__label::selection{background:none}input[type=checkbox].tribe-common-switch__input:checked+.tribe-common-switch__label:after{background:#2e709d;left:50%}.tribe-events-admin-header__logo-word-mark{display:inline-block;height:auto;margin:0 0 26px;vertical-align:middle;width:312px}.tribe-events-admin-header{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;padding:45px 0 0}.tribe-events-admin-header__right-image{height:280px;position:absolute;right:0;top:0;width:auto;z-index:-1}.tribe-events-admin-header__title{font-size:48px;line-height:48px;margin:0 0 18px}.tribe-events-admin-header__description{font-size:18px;line-height:28px;margin-bottom:44px;max-width:60%}.tribe-events-admin-tab-nav{display:flex;margin:0}.tribe-events-admin-tab-nav li{cursor:pointer;font-size:16px;font-weight:500;margin-bottom:0;margin-right:30px}.tribe-events-admin-tab-nav li:hover{color:#334aff}.tribe-events-admin-tab-nav .selected{border-bottom:3px solid #334aff;color:#334aff;padding-bottom:17px}.tribe-events-admin-tab-nav li:after{background:#334aff;border-radius:100px;bottom:0;content:"";display:block;height:3px;left:0;position:absolute;right:0}.tribe-events-admin__line{border-top:1px solid #e1e1e4}.tribe-events-admin-products-description{color:#0f1031;font-size:14px;line-height:2}.tribe-events-admin-products-card{align-items:center;border:1px solid #e1e1e4;border-radius:20px;display:flex;padding:10px 15px}.tribe-events-admin-products-card__icon{height:40px;-o-object-fit:contain;object-fit:contain;width:40px}.tribe-events-admin-products-card__group{margin:0 20px;max-width:55%}.tribe-events-admin-products-card__group-title{color:#0f1031;font-size:16px;font-weight:700;line-height:1;margin:0}.tribe-events-admin-products-card__group-description{font-size:12px;margin-top:5px}.tribe-events-admin-products-card__button{background-color:#fff;border:1px solid #e1e1e4;border-radius:20px;color:#0f1031;font-size:12px;font-weight:700;letter-spacing:1px;line-height:16px;margin-left:auto;padding:10px 15px;text-decoration:none;text-transform:uppercase}.tribe-events-admin-products-card__button:hover{background-color:#334aff;color:#fff}.tribe-events-admin-products-card__button:active,.tribe-events-admin-products-card__button:focus{box-shadow:none;outline:none}.tribe-events-admin-products-card__button--active,.tribe-events-admin-products-card__button--active:active,.tribe-events-admin-products-card__button--active:focus,.tribe-events-admin-products-card__button--active:hover{background:rgba(61,84,255,.16);color:#334aff;cursor:not-allowed;text-transform:uppercase}.tribe-events-admin-card--1up{width:100%}.tribe-events-admin-card--no-pad{padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__image{display:block;height:152px;margin:0;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{font-size:28px;line-height:34px;text-align:left}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin:0;padding:0;text-align:left}.tribe-events-admin-card--no-pad .tribe-events-admin-card__link{margin:0;padding:0}.tribe-events-admin-card--faq{display:inline-block;font-size:0;height:147px;margin:0 0 0 30px;padding:24px 16px 22px 20px;width:230px}.tribe-events-admin-card--faq:first-child{margin-left:0}.tribe-events-admin-card--faq img{float:left;height:22px;width:16px}.tribe-events-admin-card--faq .tribe-events-admin-faq__question{color:#334aff;font-size:16px;line-height:19px;margin:0 0 12px 26px;text-align:left}.tribe-events-admin-card--faq .tribe-events-admin-faq__answer{font-size:13px;line-height:16px;margin-left:26px;text-align:left}.tribe-events-admin-video{border-radius:16px;height:200px;margin-bottom:72px;-webkit-mask-image:-webkit-radial-gradient(circle,#fff 100%,#000 0);overflow:hidden;-webkit-transform:rotate(.000001deg)}.tribe-events-admin-video iframe{width:100%}.tribe-events-admin-card--promo-blue{background-color:#3d54ff;background-image:url(../images/welcome/promo.jpg)}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{color:#fff;font-size:16px;margin-bottom:16px;text-align:left}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__title{color:#fff;text-align:left}.tribe-events-admin-graphic{position:absolute;right:0;top:106px;z-index:-1}.tribe-events-admin-graphic--desktop-only{display:none}.tribe-events-admin-graphic--mobile-only{display:block}.tribe-events-admin-card__form{position:relative}input[type=email].tribe-events-admin-card__input{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;font-size:14px;height:54px}input[type=email].tribe-events-admin-card__input:-ms-input-placeholder{color:rgba(15,16,49,.72);letter-spacing:.5px;padding-left:10px}input[type=email].tribe-events-admin-card__input::placeholder{color:rgba(15,16,49,.72);letter-spacing:.5px;padding-left:10px}.tribe-events-admin-container,.tribe-events-admin-content-wrapper.tribe-events-admin-container{margin:0 auto;max-width:1024px;width:90%}.tribe-events-admin-2col-grid{display:grid;grid-gap:15px 30px;gap:15px 30px;grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-3col-grid{display:grid;grid-gap:30px;gap:30px;grid-template-areas:". . .";grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-4col-grid{display:grid;grid-gap:30px;gap:30px;grid-template-areas:". . . .";grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:1fr}.tribe-events-admin-products{margin:10px 0 0}.tribe-events-admin-quick-nav{background:#fff;border:1px solid #e1e1e4;border-radius:16px;box-sizing:border-box;display:block;margin:40px 0 78px;padding:18px 23px 2px}.tribe-events-admin-quick-nav__link{color:#3d54ff;font-size:16px;font-weight:700;line-height:18px;text-align:center;text-decoration:none}.tribe-events-admin-quick-nav__link:hover{color:#161b7d}.tribe-events-admin-quick-nav__link-item{display:block;padding-bottom:19px}.tribe-events-admin-quick-nav__links{display:inline}.tribe-events-admin-quick-nav__title{color:rgba(15,16,49,.72);display:inline-block;font-size:14px;font-weight:400;line-height:16px;padding-bottom:14px;text-transform:uppercase}.tribe-events-admin-title{padding-top:14px}.tribe-events-admin-title__description{color:#0f1031;font-size:16px;font-weight:400;line-height:24px;max-width:584px;padding-top:15px}.tribe-events-admin-title__heading{color:#0f1031;display:inline-block;font-size:24px;font-weight:700;line-height:28px;margin:5px 0 0}.tribe-events-admin-title__logo{margin-right:8px;vertical-align:top;width:34px}.tribe-events-admin-notice{background-color:#3d54ff;height:65px}.tribe-events-admin-notice .tribe-events-admin-content-wrapper{padding-bottom:0;padding-top:8px}.tribe-events-admin-notice p{color:#fff;display:inline-block;font-family:Helvetica,sans-serif;font-size:16px;line-height:18px;margin-top:0;padding-bottom:12px;padding-left:16px;vertical-align:middle;width:calc(100% - 60px)}.tribe-events-admin-notice__logo{display:inline-block}.tribe-events-admin-tickets .tribe-events-admin-section-header{font-size:28px;line-height:32px}.tribe-events-admin-tickets .tribe-events-admin-graphic--desktop-only{width:365px}.tribe-events-admin-tickets .tribe-events-admin-graphic--mobile-only{top:230px;width:300px}.tribe-events-admin-tickets .tribe-events-admin-title__heading{margin-top:0}.tribe-events-admin-tickets .tribe-events-admin-title__logo{margin-right:4px;width:32px}.tribe-events-admin-kb{margin:10px 0 0}.tribe-events-admin-kb-card{border:1px solid #e1e1e4;border-radius:20px}.tribe-events-admin-kb-card__image{height:auto;width:100%}.tribe-events-admin-kb-card__title{color:#0f1031;flex-grow:0;font-size:20px;font-weight:700;line-height:1.2;margin:0;padding:20px 28px 10px}.tribe-events-admin-kb-card__links{margin:0;padding:0 28px 25px}.tribe-events-admin-kb-card__links li{margin:0 0 10px}.tribe-events-admin-kb-card__links li a{color:#334aff;font-size:14px;line-height:1.2;text-decoration:none}.tribe-events-admin-kb-card__links li a:focus{box-shadow:none;outline:none}.tribe-events-admin-kb-card__links li a:hover{color:#1c39bb}.tribe-events-admin-section-header{align-items:center;color:#000;display:flex;font-weight:700;justify-content:space-between;margin:0}.tribe-events-admin-section-header h3{color:#0f1031;font-size:28px;font-weight:700;line-height:1}.tribe-events-admin-section-header a{border-bottom:2px solid #334aff;color:#334aff;font-size:14px;padding-bottom:2px;text-decoration:none}.tribe-events-admin-section-header a:focus{box-shadow:none;outline:none}.tribe-events-admin-section-header a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-faq{margin:10px 0 0}.tribe-events-admin-faq-card{border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;padding:24px 15px 19px 19px}.tribe-events-admin-faq-card a{color:#0f1031}.tribe-events-admin-faq-card a:focus{box-shadow:none;outline:none}.tribe-events-admin-faq-card a:hover{color:#1c39bb}.tribe-events-admin-faq-card__icon img{height:22px;width:16px}.tribe-events-admin-faq-card__content{margin-left:10px}.tribe-events-admin-faq__question,.tribe-events-admin-faq__question a{color:#334aff;font-size:16px;text-decoration:none}.tribe-events-admin-faq__question a:focus{box-shadow:none;outline:none}.tribe-events-admin-faq__question a:hover{color:#1c39bb}.tribe-events-admin-faq__answer{color:#0f1031;font-size:13px;margin-top:18px}.tribe-events-admin-extensions-title{color:#0f1031;font-size:16px;line-height:1.5;margin:0 0 30px;max-width:70%}.tribe-events-admin-extensions{margin:10px 0 0}.tribe-events-admin-extensions-card{border:1px solid #e1e1e4;border-radius:20px;border-top:8px solid #334aff;padding:48px 35px 24px 25px}.tribe-events-admin-extensions-card__title{font-size:20px;margin:0}.tribe-events-admin-extensions-card__title a{color:#0f1031;font-family:Helvetica,sans-serif;font-size:20px;font-weight:700;line-height:1.2;text-decoration:none}.tribe-events-admin-extensions-card__title a:active,.tribe-events-admin-extensions-card__title a:focus,.tribe-events-admin-extensions-card__title a:hover{box-shadow:none;color:#334aff}.tribe-events-admin-extensions-card__description{color:#0f1031;font-family:Helvetica,sans-serif;font-size:14px;line-height:1.43;margin:20px 0}.tribe-events-admin-cta{align-items:center;border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;margin:60px 0}.tribe-events-admin-cta__image{height:152px;-o-object-fit:contain;object-fit:contain;width:auto}.tribe-events-admin-cta__content,.tribe-events-admin__troubleshooting-cta{align-items:center;display:flex;flex-direction:column;justify-content:center;padding:20px 0;width:100%}.tribe-events-admin-cta__content-title{color:#0f1031;font-size:28px;font-weight:700;line-height:normal;margin:0 0 10px;text-align:center}.tribe-events-admin-cta__content-subtitle{color:#0f1031;font-size:16px;line-height:1.5;margin-bottom:10px;text-align:center}.tribe-events-admin-cta__content-description a{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;font-weight:700;padding-bottom:2px;text-decoration:none}.tribe-events-admin-cta__content-description a:focus{box-shadow:none;outline:none}.tribe-events-admin-cta__content-description a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-footer-logo{display:inline-block;vertical-align:middle;width:228px}.tribe-events-admin-step{margin:10px 0 0}.tribe-events-admin-step-card{border:1px solid #e1e1e4;border-radius:20px;display:flex;justify-content:space-between;padding:24px 15px 19px 19px}.tribe-events-admin-step-card a{border-bottom:2px solid #334aff;color:#334aff;padding-bottom:2px;text-decoration:none}.tribe-events-admin-step-card a:focus{box-shadow:none;outline:none}.tribe-events-admin-step-card a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin-step-card__icon img{height:43px;margin-right:5px;width:42px}.tribe-events-admin-step-card__content{margin-left:10px}.tribe-events-admin-step__title{color:#0f1031;font-size:20px;font-weight:700;line-height:1.2;margin-bottom:10px}.tribe-events-admin-step__answer{color:#0f1031;font-size:13px;margin-top:18px}.tribe-events-admin__system-information{display:grid;grid-gap:15px 30px;gap:15px 30px;grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:1fr;margin:100px 0;position:relative}.tribe-events-admin__troubleshooting-title{color:#0f1031;font-size:28px;font-weight:700;line-height:1;margin:0}.tribe-events-admin__troubleshooting-description{color:#0f1031;font-size:18px;line-height:1.2;line-height:1.44;margin:20px 0}.tribe-events-admin__system-information-select{display:flex;margin:30px 0 20px}.tribe-events-admin__system-information-select input[type=checkbox]{margin:0 10px 0 0}.tribe-events-admin__system-information-select label{color:#0f1031;font-size:16px;line-height:1.2}.tribe-events-admin__system-information-content small{color:#0f1031;font-size:12px;line-height:1.2}.tribe-events-admin__recent-template-changes .template-updates-wrapper,.tribe-events-admin__system-information-widget{background:#0f1031;border-radius:16px;color:#fff;font-size:14px;line-height:1.14;max-height:280px;overflow:scroll;-ms-overflow-style:none;padding:12px 0 0 27px;scrollbar-width:none}.tribe-events-admin__recent-template-changes .template-updates-wrapper p{color:#fff;font-size:14px;line-height:1.14;margin:0}.tribe-events-admin__system-information-widget a{color:#334aff}.tribe-events-admin__system-information-widget a:hover{opacity:.8}.tribe-events-admin__recent-template-changes .template-updates-wrapper{padding:30px 0 30px 27px}.tribe-events-admin__recent-template-changes .template-updates-wrapper::-webkit-scrollbar,.tribe-events-admin__system-information-widget::-webkit-scrollbar{display:none}.tribe-events-admin__system-information-widget-copy{bottom:10px;position:absolute}.tribe-events-admin__system-information-widget-copy button{background-color:#334aff;border:none;border-radius:100px;color:#fff;cursor:pointer;font-size:16px;font-weight:700;outline:none;padding:18px 25px;text-align:center}.tribe-events-admin__system-information-widget-copy button:hover{background-color:#1c39bb}.tribe-events-admin__system-information-widget-copy button .dashicons,.tribe-events-admin__system-information-widget-copy button .dashicons-before:before{display:none}.tribe-events-admin__system-information-widget-copy button .optin-success{color:#fff;font-size:16px;font-weight:700;text-align:center}.tribe-events-admin__recent-template-changes p{color:#0f1031;font-size:18px;line-height:1.2;line-height:1.44;margin:20px 0}.tribe-events-admin__recent-log{margin-top:50px}.tribe-events-admin__troubleshooting-event-log-wrapper label{color:#0f1031;display:block;font-size:16px;line-height:1.63;margin-bottom:10px}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-controls{margin:20px 0 10px}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-viewer{background:#0f1031;border-radius:16px;color:#fff;font-size:14px;line-height:1.14;max-height:280px;min-height:60px;overflow:scroll;-ms-overflow-style:none;padding:12px 0 0 27px;scrollbar-width:none}.tribe-events-admin__troubleshooting-event-log-wrapper #tribe-log-viewer::-webkit-scrollbar{display:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;padding-bottom:2px;text-decoration:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log:focus{box-shadow:none;outline:none}.tribe-events-admin__troubleshooting-event-log-wrapper .download_log:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__troubleshooting-event-log-wrapper .tribe-events-admin__recent-log-filters-select-wrapper:after{display:none}.tribe-events-admin__recent-log-filters{display:flex;padding:20px 0 40px}.tribe-events-admin__recent-log-filters-field{margin-right:40px}.tribe-events-admin__recent-log-filters-select-wrapper:after{content:url(../images/help/polygon.svg);height:13px;pointer-events:none;position:absolute;right:22px;top:20px;width:14px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default .select2-selection--single{border:1px solid #e1e1e4!important;border-radius:16px;color:#0f1031;font-size:14px;line-height:1.14;padding:0 25px 0 15px!important}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls{margin-bottom:20px;padding:0}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:first-child,.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(2),.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(3){padding-right:75px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-selection__clear{display:none}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default .select2-selection--single .select2-selection__arrow{right:5px}.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple,.tribe-events-admin__recent-log-filters-select-wrapper .select2-container--default.select2-container--open.select2-container--below .select2-selection--single{border-bottom-left-radius:16px;border-bottom-right-radius:16px}.tribe-events-admin__recent-log-filters-select-wrapper .select2-container .select2-selection--single .select2-selection__rendered{width:100%}.tribe-events-admin__recent-log-filters-select-wrapper select.focus-visible,.tribe-events-admin__recent-log-filters-select-wrapper select:focus-visible{outline:none}.tribe-events-admin__recent-log-filters-select-wrapper select option{color:#0f1031;font-size:14px;line-height:1.14}.tribe-events-admin__ea-status{margin-top:50px}.tribe-events-admin__issues-found-card{background-color:#f3eee8;border-radius:8px;margin-bottom:20px}.tribe-events-admin__issues-found-card:last-of-type{margin-bottom:100px}.tribe-events-admin__issues-found-card-title{align-items:center;cursor:pointer;display:flex;padding:10px 20px 10px 17px;position:relative}.tribe-events-admin__issues-found-card-title img{height:21px;margin-right:14px;-o-object-fit:contain;object-fit:contain;width:21px}.tribe-events-admin__issues-found-card-title h3{margin:0}.tribe-events-admin__issues-found-card-title span{color:#0f1031;display:block}.tribe-events-admin__issues-found-card-title i{background-image:url(../images/help/arrow-down.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;height:15px;margin:12px 20px;position:absolute;right:0;top:0;transition:all .3s ease;width:15px}.tribe-events-admin__issues-found-card-title.active i{background-image:url(../images/help/arrow-up.svg);background-repeat:no-repeat;top:5px}.tribe-events-admin__issues-found-card-description{display:none;padding:0 20px 20px 55px}.tribe-events-admin__issues-found-card-description p{color:#0f1031;font-size:16px;margin:0}.tribe-events-admin__issues-found-card-description-actions{display:flex;padding:20px 0 10px}.tribe-events-admin__issues-found-card-description-actions a{border-bottom:2px solid #334aff;color:#334aff;font-size:16px;margin-right:20px;padding-bottom:5px;text-decoration:none}.tribe-events-admin__issues-found-card-description-actions a:focus{box-shadow:none;outline:none}.tribe-events-admin__issues-found-card-description-actions a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__ea-status-table-wrapper{overflow-x:auto}.tribe-events-admin__ea-status-table{border:1px solid #e1e1e4;border-radius:16px;margin:30px 0 40px;overflow:hidden}.tribe-events-admin__ea-status-table a{border-bottom:2px solid #334aff;color:#334aff;padding-bottom:2px;text-decoration:none}.tribe-events-admin__ea-status-table a:focus{box-shadow:none;outline:none}.tribe-events-admin__ea-status-table a:hover{border-bottom:2px solid #1c39bb;color:#1c39bb}.tribe-events-admin__ea-status-table tr{align-items:center;display:flex}.tribe-events-admin__ea-status-table th{color:#0f1031;font-weight:700;line-height:1.17;margin-top:10px;padding:5px 25px}.tribe-events-admin__ea-status-table td{align-items:center;color:#0f1031;display:flex;font-size:16px;line-height:1.63;padding:10px 25px;width:25%}.tribe-events-admin__ea-status-table td:nth-child(2){width:45%}.tribe-events-admin__ea-status-table td:nth-child(3){display:flex;justify-content:flex-end;width:30%}.tribe-events-admin__ea-status-table-dark{background-color:#f9f7f4}.tribe-events-admin__ea-status-table td img{height:21px;margin-right:14px;-o-object-fit:contain;object-fit:contain;width:21px}.tribe_events_page_tec-troubleshooting{background-color:#fff}#tribe-community,#tribe-ticketing{display:none}.tribe-events-admin__troubleshooting-notice{background-color:#161b7d;color:#fff;font-size:16px;line-height:1;margin-left:-1.55vw;padding:24px 0}.tribe-events-admin__troubleshooting-notice_title{margin:0 auto;max-width:1024px;padding-left:25px;width:90%}.tribe-events-admin__troubleshooting-notice_title a{border-bottom:2px solid #fff;color:#fff;font-size:16px;line-height:1;padding-bottom:2px;text-decoration:none}.tribe-events-admin__troubleshooting-notice_title a:focus{box-shadow:none;outline:none}.tribe-events-admin__troubleshooting-notice_title a:hover{border-bottom:2px solid #f3eee8;color:#f3eee8}.tribe_events_page_tribe-help #tec-help-community,.tribe_events_page_tribe-help #tec-help-ticketing{display:none}.tribe_events_page_tribe-help .tribe-events-admin-title{padding-top:25px}.tribe_events_page_tribe-help .tribe-events-admin-title img{height:67px}body.tribe-welcome #fs_connect{border:1px solid #e1e1e4;border-radius:16px;box-shadow:none;box-sizing:border-box;margin-left:22px}body.tribe-welcome #fs_connect .fs-actions{background-color:transparent}body.tribe-welcome #fs_connect .fs-permissions{border-top:1px solid #e1e1e4;margin:0 16px}body.tribe-welcome #fs_connect button{background-color:#3d54ff;border-color:#3d54ff}body.tribe-welcome #fs_connect .button-secondary{background:#fff;border-color:#3d54ff;color:#3d54ff}body.tribe-welcome #fs_connect a{color:#3d54ff}body.tribe-welcome #fs_connect a:focus{box-shadow:none;outline:none}body.tribe-welcome #fs_connect a:hover{color:#161b7d}.black-friday-promo{align-items:flex-start;display:flex;flex-direction:column-reverse;justify-content:space-between}.black-friday-promo .black-friday-promo__button{background:#3d54ff;border-color:transparent;border-radius:20px;color:#fff;font-size:12px;height:34px;line-height:32px;min-height:unset;width:115px}.black-friday-promo .black-friday-promo__button:active,.black-friday-promo .black-friday-promo__button:focus,.black-friday-promo .black-friday-promo__button:hover{background:#1c39bb;border-color:transparent;color:#fff}.black-friday-promo__promo{background-position:50%;background-repeat:no-repeat;border-radius:10px;display:grid;grid-template-areas:"a b";grid-template-columns:auto 150px;height:150px;margin:10px 0;max-width:100%;width:450px}.black-friday-promo__content{grid-area:b;padding-top:8px;text-align:center}.black-friday-promo__text{color:#0f1031;font-family:monospace;font-size:16px;line-height:1;text-transform:uppercase}.black-friday-promo__branding-image{max-width:390px;width:100%}@media only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min--moz-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){#tribe-loading span{background-image:url(../images/tribe-loading@2x.gif)}}@media screen and (max-width:782px){.tribe-half-column,.tribe-row .tribe-half-column:last-child{margin:0 0 20px;width:100%}input[type=email]{width:100%}.events-cal .subsubsub{float:none}.events-cal .search-box{width:98%}.events-cal #search-submit{width:100%}.events-cal .tablenav.top{display:none}}@media screen and (min-width:500px){.api-check .tribe-mascot{display:block}.api-check .notice-content{margin-right:180px}}@media screen and (min-width:320px){.tribe-marketing-notice .tribe-marketing-notice__icon{display:block}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px}}@media screen and (min-width:600px) and (max-width:782px){.tribe-marketing-notice .tribe-marketing-notice__content{margin-left:145px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px;padding:0}}@media screen and (min-width:782px){.tribe-marketing-notice .tribe-marketing-notice__content{margin-left:130px}.notice-tribe-banner .tribe-marketing-notice__content{margin-left:22px;padding:0}.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe-welcome .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:642px}}@media screen and (min-width:400px){.notice-tribe-banner .tribe-marketing-notice__icon{width:67px}}@media screen and (min-width:800px){.notice-tribe-banner h3{display:inline-block;font-size:1rem;margin:0 .5rem 0 0}.notice-tribe-banner a{line-height:1.5}.notice-tribe-banner a,.notice-tribe-banner p{font-size:1rem}.notice-tribe-banner p{margin:0 .5rem 0 0}.notice-tribe-banner .tribe-marketing-notice__cta{display:inline-block;margin-left:.5rem}}@media screen and (min-width:1215px){.events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice,.tribe_events_page_tribe-app-shop .notice-tribe-banner .tribe-marketing-notice{max-width:992px}.tribe-welcome .notice-tribe-banner .tribe-marketing-notice{max-width:1036px}}@media screen and (min-width:710px){.tribe-events-admin-content-wrapper{width:670px}.tribe-events-admin-card--2up{display:inline-block;width:calc(50% - 20px)}.tribe-events-admin-card--2up.tribe-events-admin-card--first{margin-right:36px}.tribe-events-admin-card--2up.tribe-events-admin-card--last{margin-right:0}.tribe-events-admin-card--2up .tribe-events-admin-card__image{height:100px;margin-bottom:12px}.tribe-events-admin-card--2up .tribe-events-admin-card__title{margin-bottom:27px;max-width:340px}.tribe-events-admin-card--3up{display:inline-block;margin-bottom:32px;width:calc(50% - 18px)}.tribe-events-admin-card--3up.tribe-events-admin-card--first{margin-right:32px}.tribe-events-admin-card--3up.tribe-events-admin-card--middle{margin-right:0}.tribe-events-admin-card__title{font-size:20px;line-height:23px}.tribe-events-admin-card--1up{display:inline-block;margin-left:32px;width:calc(50% - 18px)}.tribe-events-admin-card--1up .tribe-events-admin-card__description{height:71px}.tribe-events-admin-card--1up .tribe-events-admin-card__image{margin-bottom:28px}.tribe-events-admin-card--no-pad{height:154px;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{margin-left:50%;padding:42px 0 10px}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin-left:50%}.tribe-events-admin-card--promo-blue{display:block;margin-left:0;min-height:170px;width:100%}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{float:left;max-width:300px}.tribe-events-admin-graphic{max-width:250px;top:0}.tribe-events-admin-graphic--desktop-only{display:block}.tribe-events-admin-graphic--mobile-only{display:none}.tribe-events-admin-card__form{float:right;width:300px}input[type=email].tribe-events-admin-card__input{width:300px}.tribe-events-admin-title{padding-top:50px}.tribe-events-admin-title__description{padding-top:15px}.tribe-events-admin-title__heading{font-size:48px;line-height:55px;margin:0}.tribe-events-admin-title__logo{margin-right:14px;padding-top:5px;width:40px}.tribe-events-admin-tickets .tribe-events-admin-card__title{font-size:18px}.tribe-events-admin-tickets .tribe-events-admin-card--2up .tribe-events-admin-card__title{font-size:18px;height:66px}.tribe-events-admin-tickets .tribe-events-admin-title__logo{margin-right:8px;padding-top:4px;width:60px}}@media screen and (min-width:1217px){.tribe-events-admin-content-wrapper{max-width:1060px;width:100%}.tribe-events-admin-card--2up{margin-right:36px;width:486px}.tribe-events-admin-card--3up{width:310px}.tribe-events-admin-card--3up.tribe-events-admin-card--first,.tribe-events-admin-card--3up.tribe-events-admin-card--middle{margin-right:36px}.tribe-events-admin-card--3up.tribe-events-admin-card--last{margin-right:0}.tribe-events-admin-card--1up{margin:0 0 36px;padding:33px 44px 30px;text-align:left;width:1012px}.tribe-events-admin-card--1up .tribe-events-admin-card__description{height:auto}.tribe-events-admin-card--1up .tribe-events-admin-card__image{float:left;margin:0 48px 10px 0}.tribe-events-admin-card--no-pad{padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__image{margin:0;padding:0}.tribe-events-admin-card--no-pad .tribe-events-admin-card__title{margin-left:50%;padding:42px 0 10px}.tribe-events-admin-card--no-pad .tribe-events-admin-card__description{margin-left:50%}.tribe-events-admin-card--promo-blue{min-height:150px}.tribe-events-admin-card--promo-blue .tribe-events-admin-card__description{max-width:450px}.tribe-events-admin-graphic{max-width:none}.tribe-events-admin-card__form,input[type=email].tribe-events-admin-card__input{width:365px}.tribe-events-admin-quick-nav{border-radius:100px;display:inline-block;height:54px;margin:24px 0 94px;max-width:1010px;padding:0 36px 0 0}.tribe-events-admin-quick-nav__link-item{display:inline-block;padding:18px 10px 0}.tribe-events-admin-quick-nav__title{padding:19px 6px 17px 32px}.tribe-events-admin-tickets .tribe-events-admin-card--2up .tribe-events-admin-card__title{height:auto}}@media screen and (max-width:768px){.tribe-events-admin-header__logo-word-mark{width:285px}.tribe-events-admin-header__right-image{height:160px}.tribe-events-admin-header__description{max-width:100%}.tribe-events-admin-tab-nav li{margin-right:20px}.tribe-events-admin-tab-nav .selected{border-bottom:2px solid #334aff;padding-bottom:10px}.tribe-events-admin-2col-grid{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr))}.tribe-events-admin-3col-grid{grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr))}.tribe-events-admin-extensions-title{max-width:100%}.tribe-events-admin-cta{align-items:flex-start;flex-direction:column;overflow:hidden}.tribe-events-admin-footer-logo{width:225px}.tribe-events-admin__system-information{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr));margin:50px 0}}@media screen and (max-width:480px){.tribe-events-admin-header__logo-word-mark{width:260px}.tribe-events-admin-header__right-image{height:120px}.tribe-events-admin-header__title{font-size:35px}.tribe-events-admin-header__description{max-width:100%}.tribe-events-admin-tab-nav{border:1px solid #e1e1e4;border-radius:20px;flex-direction:column;padding:18px 22px}.tribe-events-admin-tab-nav li{margin-bottom:18px;margin-right:0}.tribe-events-admin-tab-nav .selected{border-bottom:2px solid #334aff;padding-bottom:10px;width:-moz-fit-content;width:fit-content}.tribe-events-admin__line{border:none}.tribe-events-admin-products-card,.tribe-events-admin-products-description{display:none}.tribe-events-admin-container,.tribe-events-admin-content-wrapper.tribe-events-admin-container{max-width:90%}.tribe-events-admin-2col-grid,.tribe-events-admin-3col-grid,.tribe-events-admin-4col-grid{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr))}.tribe-events-admin-extensions-title{max-width:100%}.tribe-events-admin-cta__image{height:auto;width:90%}.tribe-events-admin-cta__content,.tribe-events-admin__troubleshooting-cta{align-items:flex-start;padding:32px 23px 45px;width:auto}.tribe-events-admin-cta__content-title{font-size:22px;text-align:left}.tribe-events-admin-cta__content-subtitle{text-align:left}.tribe-events-admin-footer-logo{width:210px}.tribe-events-admin__system-information{grid-template-areas:".";grid-template-columns:repeat(1,minmax(0,1fr));margin:50px 0}.tribe-events-admin__troubleshooting-notice{margin-left:-20px}.tribe-events-admin__troubleshooting-notice_title{max-width:90%}}@media screen and (min-width:1200px){.tribe-events-admin-products-card__group{max-width:47%}}@media screen and (min-width:500px) and (max-width:1080px){.tribe-events-admin-4col-grid{grid-template-areas:". .";grid-template-columns:repeat(2,minmax(0,1fr))}}@media screen and (min-width:768px){.tribe-events-admin-section-header{font-size:28px;line-height:1.143;margin:50px 0 21px}}@media screen and (max-width:1080px){.tribe-events-admin-cta__content-title{font-size:24px}}@media only screen and (max-width:1920px){.tribe-events-admin__system-information-widget-copy{right:20.5vw}}@media only screen and (max-width:1280px){.tribe-events-admin__system-information-widget-copy{right:22vw}}@media only screen and (max-width:768px){.tribe-events-admin__system-information-widget-copy{left:10px;right:auto}.tribe-events-admin__recent-log-filters{flex-direction:column}.tribe-events-admin__recent-log-filters-field{margin-bottom:30px;margin-right:0}.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:first-child,.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(2),.tribe-events-admin__recent-log-filters-select-wrapper #tribe-log-controls div:nth-child(3){padding-right:30px}.tribe-events-admin__issues-found-card-title h3{max-width:90%}}@media only screen and (max-width:480px){.tribe-events-admin__system-information-widget-copy{left:10px;right:auto}.tribe-events-admin__recent-log-filters{flex-direction:column}.tribe-events-admin__recent-log-filters-field{margin-bottom:30px;margin-right:0}.tribe-events-admin__recent-log-filters-select-wrapper:after{right:25px}.tribe-events-admin__issues-found-card-title h3{max-width:80%}.tribe-events-admin__ea-status-table{overflow:scroll}.tribe-events-admin__ea-status-table td{min-width:150px}.tribe-events-admin__ea-status-table td:nth-child(2),.tribe-events-admin__ea-status-table td:nth-child(3){width:100%}}@media (min-width:1024px){.black-friday-promo{align-items:center;flex-direction:row}.black-friday-promo__branding{padding-right:10px;width:calc(100% - 450px)}}
common/src/resources/css/variables-skeleton.min.css CHANGED
@@ -1 +1 @@
1
- :root{--tec-grid-gutter:48px;--tec-grid-gutter-negative:calc(var(--tec-grid-gutter)*-1);--tec-grid-gutter-half:calc(var(--tec-grid-gutter)/2);--tec-grid-gutter-half-negative:calc(var(--tec-grid-gutter-half)*-1);--tec-grid-gutter-small:42px;--tec-grid-gutter-small-negative:calc(var(--tec-grid-gutter-small)*-1);--tec-grid-gutter-small-half:calc(var(--tec-grid-gutter-small)/2);--tec-grid-gutter-small-half-negative:calc(var(--tec-grid-gutter-small-half)*-1);--tec-grid-gutter-page:42px;--tec-grid-gutter-page-small:19.5px;--tec-grid-width-default:1176px;--tec-grid-width-min:320px;--tec-grid-width:calc(var(--tec-grid-width-default) + var(--tec-grid-gutter-page)*2);--tec-grid-width-1-of-2:50%;--tec-grid-width-1-of-3:33.333%;--tec-grid-width-1-of-4:25%;--tec-grid-width-1-of-5:20%;--tec-grid-width-1-of-7:14.285%;--tec-grid-width-1-of-8:12.5%;--tec-grid-width-1-of-9:11.111%;--grid-gutter:var(--tec-grid-gutter);--grid-gutter-negative:var(--tec-grid-gutter-negative);--grid-gutter-half:var(--tec-grid-gutter-half);--grid-gutter-half-negative:var(--tec-grid-gutter-half-negative);--grid-gutter-small:var(--tec-grid-gutter-small);--grid-gutter-small-negative:var(--tec-grid-gutter-small-negative);--grid-gutter-small-half:var(--tec-grid-gutter-small-half);--grid-gutter-small-half-negative:var(--tec-grid-gutter-small-half-negative);--grid-gutter-page:var(--tec-grid-gutter-page);--grid-gutter-page-small:var(--tec-grid-gutter-page-small);--grid-width-default:var(--tec-grid-width-default);--grid-width-min:var(--tec-grid-width-min);--grid-width:var(--tec-grid-width);--grid-width-1-of-2:var(--tec-grid-width-1-of-2);--grid-width-1-of-3:var(--tec-grid-width-1-of-3);--grid-width-1-of-4:var(--tec-grid-width-1-of-4);--grid-width-1-of-5:var(--tec-grid-width-1-of-5);--grid-width-1-of-7:var(--tec-grid-width-1-of-7);--grid-width-1-of-8:var(--tec-grid-width-1-of-8);--grid-width-1-of-9:var(--tec-grid-width-1-of-9);--tec-spacer-0:4px;--tec-spacer-1:8px;--tec-spacer-2:12px;--tec-spacer-3:16px;--tec-spacer-4:20px;--tec-spacer-5:24px;--tec-spacer-6:28px;--tec-spacer-7:32px;--tec-spacer-8:40px;--tec-spacer-9:48px;--tec-spacer-10:56px;--tec-spacer-11:64px;--tec-spacer-12:80px;--tec-spacer-13:96px;--tec-spacer-14:160px;--spacer-0:var(--tec-spacer-0);--spacer-1:var(--tec-spacer-1);--spacer-2:var(--tec-spacer-2);--spacer-3:var(--tec-spacer-3);--spacer-4:var(--tec-spacer-4);--spacer-5:var(--tec-spacer-5);--spacer-6:var(--tec-spacer-6);--spacer-7:var(--tec-spacer-7);--spacer-8:var(--tec-spacer-8);--spacer-9:var(--tec-spacer-9);--spacer-10:var(--tec-spacer-10);--spacer-11:var(--tec-spacer-11);--spacer-12:var(--tec-spacer-12);--spacer-13:var(--tec-spacer-13);--spacer-14:var(--tec-spacer-14);--tec-z-index-spinner-container:100;--tec-z-index-views-selector:30;--tec-z-index-dropdown:30;--tec-z-index-events-bar-button:20;--tec-z-index-search:10;--tec-z-index-filters:9;--tec-z-index-scroller:7;--tec-z-index-week-event-hover:5;--tec-z-index-map-event-hover:5;--tec-z-index-map-event-hover-actions:6;--tec-z-index-multiday-event:5;--tec-z-index-multiday-event-bar:2;--z-index-spinner-container:var(--tec-z-index-spinner-container);--z-index-views-selector:var(--tec-z-index-views-selector);--z-index-dropdown:var(--tec-z-index-dropdown);--z-index-events-bar-button:var(--tec-z-index-events-bar-button);--z-index-search:var(--tec-z-index-search);--z-index-filters:var(--tec-z-index-filters);--z-index-scroller:var(--tec-z-index-scroller);--z-index-week-event-hover:var(--tec-z-index-week-event-hover);--z-index-map-event-hover:var(--tec-z-index-map-event-hover);--z-index-map-event-hover-actions:var(--tec-z-index-map-event-hover-actions);--z-index-multiday-event:var(--tec-z-index-multiday-event);--z-index-multiday-event-bar:var(--tec-z-index-multiday-event-bar);--tec-color-text-primary:#141827;--tec-color-text-primary-light:rgba(20,24,39,.62);--tec-color-text-secondary:#5d5d5d;--tec-color-text-disabled:#d5d5d5;--tec-color-text-events-title:var(--tec-color-text-primary);--tec-color-text-event-title:var(--tec-color-text-events-title);--tec-color-text-event-date:var(--tec-color-text-primary);--tec-color-text-secondary-event-date:var(--tec-color-text-secondary);--tec-color-icon-primary:#5d5d5d;--tec-color-icon-primary-alt:#757575;--tec-color-icon-secondary:#bababa;--tec-color-icon-active:#141827;--tec-color-icon-disabled:#d5d5d5;--tec-color-icon-focus:#334aff;--tec-color-icon-error:#da394d;--tec-color-event-icon:#141827;--tec-color-event-icon-hover:#334aff;--tec-color-accent-primary:#334aff;--tec-color-accent-primary-hover:rgba(51,74,255,.8);--tec-color-accent-primary-active:rgba(51,74,255,.9);--tec-color-accent-primary-background:rgba(51,74,255,.07);--tec-color-accent-secondary:#141827;--tec-color-accent-secondary-hover:rgba(20,24,39,.8);--tec-color-accent-secondary-active:rgba(20,24,39,.9);--tec-color-accent-secondary-background:rgba(20,24,39,.07);--tec-color-button-primary:var(--tec-color-accent-primary);--tec-color-button-primary-hover:var(--tec-color-accent-primary-hover);--tec-color-button-primary-active:var(--tec-color-accent-primary-active);--tec-color-button-primary-background:var(--tec-color-accent-primary-background);--tec-color-button-secondary:var(--tec-color-accent-secondary);--tec-color-button-secondary-hover:var(--tec-color-accent-secondary-hover);--tec-color-button-secondary-active:var(--tec-color-accent-secondary-active);--tec-color-button-secondary-background:var(--tec-color-accent-secondary-background);--tec-color-link-primary:var(--tec-color-text-primary);--tec-color-link-accent:var(--tec-color-accent-primary);--tec-color-link-accent-hover:rgba(51,74,255,.8);--tec-color-border-default:#d5d5d5;--tec-color-border-secondary:#e4e4e4;--tec-color-border-tertiary:#7d7d7d;--tec-color-border-hover:#5d5d5d;--tec-color-border-active:#141827;--tec-color-background:#fff;--tec-color-background-events:transparent;--tec-color-background-transparent:hsla(0,0%,100%,.6);--tec-color-background-secondary:#f7f6f6;--tec-color-background-messages:rgba(20,24,39,.07);--tec-color-background-secondary-hover:#f0eeee;--tec-color-background-error:rgba(218,57,77,.08);--tec-color-box-shadow:rgba(0,0,0,.14);--tec-color-box-shadow-secondary:rgba(0,0,0,.1);--tec-color-scroll-track:rgba(0,0,0,.25);--tec-color-scroll-bar:rgba(0,0,0,.5);--tec-color-background-primary-multiday:rgba(51,74,255,.24);--tec-color-background-primary-multiday-hover:rgba(51,74,255,.34);--tec-color-background-secondary-multiday:rgba(20,24,39,.24);--tec-color-background-secondary-multiday-hover:rgba(20,24,39,.34);--tec-color-accent-primary-week-event:rgba(51,74,255,.1);--tec-color-accent-primary-week-event-hover:rgba(51,74,255,.2);--tec-color-accent-primary-week-event-featured:rgba(51,74,255,.04);--tec-color-accent-primary-week-event-featured-hover:rgba(51,74,255,.14);--tec-color-background-secondary-datepicker:var(--tec-color-background-secondary);--tec-color-accent-primary-background-datepicker:var(--tec-color-accent-primary-background);--color-text-primary:var(--tec-color-text-primary);--color-text-primary-light:var(--tec-color-text-primary-light);--color-text-secondary:var(--tec-color-text-secondary);--color-text-disabled:var(--tec-color-text-disabled);--color-icon-primary:var(--tec-color-icon-primary);--color-icon-primary-alt:var(--tec-color-icon-primary);--color-icon-secondary:var(--tec-color-icon-secondary);--color-icon-active:var(--tec-color-icon-active);--color-icon-disabled:var(--tec-color-icon-disabled);--color-icon-focus:var(--tec-color-icon-focus);--color-icon-error:var(--tec-color-icon-error);--color-accent-primary:var(--tec-color-accent-primary);--color-accent-primary-hover:var(--tec-color-accent-primary-hover);--color-accent-primary-active:var(--tec-color-accent-primary-active);--color-accent-primary-background:var(--tec-color-accent-primary-background);--color-accent-primary-multiday:var(--tec-color-accent-primary-multiday);--color-accent-primary-multiday-hover:var(--tec-color-accent-primary-multiday-hover);--color-accent-primary-week-event:var(--tec-color-accent-primary-week-event);--color-accent-primary-week-event-hover:var(--tec-color-accent-primary-week-event-hover);--color-accent-primary-week-event-featured:var(--tec-color-accent-primary-week-event-featured);--color-accent-primary-week-event-featured-hover:var(--tec-color-accent-primary-week-event-featured-hover);--color-accent-secondary:var(--tec-color-accent-secondary);--color-accent-secondary-hover:var(--tec-color-accent-secondary-hover);--color-accent-secondary-active:var(--tec-color-accent-secondary-active);--color-accent-secondary-background:var(--tec-color-accent-secondary-background);--color-border-default:var(--tec-color-border-default);--color-border-secondary:var(--tec-color-border-secondary);--color-border-tertiary:var(--tec-color-border-tertiary);--color-border-hover:var(--tec-color-border-hover);--color-border-active:var(--tec-color-border-active);--color-background:var(--tec-color-background);--color-background-transparent:var(--tec-color-background-transparent);--color-background-secondary:var(--tec-color-background-secondary);--color-background-messages:var(--tec-color-background-messages);--color-background-secondary-hover:var(--tec-color-background-secondary-hover);--color-background-error:var(--tec-color-icon-error);--color-box-shadow:var(--tec-color-box-shadow);--color-box-shadow-secondary:var(--tec-color-box-shadow-secondary);--color-scroll-track:var(--tec-color-scroll-track);--color-scroll-bar:var(--tec-color-scroll-bar)}
1
+ :root{--tec-grid-gutter:48px;--tec-grid-gutter-negative:calc(var(--tec-grid-gutter)*-1);--tec-grid-gutter-half:calc(var(--tec-grid-gutter)/2);--tec-grid-gutter-half-negative:calc(var(--tec-grid-gutter-half)*-1);--tec-grid-gutter-small:42px;--tec-grid-gutter-small-negative:calc(var(--tec-grid-gutter-small)*-1);--tec-grid-gutter-small-half:calc(var(--tec-grid-gutter-small)/2);--tec-grid-gutter-small-half-negative:calc(var(--tec-grid-gutter-small-half)*-1);--tec-grid-gutter-page:42px;--tec-grid-gutter-page-small:19.5px;--tec-grid-width-default:1176px;--tec-grid-width-min:320px;--tec-grid-width:calc(var(--tec-grid-width-default) + var(--tec-grid-gutter-page)*2);--tec-grid-width-1-of-2:50%;--tec-grid-width-1-of-3:33.333%;--tec-grid-width-1-of-4:25%;--tec-grid-width-1-of-5:20%;--tec-grid-width-1-of-7:14.285%;--tec-grid-width-1-of-8:12.5%;--tec-grid-width-1-of-9:11.111%;--grid-gutter:var(--tec-grid-gutter);--grid-gutter-negative:var(--tec-grid-gutter-negative);--grid-gutter-half:var(--tec-grid-gutter-half);--grid-gutter-half-negative:var(--tec-grid-gutter-half-negative);--grid-gutter-small:var(--tec-grid-gutter-small);--grid-gutter-small-negative:var(--tec-grid-gutter-small-negative);--grid-gutter-small-half:var(--tec-grid-gutter-small-half);--grid-gutter-small-half-negative:var(--tec-grid-gutter-small-half-negative);--grid-gutter-page:var(--tec-grid-gutter-page);--grid-gutter-page-small:var(--tec-grid-gutter-page-small);--grid-width-default:var(--tec-grid-width-default);--grid-width-min:var(--tec-grid-width-min);--grid-width:var(--tec-grid-width);--grid-width-1-of-2:var(--tec-grid-width-1-of-2);--grid-width-1-of-3:var(--tec-grid-width-1-of-3);--grid-width-1-of-4:var(--tec-grid-width-1-of-4);--grid-width-1-of-5:var(--tec-grid-width-1-of-5);--grid-width-1-of-7:var(--tec-grid-width-1-of-7);--grid-width-1-of-8:var(--tec-grid-width-1-of-8);--grid-width-1-of-9:var(--tec-grid-width-1-of-9);--tec-spacer-0:4px;--tec-spacer-1:8px;--tec-spacer-2:12px;--tec-spacer-3:16px;--tec-spacer-4:20px;--tec-spacer-5:24px;--tec-spacer-6:28px;--tec-spacer-7:32px;--tec-spacer-8:40px;--tec-spacer-9:48px;--tec-spacer-10:56px;--tec-spacer-11:64px;--tec-spacer-12:80px;--tec-spacer-13:96px;--tec-spacer-14:160px;--spacer-0:var(--tec-spacer-0);--spacer-1:var(--tec-spacer-1);--spacer-2:var(--tec-spacer-2);--spacer-3:var(--tec-spacer-3);--spacer-4:var(--tec-spacer-4);--spacer-5:var(--tec-spacer-5);--spacer-6:var(--tec-spacer-6);--spacer-7:var(--tec-spacer-7);--spacer-8:var(--tec-spacer-8);--spacer-9:var(--tec-spacer-9);--spacer-10:var(--tec-spacer-10);--spacer-11:var(--tec-spacer-11);--spacer-12:var(--tec-spacer-12);--spacer-13:var(--tec-spacer-13);--spacer-14:var(--tec-spacer-14);--tec-z-index-spinner-container:100;--tec-z-index-views-selector:30;--tec-z-index-dropdown:30;--tec-z-index-events-bar-button:20;--tec-z-index-search:10;--tec-z-index-filters:9;--tec-z-index-scroller:7;--tec-z-index-week-event-hover:5;--tec-z-index-map-event-hover:5;--tec-z-index-map-event-hover-actions:6;--tec-z-index-multiday-event:5;--tec-z-index-multiday-event-bar:2;--z-index-spinner-container:var(--tec-z-index-spinner-container);--z-index-views-selector:var(--tec-z-index-views-selector);--z-index-dropdown:var(--tec-z-index-dropdown);--z-index-events-bar-button:var(--tec-z-index-events-bar-button);--z-index-search:var(--tec-z-index-search);--z-index-filters:var(--tec-z-index-filters);--z-index-scroller:var(--tec-z-index-scroller);--z-index-week-event-hover:var(--tec-z-index-week-event-hover);--z-index-map-event-hover:var(--tec-z-index-map-event-hover);--z-index-map-event-hover-actions:var(--tec-z-index-map-event-hover-actions);--z-index-multiday-event:var(--tec-z-index-multiday-event);--z-index-multiday-event-bar:var(--tec-z-index-multiday-event-bar);--tec-color-text-primary:#141827;--tec-color-text-primary-light:rgba(20,24,39,.62);--tec-color-text-secondary:#5d5d5d;--tec-color-text-disabled:#d5d5d5;--tec-color-text-events-title:var(--tec-color-text-primary);--tec-color-text-event-title:var(--tec-color-text-events-title);--tec-color-text-event-date:var(--tec-color-text-primary);--tec-color-text-secondary-event-date:var(--tec-color-text-secondary);--tec-color-icon-primary:#5d5d5d;--tec-color-icon-primary-alt:#757575;--tec-color-icon-secondary:#bababa;--tec-color-icon-active:#141827;--tec-color-icon-disabled:#d5d5d5;--tec-color-icon-focus:#334aff;--tec-color-icon-error:#da394d;--tec-color-event-icon:#141827;--tec-color-event-icon-hover:#334aff;--tec-color-accent-primary:#334aff;--tec-color-accent-primary-hover:rgba(51,74,255,.8);--tec-color-accent-primary-active:rgba(51,74,255,.9);--tec-color-accent-primary-background:rgba(51,74,255,.07);--tec-color-accent-secondary:#141827;--tec-color-accent-secondary-hover:rgba(20,24,39,.8);--tec-color-accent-secondary-active:rgba(20,24,39,.9);--tec-color-accent-secondary-background:rgba(20,24,39,.07);--tec-color-button-primary:var(--tec-color-accent-primary);--tec-color-button-primary-hover:var(--tec-color-accent-primary-hover);--tec-color-button-primary-active:var(--tec-color-accent-primary-active);--tec-color-button-primary-background:var(--tec-color-accent-primary-background);--tec-color-button-secondary:var(--tec-color-accent-secondary);--tec-color-button-secondary-hover:var(--tec-color-accent-secondary-hover);--tec-color-button-secondary-active:var(--tec-color-accent-secondary-active);--tec-color-button-secondary-background:var(--tec-color-accent-secondary-background);--tec-color-link-primary:var(--tec-color-text-primary);--tec-color-link-accent-hover:rgba(51,74,255,.8);--tec-color-border-default:#d5d5d5;--tec-color-border-secondary:#e4e4e4;--tec-color-border-tertiary:#7d7d7d;--tec-color-border-hover:#5d5d5d;--tec-color-border-active:#141827;--tec-color-background:#fff;--tec-color-background-events:transparent;--tec-color-background-transparent:hsla(0,0%,100%,.6);--tec-color-background-secondary:#f7f6f6;--tec-color-background-messages:rgba(20,24,39,.07);--tec-color-background-secondary-hover:#f0eeee;--tec-color-background-error:rgba(218,57,77,.08);--tec-color-box-shadow:rgba(0,0,0,.14);--tec-color-box-shadow-secondary:rgba(0,0,0,.1);--tec-color-scroll-track:rgba(0,0,0,.25);--tec-color-scroll-bar:rgba(0,0,0,.5);--tec-color-background-primary-multiday:rgba(51,74,255,.24);--tec-color-background-primary-multiday-hover:rgba(51,74,255,.34);--tec-color-background-secondary-multiday:rgba(20,24,39,.24);--tec-color-background-secondary-multiday-hover:rgba(20,24,39,.34);--tec-color-accent-primary-week-event:rgba(51,74,255,.1);--tec-color-accent-primary-week-event-hover:rgba(51,74,255,.2);--tec-color-accent-primary-week-event-featured:rgba(51,74,255,.04);--tec-color-accent-primary-week-event-featured-hover:rgba(51,74,255,.14);--tec-color-background-secondary-datepicker:var(--tec-color-background-secondary);--tec-color-accent-primary-background-datepicker:var(--tec-color-accent-primary-background);--color-text-primary:var(--tec-color-text-primary);--color-text-primary-light:var(--tec-color-text-primary-light);--color-text-secondary:var(--tec-color-text-secondary);--color-text-disabled:var(--tec-color-text-disabled);--color-icon-primary:var(--tec-color-icon-primary);--color-icon-primary-alt:var(--tec-color-icon-primary);--color-icon-secondary:var(--tec-color-icon-secondary);--color-icon-active:var(--tec-color-icon-active);--color-icon-disabled:var(--tec-color-icon-disabled);--color-icon-focus:var(--tec-color-icon-focus);--color-icon-error:var(--tec-color-icon-error);--color-accent-primary:var(--tec-color-accent-primary);--color-accent-primary-hover:var(--tec-color-accent-primary-hover);--color-accent-primary-active:var(--tec-color-accent-primary-active);--color-accent-primary-background:var(--tec-color-accent-primary-background);--color-accent-primary-multiday:var(--tec-color-accent-primary-multiday);--color-accent-primary-multiday-hover:var(--tec-color-accent-primary-multiday-hover);--color-accent-primary-week-event:var(--tec-color-accent-primary-week-event);--color-accent-primary-week-event-hover:var(--tec-color-accent-primary-week-event-hover);--color-accent-primary-week-event-featured:var(--tec-color-accent-primary-week-event-featured);--color-accent-primary-week-event-featured-hover:var(--tec-color-accent-primary-week-event-featured-hover);--color-accent-secondary:var(--tec-color-accent-secondary);--color-accent-secondary-hover:var(--tec-color-accent-secondary-hover);--color-accent-secondary-active:var(--tec-color-accent-secondary-active);--color-accent-secondary-background:var(--tec-color-accent-secondary-background);--color-border-default:var(--tec-color-border-default);--color-border-secondary:var(--tec-color-border-secondary);--color-border-tertiary:var(--tec-color-border-tertiary);--color-border-hover:var(--tec-color-border-hover);--color-border-active:var(--tec-color-border-active);--color-background:var(--tec-color-background);--color-background-transparent:var(--tec-color-background-transparent);--color-background-secondary:var(--tec-color-background-secondary);--color-background-messages:var(--tec-color-background-messages);--color-background-secondary-hover:var(--tec-color-background-secondary-hover);--color-background-error:var(--tec-color-icon-error);--color-box-shadow:var(--tec-color-box-shadow);--color-box-shadow-secondary:var(--tec-color-box-shadow-secondary);--color-scroll-track:var(--tec-color-scroll-track);--color-scroll-bar:var(--tec-color-scroll-bar)}
common/src/resources/images/marketing/bf-promo.png ADDED
Binary file
common/src/resources/images/mascot.png CHANGED
Binary file
common/src/resources/images/promos/bf-promo.png ADDED
Binary file
common/src/resources/js/onboarding.js DELETED
@@ -1,106 +0,0 @@
1
- /**
2
- *
3
- * @type {PlainObject}
4
- */
5
- tribe.onboarding = {};
6
-
7
- /**
8
- *
9
- * @param {PlainObject} $ jQuery
10
- * @param {PlainObject} obj tribe.onboarding
11
- *
12
- * @return {void}
13
- */
14
- ( function( $, obj ) {
15
- 'use strict';
16
- var $document = $( document );
17
-
18
- /**
19
- * Selectors used for configuration and setup
20
- *
21
- * @since TBD
22
- *
23
- * @type {PlainObject}
24
- */
25
- obj.selectors = {};
26
-
27
- /**
28
- * Concatenate the CSS classes for the tooltip.
29
- *
30
- * @param {Array} classes
31
- * @returns {String} String containing the classes for the tooltip.
32
- */
33
- obj.getTooltipClasses = function( classes ) {
34
- const defaultClasses = [ 'tribe-onboarding__tooltip' ];
35
-
36
- return defaultClasses.concat( classes ).join( ' ' );
37
- }
38
-
39
- /**
40
- * Init onboarding steps.
41
- *
42
- * @since TBD
43
- *
44
- * @return void
45
- */
46
- obj.initTour = function() {
47
- const steps = TribeOnboardingTour.steps;
48
- const classes = TribeOnboardingTour.classes || [];
49
-
50
- if ( typeof steps === 'undefined' ) {
51
- return;
52
- }
53
-
54
- if ( ! steps.length ) {
55
- return;
56
- }
57
-
58
- introJs().setOptions( {
59
- tooltipClass: obj.getTooltipClasses( classes ),
60
- steps: steps
61
- } ).start();
62
- };
63
-
64
- /**
65
- * Init hints.
66
- *
67
- * @since TBD
68
- *
69
- * @return void
70
- */
71
- obj.initHints = function() {
72
- const hints = TribeOnboardingHints.hints;
73
- const classes = TribeOnboardingHints.classes || [];
74
-
75
- if ( ! Array.isArray( hints ) || ! hints.length ) {
76
- return;
77
- }
78
-
79
- introJs().setOptions( {
80
- tooltipClass: obj.getTooltipClasses( classes ),
81
- hintButtonLabel: TribeOnboarding.hintButtonLabel,
82
- hintPosition: 'middle-right',
83
- hintAnimation: true,
84
- hints: hints,
85
- } ).addHints();
86
- };
87
-
88
- /**
89
- * Handles the initialization of the enhancer.
90
- *
91
- * @since TBD
92
- *
93
- * @return {void}
94
- */
95
- obj.ready = function() {
96
- // Init Tour.
97
- obj.initTour();
98
-
99
- // Init hint.
100
- obj.initHints();
101
- };
102
-
103
- // Configure on document ready.
104
- $document.ready( obj.ready );
105
-
106
- } )( jQuery, tribe.onboarding );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/resources/js/onboarding.min.js DELETED
@@ -1 +0,0 @@
1
- tribe.onboarding={},function(t,i){"use strict";var n=t(document);i.selectors={},i.getTooltipClasses=function(t){return["tribe-onboarding__tooltip"].concat(t).join(" ")},i.initTour=function(){const t=TribeOnboardingTour.steps,n=TribeOnboardingTour.classes||[];void 0!==t&&t.length&&introJs().setOptions({tooltipClass:i.getTooltipClasses(n),steps:t}).start()},i.initHints=function(){const t=TribeOnboardingHints.hints,n=TribeOnboardingHints.classes||[];Array.isArray(t)&&t.length&&introJs().setOptions({tooltipClass:i.getTooltipClasses(n),hintButtonLabel:TribeOnboarding.hintButtonLabel,hintPosition:"middle-right",hintAnimation:!0,hints:t}).addHints()},i.ready=function(){i.initTour(),i.initHints()},n.ready(i.ready)}(jQuery,tribe.onboarding);
 
common/src/views/v2/components/icons/list.php CHANGED
@@ -10,14 +10,25 @@
10
  * @link http://evnt.is/1aiy
11
  *
12
  * @var array<string> $classes Additional classes to add to the svg icon.
 
13
  *
14
  * @version 4.12.14
 
15
  *
16
  */
17
  $svg_classes = [ 'tribe-common-c-svgicon', 'tribe-common-c-svgicon--list' ];
18
 
19
  if ( ! empty( $classes ) ) {
20
  $svg_classes = array_merge( $svg_classes, $classes );
 
 
 
 
 
 
21
  }
 
 
 
22
  ?>
23
- <svg <?php tribe_classes( $svg_classes ); ?> viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M.451.432V17.6c0 .238.163.432.364.432H18.12c.2 0 .364-.194.364-.432V.432c0-.239-.163-.432-.364-.432H.815c-.2 0-.364.193-.364.432zm.993.81h16.024V3.56H1.444V1.24zM17.468 3.56H1.444v13.227h16.024V3.56z" class="tribe-common-c-svgicon__svg-fill"/><g clip-path="url(#clip0)" class="tribe-common-c-svgicon__svg-fill"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.831 4.912v1.825c0 .504.409.913.913.913h1.825a.913.913 0 00.912-.913V4.912A.913.913 0 0014.57 4h-1.825a.912.912 0 00-.913.912z"/><path d="M8.028 7.66a.449.449 0 00.446-.448v-.364c0-.246-.2-.448-.446-.448h-4.13a.449.449 0 00-.447.448v.364c0 .246.201.448.447.448h4.13zM9.797 5.26a.449.449 0 00.447-.448v-.364c0-.246-.201-.448-.447-.448h-5.9a.449.449 0 00-.446.448v.364c0 .246.201.448.447.448h5.9z"/></g><g clip-path="url(#clip1)" class="tribe-common-c-svgicon__svg-fill"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.831 10.912v1.825c0 .505.409.913.913.913h1.825a.913.913 0 00.912-.912v-1.825A.913.913 0 0014.57 10h-1.825a.912.912 0 00-.913.912z"/><path d="M8.028 13.66a.449.449 0 00.446-.448v-.364c0-.246-.2-.448-.446-.448h-4.13a.449.449 0 00-.447.448v.364c0 .246.201.448.447.448h4.13zM9.797 11.26a.449.449 0 00.447-.448v-.364c0-.246-.201-.448-.447-.448h-5.9a.449.449 0 00-.446.448v.364c0 .246.201.448.447.448h5.9z"/></g><defs><clipPath id="clip0"><path transform="translate(3.451 4)" d="M0 0h13v4H0z"/></clipPath><clipPath id="clip1"><path transform="translate(3.451 10)" d="M0 0h13v4H0z"/></clipPath></defs></svg>
10
  * @link http://evnt.is/1aiy
11
  *
12
  * @var array<string> $classes Additional classes to add to the svg icon.
13
+ * If not empty, the first is used for the clip path IDs.
14
  *
15
  * @version 4.12.14
16
+ * @since 4.14.7 Prevent duplicate IDs.
17
  *
18
  */
19
  $svg_classes = [ 'tribe-common-c-svgicon', 'tribe-common-c-svgicon--list' ];
20
 
21
  if ( ! empty( $classes ) ) {
22
  $svg_classes = array_merge( $svg_classes, $classes );
23
+ // If we have classes, use the first for the id_prefix for target specificity.
24
+ $id_prefix = array_shift( $classes );
25
+ } else {
26
+ // If we don't have classes, use a generated ID.
27
+ $id_prefix = 'tribe-common-c-svgicon__list-clip-path-';
28
+ $id_prefix .= tribe_get_next_cached_increment( $id_prefix );
29
  }
30
+
31
+ $clip0 = $id_prefix . '-0';
32
+ $clip1 = $id_prefix . '-1';
33
  ?>
34
+ <svg <?php tribe_classes( $svg_classes ); ?> viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M.451.432V17.6c0 .238.163.432.364.432H18.12c.2 0 .364-.194.364-.432V.432c0-.239-.163-.432-.364-.432H.815c-.2 0-.364.193-.364.432zm.993.81h16.024V3.56H1.444V1.24zM17.468 3.56H1.444v13.227h16.024V3.56z" class="tribe-common-c-svgicon__svg-fill"/><g clip-path="url(#<?php echo $clip0; ?>)" class="tribe-common-c-svgicon__svg-fill"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.831 4.912v1.825c0 .504.409.913.913.913h1.825a.913.913 0 00.912-.913V4.912A.913.913 0 0014.57 4h-1.825a.912.912 0 00-.913.912z"/><path d="M8.028 7.66a.449.449 0 00.446-.448v-.364c0-.246-.2-.448-.446-.448h-4.13a.449.449 0 00-.447.448v.364c0 .246.201.448.447.448h4.13zM9.797 5.26a.449.449 0 00.447-.448v-.364c0-.246-.201-.448-.447-.448h-5.9a.449.449 0 00-.446.448v.364c0 .246.201.448.447.448h5.9z"/></g><g clip-path="url(#<?php echo $clip1; ?>)" class="tribe-common-c-svgicon__svg-fill"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.831 10.912v1.825c0 .505.409.913.913.913h1.825a.913.913 0 00.912-.912v-1.825A.913.913 0 0014.57 10h-1.825a.912.912 0 00-.913.912z"/><path d="M8.028 13.66a.449.449 0 00.446-.448v-.364c0-.246-.2-.448-.446-.448h-4.13a.449.449 0 00-.447.448v.364c0 .246.201.448.447.448h4.13zM9.797 11.26a.449.449 0 00.447-.448v-.364c0-.246-.201-.448-.447-.448h-5.9a.449.449 0 00-.446.448v.364c0 .246.201.448.447.448h5.9z"/></g><defs><clipPath id="<?php echo $clip0; ?>"><path transform="translate(3.451 4)" d="M0 0h13v4H0z"/></clipPath><clipPath id="<?php echo $clip1; ?>"><path transform="translate(3.451 10)" d="M0 0h13v4H0z"/></clipPath></defs></svg>
common/vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInite327b8b697647c495d3e4d6238d79f58::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitb53837a8c1428672f8ec1944182c5ba7::getLoader();
common/vendor/autoload_52.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
- return ComposerAutoloaderInit77a78a5dadfd0c72ac991d87712ceac6::getLoader();
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
+ return ComposerAutoloaderInit3410cd31e8268fa68b879e75e76a2048::getLoader();
common/vendor/composer/autoload_classmap.php CHANGED
@@ -114,6 +114,9 @@ return array(
114
  'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/DummyTest.php',
115
  'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
116
  'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php',
 
 
 
117
  'Tribe\\Admin\\Notice\\Date_Based' => $baseDir . '/src/Tribe/Admin/Notice/Date_Based.php',
118
  'Tribe\\Admin\\Notice\\Marketing\\Black_Friday' => $baseDir . '/src/Tribe/Admin/Notice/Marketing/Black_Friday.php',
119
  'Tribe\\Admin\\Notice\\Marketing\\Stellar_Sale' => $baseDir . '/src/Tribe/Admin/Notice/Marketing/Stellar_Sale.php',
@@ -135,16 +138,12 @@ return array(
135
  'Tribe\\Log\\Service_Provider' => $baseDir . '/src/Tribe/Log/Service_Provider.php',
136
  'Tribe\\Models\\Post_Types\\Base' => $baseDir . '/src/Tribe/Models/Post_Types/Base.php',
137
  'Tribe\\Models\\Post_Types\\Nothing' => $baseDir . '/src/Tribe/Models/Post_Types/Nothing.php',
138
- 'Tribe\\Onboarding\\Hints_Abstract' => $baseDir . '/src/Tribe/Onboarding/Hints_Abstract.php',
139
- 'Tribe\\Onboarding\\Main' => $baseDir . '/src/Tribe/Onboarding/Main.php',
140
- 'Tribe\\Onboarding\\Tour_Abstract' => $baseDir . '/src/Tribe/Onboarding/Tour_Abstract.php',
141
  'Tribe\\PUE\\Update_Prevention' => $baseDir . '/src/Tribe/PUE/Update_Prevention.php',
142
  'Tribe\\Repository\\Core_Read_Interface' => $baseDir . '/src/Tribe/Repository/Core_Read_Interface.php',
143
  'Tribe\\Repository\\Filter_Validation' => $baseDir . '/src/Tribe/Repository/Filter_Validation.php',
144
  'Tribe\\Service_Providers\\Body_Classes' => $baseDir . '/src/Tribe/Service_Providers/Body_Classes.php',
145
  'Tribe\\Service_Providers\\Crons' => $baseDir . '/src/Tribe/Service_Providers/Crons.php',
146
  'Tribe\\Service_Providers\\Dialog' => $baseDir . '/src/Tribe/Service_Providers/Dialog.php',
147
- 'Tribe\\Service_Providers\\Onboarding' => $baseDir . '/src/Tribe/Service_Providers/Onboarding.php',
148
  'Tribe\\Service_Providers\\PUE' => $baseDir . '/src/Tribe/Service_Providers/PUE.php',
149
  'Tribe\\Service_Providers\\Shortcodes' => $baseDir . '/src/Tribe/Service_Providers/Shortcodes.php',
150
  'Tribe\\Service_Providers\\Tooltip' => $baseDir . '/src/Tribe/Service_Providers/Tooltip.php',
114
  'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/DummyTest.php',
115
  'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
116
  'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php',
117
+ 'Tribe\\Admin\\Conditional_Content\\Black_Friday' => $baseDir . '/src/Tribe/Admin/Conditional_Content/Black_Friday.php',
118
+ 'Tribe\\Admin\\Conditional_Content\\Datetime_Conditional_Abstract' => $baseDir . '/src/Tribe/Admin/Conditional_Content/Datetime_Conditional_Abstract.php',
119
+ 'Tribe\\Admin\\Conditional_Content\\Service_Provider' => $baseDir . '/src/Tribe/Admin/Conditional_Content/Service_Provider.php',
120
  'Tribe\\Admin\\Notice\\Date_Based' => $baseDir . '/src/Tribe/Admin/Notice/Date_Based.php',
121
  'Tribe\\Admin\\Notice\\Marketing\\Black_Friday' => $baseDir . '/src/Tribe/Admin/Notice/Marketing/Black_Friday.php',
122
  'Tribe\\Admin\\Notice\\Marketing\\Stellar_Sale' => $baseDir . '/src/Tribe/Admin/Notice/Marketing/Stellar_Sale.php',
138
  'Tribe\\Log\\Service_Provider' => $baseDir . '/src/Tribe/Log/Service_Provider.php',
139
  'Tribe\\Models\\Post_Types\\Base' => $baseDir . '/src/Tribe/Models/Post_Types/Base.php',
140
  'Tribe\\Models\\Post_Types\\Nothing' => $baseDir . '/src/Tribe/Models/Post_Types/Nothing.php',
 
 
 
141
  'Tribe\\PUE\\Update_Prevention' => $baseDir . '/src/Tribe/PUE/Update_Prevention.php',
142
  'Tribe\\Repository\\Core_Read_Interface' => $baseDir . '/src/Tribe/Repository/Core_Read_Interface.php',
143
  'Tribe\\Repository\\Filter_Validation' => $baseDir . '/src/Tribe/Repository/Filter_Validation.php',
144
  'Tribe\\Service_Providers\\Body_Classes' => $baseDir . '/src/Tribe/Service_Providers/Body_Classes.php',
145
  'Tribe\\Service_Providers\\Crons' => $baseDir . '/src/Tribe/Service_Providers/Crons.php',
146
  'Tribe\\Service_Providers\\Dialog' => $baseDir . '/src/Tribe/Service_Providers/Dialog.php',
 
147
  'Tribe\\Service_Providers\\PUE' => $baseDir . '/src/Tribe/Service_Providers/PUE.php',
148
  'Tribe\\Service_Providers\\Shortcodes' => $baseDir . '/src/Tribe/Service_Providers/Shortcodes.php',
149
  'Tribe\\Service_Providers\\Tooltip' => $baseDir . '/src/Tribe/Service_Providers/Tooltip.php',
common/vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInite327b8b697647c495d3e4d6238d79f58
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInite327b8b697647c495d3e4d6238d79f58
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInite327b8b697647c495d3e4d6238d79f58', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInite327b8b697647c495d3e4d6238d79f58', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInite327b8b697647c495d3e4d6238d79f58::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitb53837a8c1428672f8ec1944182c5ba7
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitb53837a8c1428672f8ec1944182c5ba7', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitb53837a8c1428672f8ec1944182c5ba7', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInitb53837a8c1428672f8ec1944182c5ba7::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
common/vendor/composer/autoload_real_52.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
- class ComposerAutoloaderInit77a78a5dadfd0c72ac991d87712ceac6 {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit77a78a5dadfd0c72ac991d87712ceac6 {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit77a78a5dadfd0c72ac991d87712ceac6', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit77a78a5dadfd0c72ac991d87712ceac6', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
+ class ComposerAutoloaderInit3410cd31e8268fa68b879e75e76a2048 {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit3410cd31e8268fa68b879e75e76a2048', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit3410cd31e8268fa68b879e75e76a2048', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
common/vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInite327b8b697647c495d3e4d6238d79f58
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'T' =>
@@ -170,6 +170,9 @@ class ComposerStaticInite327b8b697647c495d3e4d6238d79f58
170
  'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/DummyTest.php',
171
  'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
172
  'Psr\\Log\\Test\\TestLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/TestLogger.php',
 
 
 
173
  'Tribe\\Admin\\Notice\\Date_Based' => __DIR__ . '/../..' . '/src/Tribe/Admin/Notice/Date_Based.php',
174
  'Tribe\\Admin\\Notice\\Marketing\\Black_Friday' => __DIR__ . '/../..' . '/src/Tribe/Admin/Notice/Marketing/Black_Friday.php',
175
  'Tribe\\Admin\\Notice\\Marketing\\Stellar_Sale' => __DIR__ . '/../..' . '/src/Tribe/Admin/Notice/Marketing/Stellar_Sale.php',
@@ -191,16 +194,12 @@ class ComposerStaticInite327b8b697647c495d3e4d6238d79f58
191
  'Tribe\\Log\\Service_Provider' => __DIR__ . '/../..' . '/src/Tribe/Log/Service_Provider.php',
192
  'Tribe\\Models\\Post_Types\\Base' => __DIR__ . '/../..' . '/src/Tribe/Models/Post_Types/Base.php',
193
  'Tribe\\Models\\Post_Types\\Nothing' => __DIR__ . '/../..' . '/src/Tribe/Models/Post_Types/Nothing.php',
194
- 'Tribe\\Onboarding\\Hints_Abstract' => __DIR__ . '/../..' . '/src/Tribe/Onboarding/Hints_Abstract.php',
195
- 'Tribe\\Onboarding\\Main' => __DIR__ . '/../..' . '/src/Tribe/Onboarding/Main.php',
196
- 'Tribe\\Onboarding\\Tour_Abstract' => __DIR__ . '/../..' . '/src/Tribe/Onboarding/Tour_Abstract.php',
197
  'Tribe\\PUE\\Update_Prevention' => __DIR__ . '/../..' . '/src/Tribe/PUE/Update_Prevention.php',
198
  'Tribe\\Repository\\Core_Read_Interface' => __DIR__ . '/../..' . '/src/Tribe/Repository/Core_Read_Interface.php',
199
  'Tribe\\Repository\\Filter_Validation' => __DIR__ . '/../..' . '/src/Tribe/Repository/Filter_Validation.php',
200
  'Tribe\\Service_Providers\\Body_Classes' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Body_Classes.php',
201
  'Tribe\\Service_Providers\\Crons' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Crons.php',
202
  'Tribe\\Service_Providers\\Dialog' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Dialog.php',
203
- 'Tribe\\Service_Providers\\Onboarding' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Onboarding.php',
204
  'Tribe\\Service_Providers\\PUE' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/PUE.php',
205
  'Tribe\\Service_Providers\\Shortcodes' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Shortcodes.php',
206
  'Tribe\\Service_Providers\\Tooltip' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Tooltip.php',
@@ -246,10 +245,10 @@ class ComposerStaticInite327b8b697647c495d3e4d6238d79f58
246
  public static function getInitializer(ClassLoader $loader)
247
  {
248
  return \Closure::bind(function () use ($loader) {
249
- $loader->prefixLengthsPsr4 = ComposerStaticInite327b8b697647c495d3e4d6238d79f58::$prefixLengthsPsr4;
250
- $loader->prefixDirsPsr4 = ComposerStaticInite327b8b697647c495d3e4d6238d79f58::$prefixDirsPsr4;
251
- $loader->prefixesPsr0 = ComposerStaticInite327b8b697647c495d3e4d6238d79f58::$prefixesPsr0;
252
- $loader->classMap = ComposerStaticInite327b8b697647c495d3e4d6238d79f58::$classMap;
253
 
254
  }, null, ClassLoader::class);
255
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitb53837a8c1428672f8ec1944182c5ba7
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'T' =>
170
  'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/DummyTest.php',
171
  'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
172
  'Psr\\Log\\Test\\TestLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/TestLogger.php',
173
+ 'Tribe\\Admin\\Conditional_Content\\Black_Friday' => __DIR__ . '/../..' . '/src/Tribe/Admin/Conditional_Content/Black_Friday.php',
174
+ 'Tribe\\Admin\\Conditional_Content\\Datetime_Conditional_Abstract' => __DIR__ . '/../..' . '/src/Tribe/Admin/Conditional_Content/Datetime_Conditional_Abstract.php',
175
+ 'Tribe\\Admin\\Conditional_Content\\Service_Provider' => __DIR__ . '/../..' . '/src/Tribe/Admin/Conditional_Content/Service_Provider.php',
176
  'Tribe\\Admin\\Notice\\Date_Based' => __DIR__ . '/../..' . '/src/Tribe/Admin/Notice/Date_Based.php',
177
  'Tribe\\Admin\\Notice\\Marketing\\Black_Friday' => __DIR__ . '/../..' . '/src/Tribe/Admin/Notice/Marketing/Black_Friday.php',
178
  'Tribe\\Admin\\Notice\\Marketing\\Stellar_Sale' => __DIR__ . '/../..' . '/src/Tribe/Admin/Notice/Marketing/Stellar_Sale.php',
194
  'Tribe\\Log\\Service_Provider' => __DIR__ . '/../..' . '/src/Tribe/Log/Service_Provider.php',
195
  'Tribe\\Models\\Post_Types\\Base' => __DIR__ . '/../..' . '/src/Tribe/Models/Post_Types/Base.php',
196
  'Tribe\\Models\\Post_Types\\Nothing' => __DIR__ . '/../..' . '/src/Tribe/Models/Post_Types/Nothing.php',
 
 
 
197
  'Tribe\\PUE\\Update_Prevention' => __DIR__ . '/../..' . '/src/Tribe/PUE/Update_Prevention.php',
198
  'Tribe\\Repository\\Core_Read_Interface' => __DIR__ . '/../..' . '/src/Tribe/Repository/Core_Read_Interface.php',
199
  'Tribe\\Repository\\Filter_Validation' => __DIR__ . '/../..' . '/src/Tribe/Repository/Filter_Validation.php',
200
  'Tribe\\Service_Providers\\Body_Classes' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Body_Classes.php',
201
  'Tribe\\Service_Providers\\Crons' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Crons.php',
202
  'Tribe\\Service_Providers\\Dialog' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Dialog.php',
 
203
  'Tribe\\Service_Providers\\PUE' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/PUE.php',
204
  'Tribe\\Service_Providers\\Shortcodes' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Shortcodes.php',
205
  'Tribe\\Service_Providers\\Tooltip' => __DIR__ . '/../..' . '/src/Tribe/Service_Providers/Tooltip.php',
245
  public static function getInitializer(ClassLoader $loader)
246
  {
247
  return \Closure::bind(function () use ($loader) {
248
+ $loader->prefixLengthsPsr4 = ComposerStaticInitb53837a8c1428672f8ec1944182c5ba7::$prefixLengthsPsr4;
249
+ $loader->prefixDirsPsr4 = ComposerStaticInitb53837a8c1428672f8ec1944182c5ba7::$prefixDirsPsr4;
250
+ $loader->prefixesPsr0 = ComposerStaticInitb53837a8c1428672f8ec1944182c5ba7::$prefixesPsr0;
251
+ $loader->classMap = ComposerStaticInitb53837a8c1428672f8ec1944182c5ba7::$classMap;
252
 
253
  }, null, ClassLoader::class);
254
  }
common/vendor/composer/installed.json CHANGED
@@ -35,13 +35,13 @@
35
  "authors": [
36
  {
37
  "name": "Neuman Vong",
38
- "role": "Developer",
39
- "email": "neuman+pear@twilio.com"
40
  },
41
  {
42
  "name": "Anant Narayanan",
43
- "role": "Developer",
44
- "email": "anant@php.net"
45
  }
46
  ],
47
  "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
35
  "authors": [
36
  {
37
  "name": "Neuman Vong",
38
+ "email": "neuman+pear@twilio.com",
39
+ "role": "Developer"
40
  },
41
  {
42
  "name": "Anant Narayanan",
43
+ "email": "anant@php.net",
44
+ "role": "Developer"
45
  }
46
  ],
47
  "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
event-tickets.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Event Tickets
4
  Plugin URI: https://evnt.is/1acb
5
  Description: Event Tickets allows you to sell basic tickets and collect RSVPs from any post, page, or event.
6
- Version: 5.1.10
7
  Author: The Events Calendar
8
  Author URI: https://evnt.is/1aor
9
  License: GPLv2 or later
3
  Plugin Name: Event Tickets
4
  Plugin URI: https://evnt.is/1acb
5
  Description: Event Tickets allows you to sell basic tickets and collect RSVPs from any post, page, or event.
6
+ Version: 5.2.0
7
  Author: The Events Calendar
8
  Author URI: https://evnt.is/1aor
9
  License: GPLv2 or later
lang/event-tickets-cs_CZ.mo CHANGED
Binary file
lang/event-tickets-nb_NO.mo CHANGED
Binary file
lang/event-tickets-nl_NL.mo CHANGED
Binary file
lang/event-tickets-ro_RO.mo CHANGED
Binary file
lang/event-tickets-ru_RU.mo CHANGED
Binary file
lang/event-tickets.pot CHANGED
@@ -2,47 +2,306 @@
2
  # This file is distributed under the same license as the Event Tickets package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Event Tickets 5.1.10\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/event-tickets\n"
7
- "POT-Creation-Date: 2021-09-27 06:38:37+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2021-09-27 06:38\n"
12
  "Last-Translator: \n"
13
  "Language-Team: \n"
14
 
15
- #. #-#-#-#-# event-tickets.pot (Event Tickets 5.1.10) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
  #: event-tickets.php:61 src/Tribe/Admin/Notices.php:92 src/Tribe/Main.php:691
18
  #: src/Tribe/Privacy.php:59 src/admin-views/admin-welcome-message.php:58
19
  msgid "Event Tickets"
20
  msgstr ""
21
 
22
- #: src/Tickets/Commerce/Attendee.php:197 src/Tribe/Admin/Columns/Tickets.php:56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  #: src/Tribe/Admin/Manager/Service_Provider.php:173 src/Tribe/Attendees.php:212
24
  #: src/Tribe/Commerce/PayPal/Main.php:456
25
  #: src/Tribe/Tabbed_View/Attendee_Report_Tab.php:22 src/admin-views/list.php:95
26
  msgid "Attendees"
27
  msgstr ""
28
 
29
- #: src/Tickets/Commerce/Checkout.php:176
 
 
 
 
 
 
 
 
30
  msgid "Tickets Commerce Checkout Page"
31
  msgstr ""
32
 
33
- #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:42
34
- msgid "Disconnect PayPal Account"
35
  msgstr ""
36
 
37
  #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:43
38
- msgid "Are you sure you want to disconnect your PayPal account?"
39
  msgstr ""
40
 
41
  #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:44
 
 
 
 
42
  msgid "You’re connected to PayPal! Here’s what’s next..."
43
  msgstr ""
44
 
45
- #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:46
46
  msgid ""
47
  "PayPal allows you to accept credit or debit cards directly on your website. "
48
  "Because of\n"
@@ -54,160 +313,4158 @@ msgid ""
54
  "comprised of, but not limited to:"
55
  msgstr ""
56
 
57
- #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:56
58
  msgid ""
59
  "Using a trusted, secure hosting provider – preferably one which claims and "
60
  "actively promotes PCI compliance."
61
  msgstr ""
62
 
63
- #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:57
64
  msgid ""
65
  "Maintain security best practices when setting passwords and limit access to "
66
  "your server."
67
  msgstr ""
68
 
69
- #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:58
70
  msgid "Implement an SSL certificate to keep your payments secure."
71
  msgstr ""
72
 
73
- #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:59
74
  msgid "Keep plugins up to date to ensure latest security fixes are present."
75
  msgstr ""
76
 
77
- #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:62
78
  msgid ""
79
  "You have connected your account for test mode. You will need to connect "
80
  "again once you are in live mode."
81
  msgstr ""
82
 
83
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:673
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  msgid "The PayPal webhook does not exist"
85
  msgstr ""
86
 
87
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:676
88
  msgid "Unexpected PayPal response when getting webhook"
89
  msgstr ""
90
 
91
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:723
92
  msgid "Unexpected PayPal response when creating webhook"
93
  msgstr ""
94
 
95
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:734
96
  msgid ""
97
  "PayPal webhook limit has been reached, you need to go into your developer."
98
  "paypal.com account and remove webhooks from the associated account"
99
  msgstr ""
100
 
101
- #: src/Tickets/Commerce/Gateways/PayPal/Client.php:791
102
  msgid "Unexpected PayPal response when updating webhook"
103
  msgstr ""
104
 
105
- #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:43
106
- msgid "PayPal Commerce"
107
  msgstr ""
108
 
109
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:30
110
- msgid ""
111
- "Make sure to complete the entire PayPal process. Do not close the window you "
112
- "have finished the process."
113
  msgstr ""
114
 
115
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:31
116
- msgid ""
117
- "The last screen of the PayPal connect process includes a button to be sent "
118
- "back to your site. It is important you click this and do not close the "
119
- "window yourself."
120
  msgstr ""
121
 
122
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:32
123
- msgid "If you’re still having problems connecting:"
124
  msgstr ""
125
 
126
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:38
127
- msgid "Having trouble connecting to PayPal?"
128
  msgstr ""
129
 
130
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:64
131
- msgid ""
132
- "There was a problem with creating webhook on PayPal. A gateway error log "
133
- "also added to get details information about PayPal response."
134
  msgstr ""
135
 
136
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:94
137
- msgid "PayPal client access token API request response is:"
138
  msgstr ""
139
 
140
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:100
141
- msgid "PayPal client rest API credentials API request response is:"
142
  msgstr ""
143
 
144
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:104
145
- msgid ""
146
- "There was a problem with PayPal client rest API request and we could not "
147
- "find valid client id and secret."
148
  msgstr ""
149
 
150
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:133
151
- msgid "PayPal merchant status check API request response is:"
152
  msgstr ""
153
 
154
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:138
155
  msgid ""
156
- "A valid SSL certificate is required to accept payments and set up your "
157
- "PayPal account. Once a\n"
158
- "\t\t\t\t\tcertificate is installed and the site is using https, please "
159
- "disconnect and reconnect your account."
160
  msgstr ""
161
 
162
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:143
163
- msgid ""
164
- "There was a problem with the status check for your account. Please try "
165
- "disconnecting and connecting again. If the problem persists, please contact "
166
- "support."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  msgstr ""
168
 
169
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:156
170
- msgid "Set up an account to receive payment from PayPal"
 
171
  msgstr ""
172
 
173
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:160
174
- msgid "Confirm your primary email address"
175
  msgstr ""
176
 
177
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:168
178
- msgid ""
179
- "Your account was expected to be able to accept custom payments, but is not. "
180
- "Please make sure your\n"
181
- "\t\t\t\taccount country matches the country setting. If the problem "
182
- "persists, please contact PayPal."
183
  msgstr ""
184
 
185
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:186
186
- msgid "Reach out to PayPal to enable PPCP_CUSTOM for your account"
187
  msgstr ""
188
 
189
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:198
190
- msgid "Reach out to PayPal to resolve the following capabilities:"
191
  msgstr ""
192
 
193
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:226
194
- msgid "logged data"
195
  msgstr ""
196
 
197
- #. Translators: %1$s: The logged data link.
198
- #: src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php:233
199
- msgid ""
200
- "There was a problem setting up the webhooks for your PayPal account. Please "
201
- "try disconnecting and reconnecting your PayPal account. If the problem "
202
- "persists, please contact support and provide them with the latest %1$s"
203
  msgstr ""
204
 
205
- #: src/Tickets/Commerce/Gateways/PayPal/REST/On_Boarding_Endpoint.php:140
206
- msgid "Unexpected response from PayPal when on boarding"
207
  msgstr ""
208
 
209
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:236
210
- msgid "Order ID in PayPal"
211
  msgstr ""
212
 
213
  #. Translators: %s: The event type.
@@ -225,15 +4482,15 @@ msgstr ""
225
  msgid "Failed PayPal webhook event verification"
226
  msgstr ""
227
 
228
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php:218
229
  msgid "Processes the Webhook as long as it includes valid Payment Event data"
230
  msgstr ""
231
 
232
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php:225
233
  msgid "Whether the processing was successful"
234
  msgstr ""
235
 
236
- #: src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php:234
237
  msgid "The webhook was invalid and was not processed"
238
  msgstr ""
239
 
@@ -242,19 +4499,50 @@ msgid "-- Please select a country --"
242
  msgstr ""
243
 
244
  #. Translators: %s: The PayPal telephone number.
245
- #: src/Tickets/Commerce/Gateways/PayPal/Settings.php:85
246
  msgid "Please call a PayPal support representative at %s"
247
  msgstr ""
248
 
249
- #: src/Tickets/Commerce/Gateways/PayPal/Settings.php:89
250
  msgid ""
251
  "Please reach out to PayPal support from your PayPal account Resolution Center"
252
  msgstr ""
253
 
254
- #: src/Tickets/Commerce/Gateways/PayPal/Settings.php:92
255
  msgid " and relay the following message:"
256
  msgstr ""
257
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  #: src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php:77
259
  #: src/Tribe/Commerce/PayPal/Main.php:1908 src/Tribe/RSVP.php:2355
260
  msgid "Return to the %1$sAttendees Report%2$s."
@@ -292,6 +4580,23 @@ msgid ""
292
  "confirmation."
293
  msgstr ""
294
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  #. Translators: %s: The PayPal payment event.
296
  #: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Handler.php:72
297
  msgid "Missing PayPal payment for webhook event: %s"
@@ -312,23 +4617,57 @@ msgstr ""
312
  msgid "Change %1$s in PayPal from webhook: %2$s"
313
  msgstr ""
314
 
315
- #: src/Tickets/Commerce/Legacy_Compat.php:64
316
  msgid "Tribe Commerce ( Legacy PayPal, not recommended )"
317
  msgstr ""
318
 
319
- #: src/Tickets/Commerce/Models/Attendee_Model.php:71
320
  #: src/Tribe/Commerce/PayPal/Main.php:2959 src/Tribe/RSVP.php:2014
321
  msgid "(deleted)"
322
  msgstr ""
323
 
324
- #: src/Tickets/Commerce/Module.php:19
325
  msgid "Tickets Commerce"
326
  msgstr ""
327
 
328
- #: src/Tickets/Commerce/Order.php:163 src/Tribe/Commerce/PayPal/Main.php:468
 
 
329
  msgid "Orders"
330
  msgstr ""
331
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  #: src/Tickets/Commerce/Reports/Attendance_Totals.php:84
333
  #: src/Tribe/Commerce/PayPal/Attendance_Totals.php:77
334
  #: src/Tribe/RSVP/Attendance_Totals.php:49
@@ -348,82 +4687,132 @@ msgctxt "attendee summary"
348
  msgid "Cancelled:"
349
  msgstr ""
350
 
351
- #: src/Tickets/Commerce/Reports/Event.php:53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  #: src/Tribe/Commerce/PayPal/Main.php:1724
353
  msgid "Sales report"
354
  msgstr ""
355
 
356
- #: src/Tickets/Commerce/Reports/Ticket.php:38
357
  #: src/Tribe/Commerce/PayPal/Main.php:1750
358
  msgid "Report"
359
  msgstr ""
360
 
361
- #: src/Tickets/Commerce/Settings.php:121
362
- msgid "Payments"
363
- msgstr ""
364
-
365
- #: src/Tickets/Commerce/Settings.php:136 src/Tribe/Admin/Notices.php:214
366
- #: src/Tribe/Main.php:666 src/admin-views/admin-welcome-message.php:56
367
- #: src/admin-views/tribe-commerce-settings.php:4
368
- msgid "Event Tickets Plus"
369
  msgstr ""
370
 
371
- #: src/Tickets/Commerce/Settings.php:140
372
- #: src/admin-views/tribe-commerce-settings.php:9
373
- msgid "Check it out!"
374
  msgstr ""
375
 
376
- #. Translators: %1$s: The Event Tickets Plus link, %2$s: The word "ticket" in
377
- #. lowercase, %3$s: The "Check it out!" link.
378
- #: src/Tickets/Commerce/Settings.php:144
379
- msgctxt "about Tickets Commerce"
380
- msgid ""
381
- "Tickets Commerce is a light implementation of a commerce gateway using "
382
- "PayPal and simplified stock handling. If you need more advanced features, "
383
- "take a look at %1$s. In addition to integrating with your favorite ecommerce "
384
- "provider, Event Tickets Plus includes options to collect custom information "
385
- "for attendees, check users in via QR codes, and share stock between %2$s. "
386
- "%3$s"
387
  msgstr ""
388
 
389
- #: src/Tickets/Commerce/Settings.php:160
390
- msgid "Enable Tickets Commerce"
391
  msgstr ""
392
 
393
- #: src/Tickets/Commerce/Settings.php:206
394
  msgid "-- No page set --"
395
  msgstr ""
396
 
397
- #: src/Tickets/Commerce/Settings.php:221
398
  msgid "Tickets Commerce Settings"
399
  msgstr ""
400
 
401
- #: src/Tickets/Commerce/Settings.php:225
402
  msgid "Enable Test Mode"
403
  msgstr ""
404
 
405
- #: src/Tickets/Commerce/Settings.php:226
406
  msgid ""
407
  "Enables Test mode for testing payments. Any payments made will be done on "
408
  "\"sandbox\" accounts."
409
  msgstr ""
410
 
411
- #: src/Tickets/Commerce/Settings.php:232
412
  #: src/admin-views/tribe-commerce-settings.php:136
413
  msgid "Currency Code"
414
  msgstr ""
415
 
416
- #: src/Tickets/Commerce/Settings.php:233
417
  msgid "The currency that will be used for Tickets Commerce transactions."
418
  msgstr ""
419
 
420
- #: src/Tickets/Commerce/Settings.php:240
421
  #: src/admin-views/tribe-commerce-settings.php:144
422
  msgid "Stock Handling"
423
  msgstr ""
424
 
425
  #. Translators: %s: The word "ticket" in lowercase.
426
- #: src/Tickets/Commerce/Settings.php:244
427
  msgctxt "tickets fields settings paypal stock handling"
428
  msgid ""
429
  "When a customer purchases a %s, the payment gateway might flag the order as "
@@ -433,62 +4822,62 @@ msgstr ""
433
 
434
  #. Translators: %1$s: The word "ticket" in lowercase. %2$s: `<strong>` opening
435
  #. tag. %3$s: `</strong>` closing tag.
436
- #: src/Tickets/Commerce/Settings.php:253
437
  msgid ""
438
  "Decrease available %1$s stock as soon as a %2$sPending%3$s order is created."
439
  msgstr ""
440
 
441
  #. Translators: %1$s: The word "ticket" in lowercase. %2$s: `<strong>` opening
442
  #. tag. %3$s: `</strong>` closing tag.
443
- #: src/Tickets/Commerce/Settings.php:260
444
  msgid ""
445
  "Only decrease available %1$s stock if an order is confirmed as %2$sCompleted"
446
  "%3$s by the payment gateway."
447
  msgstr ""
448
 
449
- #: src/Tickets/Commerce/Settings.php:270
450
  msgid "Checkout page"
451
  msgstr ""
452
 
453
  #. Translators: %s: The [shortcode] for the success page.
454
- #: src/Tickets/Commerce/Settings.php:274
455
  msgid ""
456
  "This is the page where customers go to complete their purchase. Use the %s "
457
  "shortcode to display the checkout experience in the page content."
458
  msgstr ""
459
 
460
- #: src/Tickets/Commerce/Settings.php:285
461
  #: src/admin-views/tribe-commerce-settings.php:162
462
  msgid "Success page"
463
  msgstr ""
464
 
465
  #. Translators: %s: The [shortcode] for the success page.
466
- #: src/Tickets/Commerce/Settings.php:289
467
  msgid ""
468
  "After a successful order, users will be redirected to this page. Use the %s "
469
  "shortcode to display the order confirmation to the user in the page content."
470
  msgstr ""
471
 
472
- #: src/Tickets/Commerce/Settings.php:300
473
  #: src/admin-views/tribe-commerce-settings.php:176
474
  msgid "Confirmation email sender address"
475
  msgstr ""
476
 
477
  #. Translators: %s: The word "tickets" in lowercase.
478
- #: src/Tickets/Commerce/Settings.php:304
479
  msgctxt "tickets fields settings confirmation email"
480
  msgid ""
481
  "Email address that %s customers will receive confirmation from. Leave empty "
482
  "to use the default WordPress site email address."
483
  msgstr ""
484
 
485
- #: src/Tickets/Commerce/Settings.php:315
486
  #: src/admin-views/tribe-commerce-settings.php:185
487
  msgid "Confirmation email sender name"
488
  msgstr ""
489
 
490
  #. Translators: %s: The word "ticket" in lowercase.
491
- #: src/Tickets/Commerce/Settings.php:319
492
  #: src/admin-views/tribe-commerce-settings.php:186
493
  msgctxt "tickets fields settings paypal email sender"
494
  msgid ""
@@ -496,13 +4885,13 @@ msgid ""
496
  "purchase."
497
  msgstr ""
498
 
499
- #: src/Tickets/Commerce/Settings.php:330
500
  #: src/admin-views/tribe-commerce-settings.php:194
501
  msgid "Confirmation email subject"
502
  msgstr ""
503
 
504
  #. Translators: %s: The word "ticket" in lowercase.
505
- #: src/Tickets/Commerce/Settings.php:334
506
  #: src/admin-views/tribe-commerce-settings.php:195
507
  msgctxt "tickets fields settings paypal email subject"
508
  msgid ""
@@ -511,7 +4900,7 @@ msgid ""
511
  msgstr ""
512
 
513
  #. Translators: %s: The word "tickets" in lowercase.
514
- #: src/Tickets/Commerce/Settings.php:342
515
  #: src/admin-views/tribe-commerce-settings.php:197
516
  msgctxt "tickets fields settings paypal email subject"
517
  msgid "You have %s!"
@@ -547,31 +4936,31 @@ msgstr ""
547
  msgid "Pending"
548
  msgstr ""
549
 
550
- #: src/Tickets/Commerce/Status/Pending.php:93
551
  msgid "This order contained an invalid Ticket (ID: %1$d)"
552
  msgstr ""
553
 
554
- #: src/Tickets/Commerce/Status/Pending.php:108
555
  msgid "This order contained a Ticket with an invalid Event (Event ID: %1$d)"
556
  msgstr ""
557
 
558
- #: src/Tickets/Commerce/Status/Pending.php:122
559
  msgid "Cannot purchase zero of \"%1$s\""
560
  msgstr ""
561
 
562
- #: src/Tickets/Commerce/Status/Pending.php:139
563
  msgid "Insufficient stock for \"%1$s\""
564
  msgstr ""
565
 
566
- #: src/Tickets/Commerce/Status/Pending.php:155
567
  msgid "%s will be available on %s at %s"
568
  msgstr ""
569
 
570
- #: src/Tickets/Commerce/Status/Pending.php:157 src/Tribe/Tickets.php:3146
571
  msgid "%s are no longer available."
572
  msgstr ""
573
 
574
- #: src/Tickets/Commerce/Status/Pending.php:159 src/Tribe/Tickets.php:3148
575
  msgid "There are no %s available at this time."
576
  msgstr ""
577
 
@@ -579,10 +4968,6 @@ msgstr ""
579
  msgid "Refunded"
580
  msgstr ""
581
 
582
- #: src/Tickets/Commerce/Status/Reversed.php:27
583
- msgid "Reversed"
584
- msgstr ""
585
-
586
  #: src/Tickets/Commerce/Status/Undefined.php:28
587
  msgid "Undefined"
588
  msgstr ""
@@ -595,15 +4980,15 @@ msgstr ""
595
  msgid "Tickets Commerce Success Page"
596
  msgstr ""
597
 
598
- #: src/Tickets/Commerce/Ticket.php:118 src/Tribe/Commerce/PayPal/Main.php:440
599
  msgid "Tickets"
600
  msgstr ""
601
 
602
- #: src/Tickets/Commerce/Ticket.php:120
603
  msgid "Tickets Commerce Tickets"
604
  msgstr ""
605
 
606
- #: src/Tickets/Commerce/Ticket.php:121
607
  msgid "Tickets Commerce Ticket"
608
  msgstr ""
609
 
@@ -644,7 +5029,7 @@ msgid "Move %s Types"
644
  msgstr ""
645
 
646
  #: src/Tribe/Admin/Move_Ticket_Types.php:72
647
- #: src/Tribe/Admin/Move_Tickets.php:258
648
  msgid "All supported types"
649
  msgstr ""
650
 
@@ -672,7 +5057,7 @@ msgid ""
672
  msgstr ""
673
 
674
  #: src/Tribe/Admin/Move_Ticket_Types.php:320
675
- #: src/Tribe/Admin/Move_Tickets.php:753
676
  msgid "Changes to your tickets from %s"
677
  msgstr ""
678
 
@@ -702,33 +5087,33 @@ msgstr ""
702
  msgid "Loading, please wait&hellip;"
703
  msgstr ""
704
 
705
- #: src/Tribe/Admin/Move_Tickets.php:231
706
  msgctxt "attendee screen bulk actions"
707
  msgid "Move"
708
  msgstr ""
709
 
710
- #: src/Tribe/Admin/Move_Tickets.php:445
711
  msgid ""
712
  "%1$s could not be moved: valid %2$s IDs or a destination ID were not "
713
  "provided."
714
  msgstr ""
715
 
716
- #: src/Tribe/Admin/Move_Tickets.php:457
717
  msgid ""
718
  "%s could not be moved: there was an unexpected failure during reassignment."
719
  msgstr ""
720
 
721
- #: src/Tribe/Admin/Move_Tickets.php:466
722
  msgctxt "moved tickets success message fragment"
723
  msgid "assigned to %s"
724
  msgstr ""
725
 
726
- #: src/Tribe/Admin/Move_Tickets.php:473
727
  msgctxt "moved tickets success message fragment"
728
  msgid "moved to %s and"
729
  msgstr ""
730
 
731
- #: src/Tribe/Admin/Move_Tickets.php:480
732
  msgid ""
733
  "%1$d attendee for %2$s was successfully %3$s. By default, we adjust capacity "
734
  "and stock, however, we recommend reviewing each as needed to ensure numbers "
@@ -742,11 +5127,11 @@ msgid_plural ""
742
  msgstr[0] ""
743
  msgstr[1] ""
744
 
745
- #: src/Tribe/Admin/Move_Tickets.php:628
746
  msgid "This ticket was moved to %1$s %2$s from %3$s %4$s"
747
  msgstr ""
748
 
749
- #: src/Tribe/Admin/Move_Tickets.php:815
750
  msgid "This ticket was moved to %1$s from %2$s"
751
  msgstr ""
752
 
@@ -801,55 +5186,96 @@ msgid ""
801
  "for %2$s."
802
  msgstr ""
803
 
804
- #: src/Tribe/Admin/Settings/Service_Provider.php:49
805
  #: src/admin-views/admin-welcome-message.php:135
806
  msgid "Getting Started Guide"
807
  msgstr ""
808
 
809
- #: src/Tribe/Admin/Settings/Service_Provider.php:54
810
- msgid "Configuring PayPal for Ticket Purchases"
811
  msgstr ""
812
 
813
- #: src/Tribe/Admin/Settings/Service_Provider.php:58
814
- msgid "Configuring Tribe Commerce"
815
  msgstr ""
816
 
817
- #: src/Tribe/Admin/Settings/Service_Provider.php:62
818
- msgid "Using RSVPs"
819
  msgstr ""
820
 
821
- #: src/Tribe/Admin/Settings/Service_Provider.php:66
822
- msgid "Managing Orders and Attendees"
823
  msgstr ""
824
 
825
- #: src/Tribe/Admin/Settings/Service_Provider.php:70
826
- msgid "Event Tickets Manual"
827
  msgstr ""
828
 
829
- #: src/Tribe/Admin/Settings/Service_Provider.php:77
830
  msgid "Switching from Tribe Commerce to WooCommerce"
831
  msgstr ""
832
 
833
- #: src/Tribe/Admin/Settings/Service_Provider.php:81
834
  msgid "Setting Up E-Commerce Plugins for Selling Tickets"
835
  msgstr ""
836
 
837
- #: src/Tribe/Admin/Settings/Service_Provider.php:85
838
  msgid "Tickets & WooCommerce"
839
  msgstr ""
840
 
841
- #: src/Tribe/Admin/Settings/Service_Provider.php:89
842
  msgid "Creating Tickets"
843
  msgstr ""
844
 
845
- #: src/Tribe/Admin/Settings/Service_Provider.php:93
846
  msgid "Event Tickets and Event Tickets Plus Settings Overview"
847
  msgstr ""
848
 
849
- #: src/Tribe/Admin/Settings/Service_Provider.php:97
850
  msgid "Event Tickets Plus Manual"
851
  msgstr ""
852
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
853
  #: src/Tribe/Admin/Ticket_History.php:34
854
  msgctxt "attendee table"
855
  msgid "View history"
@@ -872,29 +5298,29 @@ msgstr ""
872
  msgid "Unticketed"
873
  msgstr ""
874
 
875
- #: src/Tribe/Assets.php:196 src/views/tickets/tpp-success.php:97
876
  msgid "%s header image"
877
  msgstr ""
878
 
879
- #: src/Tribe/Assets.php:197
880
  msgid "Set as %s header"
881
  msgstr ""
882
 
883
- #: src/Tribe/Assets.php:253
884
  msgid "Are you sure you want to delete this ticket? This cannot be undone."
885
  msgstr ""
886
 
887
- #: src/Tribe/Assets.php:259
888
  msgid ""
889
  "It looks like you have modified your shared capacity setting but have not "
890
  "saved or updated the post."
891
  msgstr ""
892
 
893
- #: src/Tribe/Assets.php:279 src/Tribe/Metabox.php:575
894
  msgid "Please enter in without thousand separators and currency symbols."
895
  msgstr ""
896
 
897
- #: src/Tribe/Assets.php:472
898
  msgid ""
899
  "There is unsaved attendee information. Are you sure you want to continue?"
900
  msgstr ""
@@ -904,286 +5330,125 @@ msgctxt "attendee summary"
904
  msgid "Deleted Attendees:"
905
  msgstr ""
906
 
907
- #: src/Tribe/Attendee_Registration/Template.php:398
908
- #: src/views/v2/rsvp/ari/sidebar/title.php:15
909
- msgid "Attendee Registration"
910
- msgstr ""
911
-
912
- #: src/Tribe/Attendees.php:84
913
- msgid "Post type"
914
- msgstr ""
915
-
916
- #: src/Tribe/Attendees.php:113
917
- msgctxt "attendee event actions"
918
- msgid "Edit %s"
919
- msgstr ""
920
-
921
- #: src/Tribe/Attendees.php:114
922
- msgctxt "attendee event actions"
923
- msgid "View %s"
924
- msgstr ""
925
-
926
- #: src/Tribe/Attendees.php:117
927
- msgctxt "attendee event actions"
928
- msgid "Edit"
929
- msgstr ""
930
-
931
- #: src/Tribe/Attendees.php:118
932
- msgctxt "attendee event actions"
933
- msgid "View"
934
- msgstr ""
935
-
936
- #: src/Tribe/Attendees.php:145
937
- msgctxt "attendee summary"
938
- msgid "Checked in:"
939
- msgstr ""
940
-
941
- #: src/Tribe/Attendees.php:210 src/admin-views/list.php:93
942
- msgid "See who purchased tickets to this event"
943
- msgstr ""
944
-
945
- #: src/Tribe/Attendees.php:320
946
- msgid "You need to select a user or type a valid email address"
947
- msgstr ""
948
-
949
- #: src/Tribe/Attendees.php:321
950
- msgid "Sending..."
951
- msgstr ""
952
-
953
- #: src/Tribe/Attendees.php:325
954
- msgid "You must first select one or more tickets before you can move them!"
955
- msgstr ""
956
-
957
- #: src/Tribe/Attendees.php:327
958
- msgid "Please confirm that you would like to delete this attendee."
959
- msgstr ""
960
-
961
- #: src/Tribe/Attendees.php:328
962
- msgid "Please confirm you would like to delete these attendees."
963
- msgstr ""
964
-
965
- #: src/Tribe/Attendees.php:363
966
- msgid "Columns"
967
- msgstr ""
968
-
969
- #: src/Tribe/Attendees.php:363
970
- msgid ""
971
- "You can use Screen Options to select which columns you want to see. The "
972
- "selection works in the table below, in the email, for print and for the CSV "
973
- "export."
974
- msgstr ""
975
-
976
- #: src/Tribe/Attendees.php:441
977
- msgid "%s - Attendee list"
978
- msgstr ""
979
-
980
- #: src/Tribe/Attendees.php:514
981
- msgctxt "attendee export"
982
- msgid "Order ID"
983
  msgstr ""
984
 
985
- #: src/Tribe/Attendees.php:515
986
- msgctxt "attendee export"
987
- msgid "Order Status"
988
  msgstr ""
989
 
990
- #: src/Tribe/Attendees.php:516
991
- msgctxt "attendee export"
992
- msgid "%s ID"
993
  msgstr ""
994
 
995
- #: src/Tribe/Attendees.php:517
996
- msgctxt "attendee export"
997
- msgid "Ticket Holder Name"
998
  msgstr ""
999
 
1000
- #: src/Tribe/Attendees.php:518
1001
- msgctxt "attendee export"
1002
- msgid "Ticket Holder Email Address"
1003
  msgstr ""
1004
 
1005
- #: src/Tribe/Attendees.php:519
1006
- msgctxt "attendee export"
1007
- msgid "Purchaser Name"
1008
  msgstr ""
1009
 
1010
- #: src/Tribe/Attendees.php:520
1011
- msgctxt "attendee export"
1012
- msgid "Purchaser Email Address"
1013
  msgstr ""
1014
 
1015
- #: src/Tribe/Attendees.php:549 src/admin-views/tribe-commerce-settings.php:93
1016
- #: src/admin-views/tribe-commerce-settings.php:105
1017
- msgid "Yes"
1018
  msgstr ""
1019
 
1020
- #: src/Tribe/Attendees.php:660
1021
- msgid "attendees"
1022
  msgstr ""
1023
 
1024
- #: src/Tribe/Attendees.php:698
1025
  msgid "Invalid Event ID"
1026
  msgstr ""
1027
 
1028
- #: src/Tribe/Attendees.php:715
1029
  msgid "Cheatin Huh?"
1030
  msgstr ""
1031
 
1032
- #: src/Tribe/Attendees.php:721
1033
  msgid "Empty user and email"
1034
  msgstr ""
1035
 
1036
- #: src/Tribe/Attendees.php:733
1037
  msgid "Invalid Email"
1038
  msgstr ""
1039
 
1040
- #: src/Tribe/Attendees.php:739 src/Tribe/Attendees.php:755
1041
  msgid "Invalid User ID"
1042
  msgstr ""
1043
 
1044
- #: src/Tribe/Attendees.php:775
1045
  msgid "Attendee List for: %s"
1046
  msgstr ""
1047
 
1048
- #: src/Tribe/Attendees.php:776
1049
  msgid "Error when sending the email"
1050
  msgstr ""
1051
 
1052
- #: src/Tribe/Attendees.php:783
1053
  msgid "Email sent successfully!"
1054
  msgstr ""
1055
 
1056
- #: src/Tribe/Attendees.php:998 src/Tribe/Attendees_Table.php:598
 
1057
  msgid "Export"
1058
  msgstr ""
1059
 
1060
- #: src/Tribe/Attendees_Table.php:65
1061
- msgid "Number of attendees per page:"
1062
- msgstr ""
1063
-
1064
- #: src/Tribe/Attendees_Table.php:117
1065
  msgctxt "attendee table"
1066
  msgid "Primary Information"
1067
  msgstr ""
1068
 
1069
- #: src/Tribe/Attendees_Table.php:118
1070
  msgctxt "attendee table"
1071
  msgid "Security Code"
1072
  msgstr ""
1073
 
1074
- #: src/Tribe/Attendees_Table.php:119
1075
  msgctxt "attendee table"
1076
  msgid "Status"
1077
  msgstr ""
1078
 
1079
- #: src/Tribe/Attendees_Table.php:120 src/Tribe/Attendees_Table.php:127
1080
  msgctxt "attendee table"
1081
  msgid "Check in"
1082
  msgstr ""
1083
 
1084
- #: src/Tribe/Attendees_Table.php:393
1085
- msgctxt "row action"
1086
- msgid "Check In"
1087
- msgstr ""
1088
-
1089
- #: src/Tribe/Attendees_Table.php:394
1090
- msgctxt "row action"
1091
- msgid "Undo Check In"
1092
- msgstr ""
1093
-
1094
- #: src/Tribe/Attendees_Table.php:403
1095
- msgctxt "row action"
1096
- msgid "Move"
1097
- msgstr ""
1098
-
1099
- #: src/Tribe/Attendees_Table.php:415
1100
- msgctxt "row action"
1101
- msgid "Delete"
1102
- msgstr ""
1103
-
1104
- #: src/Tribe/Attendees_Table.php:495
1105
  msgid "View order"
1106
  msgstr ""
1107
 
1108
- #: src/Tribe/Attendees_Table.php:597
1109
  msgid "Print"
1110
  msgstr ""
1111
 
1112
- #: src/Tribe/Attendees_Table.php:605
1113
- #: src/Tribe/Commerce/PayPal/Orders/Table.php:100 src/Tribe/Privacy.php:189
1114
- #: src/Tribe/Privacy.php:470 src/Tribe/Privacy.php:566
1115
- #: src/views/blocks/rsvp/form/email.php:32 src/views/tickets/rsvp.php:237
1116
- #: src/views/v2/rsvp/ari/form/fields/email.php:33
1117
- #: src/views/v2/rsvp/form/fields/email.php:34
1118
- msgid "Email"
1119
- msgstr ""
1120
-
1121
- #: src/Tribe/Attendees_Table.php:632 src/admin-views/list.php:41
1122
  msgid "Delete"
1123
  msgstr ""
1124
 
1125
- #: src/Tribe/Attendees_Table.php:633
1126
  msgid "Check in"
1127
  msgstr ""
1128
 
1129
- #: src/Tribe/Attendees_Table.php:634
1130
  msgid "Undo Check in"
1131
  msgstr ""
1132
 
1133
- #: src/Tribe/Attendees_Table.php:961
1134
- msgid "No matching attendees found."
1135
- msgstr ""
1136
-
1137
- #: src/Tribe/Attendees_Table.php:975
1138
- msgctxt "Attendees Table search options"
1139
- msgid "Search by Purchaser Name"
1140
- msgstr ""
1141
-
1142
- #: src/Tribe/Attendees_Table.php:976
1143
- msgctxt "Attendees Table search options"
1144
- msgid "Search by Purchaser Email"
1145
- msgstr ""
1146
-
1147
- #: src/Tribe/Attendees_Table.php:977
1148
- msgctxt "Attendees Table search options"
1149
- msgid "Search by Ticket Holder Name"
1150
- msgstr ""
1151
-
1152
- #: src/Tribe/Attendees_Table.php:978
1153
- msgctxt "Attendees Table search options"
1154
- msgid "Search by Ticket Holder Email"
1155
- msgstr ""
1156
-
1157
- #: src/Tribe/Attendees_Table.php:979
1158
- msgctxt "Attendees Table search options"
1159
- msgid "Search by User ID"
1160
- msgstr ""
1161
-
1162
- #: src/Tribe/Attendees_Table.php:980
1163
- msgctxt "Attendees Table search options"
1164
- msgid "Search by Order Status"
1165
- msgstr ""
1166
-
1167
- #: src/Tribe/Attendees_Table.php:981
1168
- msgctxt "Attendees Table search options"
1169
- msgid "Search by Order ID"
1170
- msgstr ""
1171
-
1172
- #: src/Tribe/Attendees_Table.php:982
1173
- msgctxt "Attendees Table search options"
1174
- msgid "Search by Security Code"
1175
- msgstr ""
1176
-
1177
- #: src/Tribe/Attendees_Table.php:983
1178
- msgctxt "Attendees Table search options"
1179
- msgid "Search by %s ID"
1180
- msgstr ""
1181
-
1182
- #: src/Tribe/Attendees_Table.php:984
1183
- msgctxt "Attendees Table search options"
1184
- msgid "Search by Product ID"
1185
- msgstr ""
1186
-
1187
  #: src/Tribe/CSV_Importer/Column_Names.php:34
1188
  msgid "Event Name or ID or Slug"
1189
  msgstr ""
@@ -1425,17 +5690,19 @@ msgid "See PayPal purchases for this %s"
1425
  msgstr ""
1426
 
1427
  #: src/Tribe/Commerce/PayPal/Orders/Report.php:108
1428
- #: src/Tribe/Commerce/PayPal/Orders/Report.php:157
1429
  #: src/Tribe/Commerce/PayPal/Orders/Tab.php:33
1430
  msgid "PayPal Orders"
1431
  msgstr ""
1432
 
1433
- #: src/Tribe/Commerce/PayPal/Orders/Report.php:216
1434
  msgctxt "Browser title"
1435
  msgid "%s - PayPal Orders"
1436
  msgstr ""
1437
 
1438
- #: src/Tribe/Commerce/PayPal/Orders/Report.php:321
 
 
1439
  msgid "Search Orders"
1440
  msgstr ""
1441
 
@@ -1447,43 +5714,10 @@ msgstr ""
1447
  msgid "Number of orders per page:"
1448
  msgstr ""
1449
 
1450
- #: src/Tribe/Commerce/PayPal/Orders/Table.php:98
1451
- msgid "Order"
1452
- msgstr ""
1453
-
1454
- #: src/Tribe/Commerce/PayPal/Orders/Table.php:99
1455
- msgid "Purchaser"
1456
- msgstr ""
1457
-
1458
- #: src/Tribe/Commerce/PayPal/Orders/Table.php:101
1459
- msgid "Purchased"
1460
- msgstr ""
1461
-
1462
- #: src/Tribe/Commerce/PayPal/Orders/Table.php:102 src/Tribe/Privacy.php:194
1463
- #: src/Tribe/Privacy.php:475 src/Tribe/Privacy.php:571
1464
- msgid "Date"
1465
- msgstr ""
1466
-
1467
- #: src/Tribe/Commerce/PayPal/Orders/Table.php:103
1468
- msgid "Status"
1469
- msgstr ""
1470
-
1471
- #: src/Tribe/Commerce/PayPal/Orders/Table.php:106
1472
- msgid "Total"
1473
- msgstr ""
1474
-
1475
- #: src/Tribe/Commerce/PayPal/Orders/Table.php:177
1476
- msgid "%1$s"
1477
- msgstr ""
1478
-
1479
  #: src/Tribe/Commerce/PayPal/Orders/Table.php:184
1480
  msgid "Refunded with %s"
1481
  msgstr ""
1482
 
1483
- #: src/Tribe/Commerce/PayPal/Orders/Table.php:274
1484
- msgid "No matching orders found."
1485
- msgstr ""
1486
-
1487
  #: src/Tribe/Commerce/PayPal/Oversell/Admin_Notice_Decorator.php:111
1488
  msgid "An event"
1489
  msgstr ""
@@ -1557,27 +5791,28 @@ msgstr ""
1557
  msgid "Are you sure you want to cancel?"
1558
  msgstr ""
1559
 
1560
- #: src/Tribe/Editor/Blocks/Tickets.php:297 src/Tribe/Tickets.php:4202
1561
  msgctxt "Error message title, will be followed by the error code."
1562
  msgid "API Error"
1563
  msgstr ""
1564
 
1565
- #: src/Tribe/Editor/Blocks/Tickets.php:298 src/Tribe/Tickets.php:4203
1566
  msgid ""
1567
  "Refresh this page or wait a few minutes before trying again. If this happens "
1568
  "repeatedly, please contact the Site Admin."
1569
  msgstr ""
1570
 
1571
- #: src/Tribe/Editor/Blocks/Tickets.php:299 src/Tribe/Tickets.php:4204
1572
  msgid ""
1573
  "The ticket for this event has sold out and has been removed from your cart."
1574
  msgstr ""
1575
 
1576
- #: src/Tribe/Editor/Blocks/Tickets.php:300 src/Tribe/Tickets.php:4205
 
1577
  msgid "Whoops!"
1578
  msgstr ""
1579
 
1580
- #: src/Tribe/Editor/Blocks/Tickets.php:301 src/Tribe/Tickets.php:4206
1581
  msgctxt "The %s will change based on the error produced."
1582
  msgid "You have %s ticket(s) with a field that requires information."
1583
  msgstr ""
@@ -2742,14 +6977,17 @@ msgid "pending order completion"
2742
  msgstr ""
2743
 
2744
  #: src/Tribe/Status/Abstract_Commerce.php:246
 
2745
  msgid "Sold counts tickets from completed orders only."
2746
  msgstr ""
2747
 
2748
  #: src/Tribe/Status/Abstract_Commerce.php:266
 
2749
  msgid "Total Sales counts %s from all completed orders."
2750
  msgstr ""
2751
 
2752
  #: src/Tribe/Status/Abstract_Commerce.php:282
 
2753
  msgid ""
2754
  "Total Ordered counts tickets from orders of any status, including pending "
2755
  "and refunded."
@@ -2768,46 +7006,46 @@ msgstr ""
2768
  msgid "Capacity"
2769
  msgstr ""
2770
 
2771
- #: src/Tribe/Tickets.php:471
2772
  msgctxt "delete link"
2773
  msgid "Delete %s"
2774
  msgstr ""
2775
 
2776
- #: src/Tribe/Tickets.php:553
2777
  msgid "Move %s"
2778
  msgstr ""
2779
 
2780
- #: src/Tribe/Tickets.php:1756
2781
  msgid "Shared capacity with other tickets"
2782
  msgstr ""
2783
 
2784
- #: src/Tribe/Tickets.php:1757
2785
  msgid "Set capacity for this ticket only"
2786
  msgstr ""
2787
 
2788
  #. translators: %1$s: The singular of "RSVP" or "ticket", %2$s: The plural of
2789
  #. "RSVPs" or "tickets", %3$s: The site name.
2790
- #: src/Tribe/Tickets.php:2374
2791
  msgctxt "The default RSVP/ticket email subject"
2792
  msgid "Your %1$s from %3$s"
2793
  msgid_plural "Your %2$s from %3$s"
2794
  msgstr[0] ""
2795
  msgstr[1] ""
2796
 
2797
- #: src/Tribe/Tickets.php:3098
2798
  msgid "%s are not available as this %s has passed."
2799
  msgstr ""
2800
 
2801
- #: src/Tribe/Tickets.php:3134
2802
  msgid "%s will be available on "
2803
  msgstr ""
2804
 
2805
- #: src/Tribe/Tickets.php:3140
2806
  msgid " at "
2807
  msgstr ""
2808
 
2809
  #. translators: %s: Tickets label
2810
- #: src/Tribe/Tickets.php:3143 src/views/blocks/tickets/content-inactive.php:19
2811
  #: src/views/v2/tickets/item/content/inactive.php:53
2812
  #: src/views/v2/tickets/item/inactive.php:63
2813
  msgid "%s are not yet available"
@@ -2894,7 +7132,7 @@ msgstr ""
2894
 
2895
  #: src/admin-views/admin-welcome-message.php:102
2896
  #: src/admin-views/admin-welcome-message.php:112
2897
- msgid "Setup PayPal"
2898
  msgstr ""
2899
 
2900
  #: src/admin-views/admin-welcome-message.php:118
@@ -2945,12 +7183,6 @@ msgstr ""
2945
  msgid "Need a language other than English? We've got you covered here."
2946
  msgstr ""
2947
 
2948
- #: src/admin-views/admin-welcome-message.php:157
2949
- #: src/admin-views/admin-welcome-message.php:179
2950
- #: src/admin-views/admin-welcome-message.php:199
2951
- msgid "Learn more"
2952
- msgstr ""
2953
-
2954
  #: src/admin-views/admin-welcome-message.php:164
2955
  msgid "Illustration of a phone screen with a person's face"
2956
  msgstr ""
@@ -3033,41 +7265,39 @@ msgstr ""
3033
  msgid "Select..."
3034
  msgstr ""
3035
 
3036
- #: src/admin-views/attendees-email.php:27
3037
  msgid "Send the attendee list by email"
3038
  msgstr ""
3039
 
3040
- #: src/admin-views/attendees-email.php:33
3041
  msgid "Select a User:"
3042
  msgstr ""
3043
 
3044
- #: src/admin-views/attendees-email.php:36
3045
  #: src/views/modal/registration-js.php:129
3046
  msgid "or"
3047
  msgstr ""
3048
 
3049
- #: src/admin-views/attendees-email.php:38
3050
  msgid "Email Address:"
3051
  msgstr ""
3052
 
3053
- #: src/admin-views/attendees-email.php:59
3054
  msgid "Send Email"
3055
  msgstr ""
3056
 
3057
- #: src/admin-views/attendees-table/check-in-button.php:23
3058
- msgid "Check In"
3059
- msgstr ""
3060
-
3061
  #: src/admin-views/attendees-table/check-in-button.php:31
3062
  msgid "Undo Check In"
3063
  msgstr ""
3064
 
3065
  #: src/admin-views/attendees.php:71
 
3066
  msgctxt "attendee screen summary"
3067
  msgid "%s Details"
3068
  msgstr ""
3069
 
3070
  #: src/admin-views/attendees.php:113
 
3071
  msgctxt "attendee screen summary"
3072
  msgid "Overview"
3073
  msgstr ""
@@ -3089,16 +7319,37 @@ msgstr ""
3089
  msgid "Leave blank for unlimited"
3090
  msgstr ""
3091
 
3092
- #: src/admin-views/commerce/metabox/sku.php:23
3093
  #: src/admin-views/tpp-metabox-sku.php:20
3094
  msgid "SKU:"
3095
  msgstr ""
3096
 
3097
- #: src/admin-views/commerce/metabox/sku.php:36
3098
  #: src/admin-views/tpp-metabox-sku.php:33
3099
  msgid "A unique identifying code for each %s type you're selling"
3100
  msgstr ""
3101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3102
  #: src/admin-views/editor/button-view-orders.php:46
3103
  msgid "View Orders"
3104
  msgstr ""
@@ -3745,66 +7996,90 @@ msgstr ""
3745
  msgid "Beginner Resources"
3746
  msgstr ""
3747
 
3748
- #: src/admin-views/settings/getting-started.php:35
3749
  msgid "Advanced Plus Features"
3750
  msgstr ""
3751
 
3752
- #: src/admin-views/settings/getting-started.php:38
3753
  msgid "Need To Upgrade?"
3754
  msgstr ""
3755
 
3756
- #: src/admin-views/settings/tickets-commerce/paypal/connect/active/connection.php:26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3757
  msgid "Connected as:"
3758
  msgstr ""
3759
 
3760
- #: src/admin-views/settings/tickets-commerce/paypal/connect/active/connection.php:36
3761
  msgid "Disconnect"
3762
  msgstr ""
3763
 
3764
- #: src/admin-views/settings/tickets-commerce/paypal/connect/active/paypal-status.php:23
3765
  msgid "PayPal Status:"
3766
  msgstr ""
3767
 
3768
- #: src/admin-views/settings/tickets-commerce/paypal/connect/active/paypal-status.php:27
3769
  msgid "Connected"
3770
  msgstr ""
3771
 
3772
- #: src/admin-views/settings/tickets-commerce/paypal/connect/active.php:22
3773
- msgid "Refresh Access Token"
3774
  msgstr ""
3775
 
3776
- #: src/admin-views/settings/tickets-commerce/paypal/connect/active.php:25
3777
- msgid "Refresh User Info"
3778
  msgstr ""
3779
 
3780
- #: src/admin-views/settings/tickets-commerce/paypal/connect/active.php:28
3781
- msgid "Refresh Webhook"
3782
  msgstr ""
3783
 
3784
- #: src/admin-views/settings/tickets-commerce/paypal/connect/inactive.php:23
 
 
 
 
3785
  msgid "Accept online payments with PayPal!"
3786
  msgstr ""
3787
 
3788
- #: src/admin-views/settings/tickets-commerce/paypal/connect/inactive.php:28
3789
  msgid ""
3790
  "Start selling tickets to your events today with PayPal. Attendees can "
3791
- "purchase tickets directly on your site using debt or credit cards with no "
3792
  "additional fees."
3793
  msgstr ""
3794
 
3795
- #: src/admin-views/settings/tickets-commerce/paypal/connect/logo/features.php:23
3796
  msgid "Credit and debit card payments"
3797
  msgstr ""
3798
 
3799
- #: src/admin-views/settings/tickets-commerce/paypal/connect/logo/features.php:26
3800
  msgid "Easy no-API key connection"
3801
  msgstr ""
3802
 
3803
- #: src/admin-views/settings/tickets-commerce/paypal/connect/logo/features.php:29
3804
  msgid "Accept payments from around the world"
3805
  msgstr ""
3806
 
3807
- #: src/admin-views/settings/tickets-commerce/paypal/connect/logo/features.php:32
3808
  msgid "Supports 3D Secure payments"
3809
  msgstr ""
3810
 
@@ -3812,7 +8087,11 @@ msgstr ""
3812
  msgid "PayPal Logo Image"
3813
  msgstr ""
3814
 
3815
- #: src/admin-views/settings/tickets-commerce/paypal/signup-link.php:26
 
 
 
 
3816
  msgid "Connect Automatically with <i>PayPal</i>"
3817
  msgstr ""
3818
 
@@ -3829,27 +8108,6 @@ msgstr ""
3829
  msgid "Click to hide history"
3830
  msgstr ""
3831
 
3832
- #: src/admin-views/tpp-orders.php:32
3833
- msgid "Orders Report"
3834
- msgstr ""
3835
-
3836
- #: src/admin-views/tpp-orders.php:62
3837
- msgctxt "post type details"
3838
- msgid "%s Details"
3839
- msgstr ""
3840
-
3841
- #: src/admin-views/tpp-orders.php:107
3842
- msgid "Sales by %s Type"
3843
- msgstr ""
3844
-
3845
- #: src/admin-views/tpp-orders.php:132
3846
- msgid "Total %s Sales"
3847
- msgstr ""
3848
-
3849
- #: src/admin-views/tpp-orders.php:150
3850
- msgid "Total %s Ordered"
3851
- msgstr ""
3852
-
3853
  #: src/admin-views/tribe-commerce-settings.php:13
3854
  msgctxt "about Tribe Commerce"
3855
  msgid ""
@@ -3857,8 +8115,8 @@ msgid ""
3857
  "and simplified stock handling. If you need more advanced features, take a "
3858
  "look at %1$s. In addition to integrating with your favorite ecommerce "
3859
  "provider, Event Tickets Plus includes options to collect custom information "
3860
- "for attendees, check users in via QR codes, and share stock between %2$s. "
3861
- "%3$s"
3862
  msgstr ""
3863
 
3864
  #: src/admin-views/tribe-commerce-settings.php:40
@@ -3883,10 +8141,6 @@ msgstr ""
3883
  msgid "Your site address is: %s"
3884
  msgstr ""
3885
 
3886
- #: src/admin-views/tribe-commerce-settings.php:55
3887
- msgid "Tribe Commerce"
3888
- msgstr ""
3889
-
3890
  #: src/admin-views/tribe-commerce-settings.php:63
3891
  msgid "Enable Tribe Commerce "
3892
  msgstr ""
@@ -4263,7 +8517,8 @@ msgstr[1] ""
4263
 
4264
  #: src/views/blocks/attendees/view-link.php:40
4265
  #: src/views/tickets/orders-pp-tickets.php:30
4266
- #: src/views/tickets/orders-rsvp.php:28 src/views/tickets/orders.php:92
 
4267
  #: src/views/tickets/view-link.php:56
4268
  msgctxt "fallback post type singular name"
4269
  msgid "Post"
@@ -4732,13 +8987,11 @@ msgctxt "ticket type email heading"
4732
  msgid "%s Type"
4733
  msgstr ""
4734
 
4735
- #: src/views/tickets/email.php:456
4736
- msgid "Security Code"
4737
- msgstr ""
4738
-
4739
  #. Translators: 1: plural RSVP label, 2: post type label.
 
4740
  #: src/views/tickets/orders-pp-tickets.php:38
4741
  #: src/views/tickets/orders-rsvp.php:37
 
4742
  msgid "My %1$s for this %2$s"
4743
  msgstr ""
4744
 
@@ -4754,6 +9007,7 @@ msgstr ""
4754
 
4755
  #: src/views/tickets/orders-pp-tickets.php:77
4756
  #: src/views/tickets/orders-rsvp.php:78
 
4757
  msgid "Attendee %d"
4758
  msgstr ""
4759
 
@@ -4777,22 +9031,29 @@ msgctxt "order status label"
4777
  msgid "RSVP: "
4778
  msgstr ""
4779
 
4780
- #: src/views/tickets/orders.php:76
 
 
 
 
 
 
 
4781
  msgctxt "notice if user does not have tickets"
4782
  msgid "You don't have %s for this event"
4783
  msgstr ""
4784
 
4785
- #: src/views/tickets/orders.php:81
4786
  msgctxt "notice if user does not have rsvps"
4787
  msgid "You don't have %s for this event"
4788
  msgstr ""
4789
 
4790
  #. Translators: %s: post type label.
4791
- #: src/views/tickets/orders.php:101
4792
  msgid "View %s"
4793
  msgstr ""
4794
 
4795
- #: src/views/tickets/orders.php:160
4796
  msgid "Update %s"
4797
  msgstr ""
4798
 
@@ -4924,11 +9185,12 @@ msgctxt "Closes the ticket description"
4924
  msgid "Less info"
4925
  msgstr ""
4926
 
4927
- #: src/views/v2/commerce/checkout/footer/gateway-error.php:41
 
4928
  msgid "Checkout Unavailable!"
4929
  msgstr ""
4930
 
4931
- #: src/views/v2/commerce/checkout/footer/gateway-error.php:42
4932
  msgid ""
4933
  "Checkout is not available at this time because a payment method has not been "
4934
  "set up. Please notify the site administrator."
@@ -4943,10 +9205,6 @@ msgstr ""
4943
  msgid "back"
4944
  msgstr ""
4945
 
4946
- #: src/views/v2/commerce/checkout/header/links/modify-attendees.php:37
4947
- msgid "modify attendees"
4948
- msgstr ""
4949
-
4950
  #. Translators: %1$s: Plural `Tickets` label.
4951
  #: src/views/v2/commerce/checkout/header/title.php:31
4952
  msgid "Purchase %1$s"
@@ -4965,8 +9223,51 @@ msgstr ""
4965
  msgid "create a new account"
4966
  msgstr ""
4967
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4968
  #. Translators: %1$s: Plural `tickets` in lowercase.
4969
- #: src/views/v2/commerce/order/description.php:29
4970
  msgid ""
4971
  "Thank you. Your order has been received. A receipt for purchase and any "
4972
  "digital %1$s ordered will be emailed to you shortly."
@@ -4984,7 +9285,7 @@ msgstr ""
4984
  msgid "Order number:"
4985
  msgstr ""
4986
 
4987
- #: src/views/v2/commerce/order/details/payment-method.php:31
4988
  msgid "Payment method:"
4989
  msgstr ""
4990
 
@@ -4992,16 +9293,16 @@ msgstr ""
4992
  msgid "Total:"
4993
  msgstr ""
4994
 
4995
- #: src/views/v2/commerce/order/footer/links/back-home.php:28
4996
  msgid "back home"
4997
  msgstr ""
4998
 
4999
  #. Translators: %1$s: Plural `events` in lowercase.
5000
- #: src/views/v2/commerce/order/footer/links/browse-events.php:35
5001
  msgid "browse more %1$s"
5002
  msgstr ""
5003
 
5004
- #: src/views/v2/commerce/order/header.php:27
5005
  msgid "Order Received!"
5006
  msgstr ""
5007
 
2
  # This file is distributed under the same license as the Event Tickets package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Event Tickets 5.2.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/event-tickets\n"
7
+ "POT-Creation-Date: 2021-11-03 17:18:01+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2021-11-03 17:18\n"
12
  "Last-Translator: \n"
13
  "Language-Team: \n"
14
 
15
+ #. #-#-#-#-# event-tickets.pot (Event Tickets 5.2.0) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
  #: event-tickets.php:61 src/Tribe/Admin/Notices.php:92 src/Tribe/Main.php:691
18
  #: src/Tribe/Privacy.php:59 src/admin-views/admin-welcome-message.php:58
19
  msgid "Event Tickets"
20
  msgstr ""
21
 
22
+ #: src/Tickets/Commerce/Admin/Notices.php:70
23
+ #: src/Tickets/Commerce/Admin/Notices.php:115
24
+ msgid "Learn More"
25
+ msgstr ""
26
+
27
+ #: src/Tickets/Commerce/Admin/Notices.php:72
28
+ msgid "Set up your checkout page"
29
+ msgstr ""
30
+
31
+ #. translators: %1$s: Link to knowledgebase article.
32
+ #: src/Tickets/Commerce/Admin/Notices.php:75
33
+ msgid ""
34
+ "In order to start selling with Tickets Commerce, you'll need to set up your "
35
+ "checkout page. Please configure the setting on Settings > Payments and "
36
+ "confirm that the page you have selected has the proper shortcode. %1$s"
37
+ msgstr ""
38
+
39
+ #: src/Tickets/Commerce/Admin/Notices.php:117
40
+ msgid "Set up your order success page"
41
+ msgstr ""
42
+
43
+ #. translators: %1$s: Link to knowledgebase article.
44
+ #: src/Tickets/Commerce/Admin/Notices.php:120
45
+ msgid ""
46
+ "In order to start selling with Tickets Commerce, you'll need to set up your "
47
+ "order success page. Please configure the setting on Settings > Payments and "
48
+ "confirm that the page you have selected has the proper shortcode. %1$s"
49
+ msgstr ""
50
+
51
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:77
52
+ #: src/Tribe/Attendees_Table.php:66
53
+ msgid "Number of attendees per page:"
54
+ msgstr ""
55
+
56
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:153
57
+ #: src/Tribe/Attendees.php:320
58
+ msgid "You need to select a user or type a valid email address"
59
+ msgstr ""
60
+
61
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:154
62
+ #: src/Tribe/Attendees.php:321
63
+ msgid "Sending..."
64
+ msgstr ""
65
+
66
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:158
67
+ #: src/Tribe/Attendees.php:325
68
+ msgid "You must first select one or more tickets before you can move them!"
69
+ msgstr ""
70
+
71
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:160
72
+ #: src/Tribe/Attendees.php:327
73
+ msgid "Please confirm that you would like to delete this attendee."
74
+ msgstr ""
75
+
76
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:161
77
+ #: src/Tribe/Attendees.php:328
78
+ msgid "Please confirm you would like to delete these attendees."
79
+ msgstr ""
80
+
81
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:193
82
+ #: src/Tribe/Attendees.php:363
83
+ msgid "Columns"
84
+ msgstr ""
85
+
86
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:193
87
+ #: src/Tribe/Attendees.php:363
88
+ msgid ""
89
+ "You can use Screen Options to select which columns you want to see. The "
90
+ "selection works in the table below, in the email, for print and for the CSV "
91
+ "export."
92
+ msgstr ""
93
+
94
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:215
95
+ msgid "Checkbox"
96
+ msgstr ""
97
+
98
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:216
99
+ msgid "Ticket"
100
+ msgstr ""
101
+
102
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:217
103
+ msgid "Primary Information"
104
+ msgstr ""
105
+
106
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:218
107
+ msgid "Details"
108
+ msgstr ""
109
+
110
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:219
111
+ #: src/views/tickets/email.php:456
112
+ msgid "Security Code"
113
+ msgstr ""
114
+
115
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:220
116
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:108
117
+ #: src/Tribe/Commerce/PayPal/Orders/Table.php:103
118
+ msgid "Status"
119
+ msgstr ""
120
+
121
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:221
122
+ #: src/admin-views/attendees-table/check-in-button.php:23
123
+ msgid "Check In"
124
+ msgstr ""
125
+
126
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:350
127
+ #: src/Tribe/Attendees_Table.php:994
128
+ msgctxt "Attendees Table search options"
129
+ msgid "Search by Purchaser Name"
130
+ msgstr ""
131
+
132
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:351
133
+ #: src/Tribe/Attendees_Table.php:995
134
+ msgctxt "Attendees Table search options"
135
+ msgid "Search by Purchaser Email"
136
+ msgstr ""
137
+
138
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:352
139
+ #: src/Tribe/Attendees_Table.php:996
140
+ msgctxt "Attendees Table search options"
141
+ msgid "Search by Ticket Holder Name"
142
+ msgstr ""
143
+
144
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:353
145
+ #: src/Tribe/Attendees_Table.php:997
146
+ msgctxt "Attendees Table search options"
147
+ msgid "Search by Ticket Holder Email"
148
+ msgstr ""
149
+
150
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:354
151
+ #: src/Tribe/Attendees_Table.php:998
152
+ msgctxt "Attendees Table search options"
153
+ msgid "Search by User ID"
154
+ msgstr ""
155
+
156
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:355
157
+ #: src/Tribe/Attendees_Table.php:999
158
+ msgctxt "Attendees Table search options"
159
+ msgid "Search by Order Status"
160
+ msgstr ""
161
+
162
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:356
163
+ #: src/Tribe/Attendees_Table.php:1000
164
+ msgctxt "Attendees Table search options"
165
+ msgid "Search by Order ID"
166
+ msgstr ""
167
+
168
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:357
169
+ #: src/Tribe/Attendees_Table.php:1001
170
+ msgctxt "Attendees Table search options"
171
+ msgid "Search by Security Code"
172
+ msgstr ""
173
+
174
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:358
175
+ #: src/Tribe/Attendees_Table.php:1002
176
+ msgctxt "Attendees Table search options"
177
+ msgid "Search by %s ID"
178
+ msgstr ""
179
+
180
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:359
181
+ #: src/Tribe/Attendees_Table.php:1003
182
+ msgctxt "Attendees Table search options"
183
+ msgid "Search by Product ID"
184
+ msgstr ""
185
+
186
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:555
187
+ #: src/Tribe/Attendees_Table.php:402
188
+ msgctxt "row action"
189
+ msgid "Check In"
190
+ msgstr ""
191
+
192
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:556
193
+ #: src/Tribe/Attendees_Table.php:403
194
+ msgctxt "row action"
195
+ msgid "Undo Check In"
196
+ msgstr ""
197
+
198
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:565
199
+ #: src/Tribe/Attendees_Table.php:412
200
+ msgctxt "row action"
201
+ msgid "Move"
202
+ msgstr ""
203
+
204
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:581
205
+ #: src/Tribe/Attendees_Table.php:425
206
+ msgctxt "row action"
207
+ msgid "Delete"
208
+ msgstr ""
209
+
210
+ #: src/Tickets/Commerce/Admin_Tables/Attendees.php:630
211
+ #: src/Tribe/Attendees_Table.php:980
212
+ msgid "No matching attendees found."
213
+ msgstr ""
214
+
215
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:101
216
+ #: src/Tribe/Commerce/PayPal/Orders/Table.php:98
217
+ msgid "Order"
218
+ msgstr ""
219
+
220
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:102
221
+ #: src/Tribe/Commerce/PayPal/Orders/Table.php:99
222
+ msgid "Purchaser"
223
+ msgstr ""
224
+
225
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:103
226
+ #: src/Tribe/Attendees_Table.php:616
227
+ #: src/Tribe/Commerce/PayPal/Orders/Table.php:100 src/Tribe/Privacy.php:189
228
+ #: src/Tribe/Privacy.php:470 src/Tribe/Privacy.php:566
229
+ #: src/views/blocks/rsvp/form/email.php:32 src/views/tickets/rsvp.php:237
230
+ #: src/views/v2/rsvp/ari/form/fields/email.php:33
231
+ #: src/views/v2/rsvp/form/fields/email.php:34
232
+ msgid "Email"
233
+ msgstr ""
234
+
235
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:104
236
+ #: src/Tribe/Commerce/PayPal/Orders/Table.php:101
237
+ msgid "Purchased"
238
+ msgstr ""
239
+
240
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:105
241
+ #: src/Tribe/Commerce/PayPal/Orders/Table.php:102 src/Tribe/Privacy.php:194
242
+ #: src/Tribe/Privacy.php:475 src/Tribe/Privacy.php:571
243
+ msgid "Date"
244
+ msgstr ""
245
+
246
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:106
247
+ msgid "Gateway"
248
+ msgstr ""
249
+
250
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:107
251
+ msgid "Gateway ID"
252
+ msgstr ""
253
+
254
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:109
255
+ #: src/Tribe/Commerce/PayPal/Orders/Table.php:106
256
+ msgid "Total"
257
+ msgstr ""
258
+
259
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:178
260
+ #: src/Tribe/Commerce/PayPal/Orders/Table.php:274
261
+ msgid "No matching orders found."
262
+ msgstr ""
263
+
264
+ #: src/Tickets/Commerce/Admin_Tables/Orders.php:281
265
+ #: src/Tribe/Commerce/PayPal/Orders/Table.php:177
266
+ msgid "%1$s"
267
+ msgstr ""
268
+
269
+ #: src/Tickets/Commerce/Attendee.php:206 src/Tribe/Admin/Columns/Tickets.php:56
270
  #: src/Tribe/Admin/Manager/Service_Provider.php:173 src/Tribe/Attendees.php:212
271
  #: src/Tribe/Commerce/PayPal/Main.php:456
272
  #: src/Tribe/Tabbed_View/Attendee_Report_Tab.php:22 src/admin-views/list.php:95
273
  msgid "Attendees"
274
  msgstr ""
275
 
276
+ #: src/Tickets/Commerce/Attendee.php:795
277
+ msgid "Name not available"
278
+ msgstr ""
279
+
280
+ #: src/Tickets/Commerce/Attendee.php:814
281
+ msgid "Email not available"
282
+ msgstr ""
283
+
284
+ #: src/Tickets/Commerce/Checkout.php:185
285
  msgid "Tickets Commerce Checkout Page"
286
  msgstr ""
287
 
288
+ #: src/Tickets/Commerce/Gateways/Manual/Gateway.php:27
289
+ msgid "Manually Generated"
290
  msgstr ""
291
 
292
  #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:43
293
+ msgid "Disconnect PayPal Account"
294
  msgstr ""
295
 
296
  #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:44
297
+ msgid "Are you sure you want to disconnect your PayPal account?"
298
+ msgstr ""
299
+
300
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:45
301
  msgid "You’re connected to PayPal! Here’s what’s next..."
302
  msgstr ""
303
 
304
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:47
305
  msgid ""
306
  "PayPal allows you to accept credit or debit cards directly on your website. "
307
  "Because of\n"
313
  "comprised of, but not limited to:"
314
  msgstr ""
315
 
316
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:57
317
  msgid ""
318
  "Using a trusted, secure hosting provider – preferably one which claims and "
319
  "actively promotes PCI compliance."
320
  msgstr ""
321
 
322
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:58
323
  msgid ""
324
  "Maintain security best practices when setting passwords and limit access to "
325
  "your server."
326
  msgstr ""
327
 
328
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:59
329
  msgid "Implement an SSL certificate to keep your payments secure."
330
  msgstr ""
331
 
332
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:60
333
  msgid "Keep plugins up to date to ensure latest security fixes are present."
334
  msgstr ""
335
 
336
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:63
337
  msgid ""
338
  "You have connected your account for test mode. You will need to connect "
339
  "again once you are in live mode."
340
  msgstr ""
341
 
342
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:108
343
+ msgid "E.g.: 123"
344
+ msgstr ""
345
+
346
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:109
347
+ msgid "E.g.: 03/26"
348
+ msgstr ""
349
+
350
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:110
351
+ msgid "E.g.: 4111 1111 1111 1111"
352
+ msgstr ""
353
+
354
+ #: src/Tickets/Commerce/Gateways/PayPal/Assets.php:111
355
+ msgid "E.g.: 01020"
356
+ msgstr ""
357
+
358
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:749
359
  msgid "The PayPal webhook does not exist"
360
  msgstr ""
361
 
362
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:752
363
  msgid "Unexpected PayPal response when getting webhook"
364
  msgstr ""
365
 
366
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:799
367
  msgid "Unexpected PayPal response when creating webhook"
368
  msgstr ""
369
 
370
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:810
371
  msgid ""
372
  "PayPal webhook limit has been reached, you need to go into your developer."
373
  "paypal.com account and remove webhooks from the associated account"
374
  msgstr ""
375
 
376
+ #: src/Tickets/Commerce/Gateways/PayPal/Client.php:869
377
  msgid "Unexpected PayPal response when updating webhook"
378
  msgstr ""
379
 
380
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:44
381
+ msgid "PayPal"
382
  msgstr ""
383
 
384
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:104
385
+ msgid "PayPal is now connected."
 
 
386
  msgstr ""
387
 
388
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:109
389
+ msgid "Failed to disconnect PayPal account."
 
 
 
390
  msgstr ""
391
 
392
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:114
393
+ msgid "Disconnected PayPal account."
394
  msgstr ""
395
 
396
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:119
397
+ msgid "Failed to refresh PayPal access token."
398
  msgstr ""
399
 
400
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:124
401
+ msgid "PayPal access token was refreshed successfully."
 
 
402
  msgstr ""
403
 
404
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:129
405
+ msgid "Failed to refresh PayPal user info."
406
  msgstr ""
407
 
408
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:134
409
+ msgid "PayPal user info was refreshed successfully."
410
  msgstr ""
411
 
412
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:139
413
+ msgid "Failed to refresh PayPal webhooks."
 
 
414
  msgstr ""
415
 
416
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:144
417
+ msgid "PayPal webhooks refreshed successfully."
418
  msgstr ""
419
 
420
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:149
421
  msgid ""
422
+ "A valid SSL certificate is required to set up your PayPal account and accept "
423
+ "payments"
 
 
424
  msgstr ""
425
 
426
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:171
427
+ #: src/views/v2/commerce/checkout.php:54
428
+ msgid "Something went wrong!"
429
+ msgstr ""
430
+
431
+ #: src/Tickets/Commerce/Gateways/PayPal/Gateway.php:172
432
+ msgid "Unexpected response recieved."
433
+ msgstr ""
434
+
435
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:95
436
+ msgid "United States"
437
+ msgstr ""
438
+
439
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:96
440
+ msgid "Canada"
441
+ msgstr ""
442
+
443
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:97
444
+ msgid "United Kingdom"
445
+ msgstr ""
446
+
447
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:98
448
+ msgid "Afghanistan"
449
+ msgstr ""
450
+
451
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:99
452
+ msgid "Albania"
453
+ msgstr ""
454
+
455
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:100
456
+ msgid "Algeria"
457
+ msgstr ""
458
+
459
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:101
460
+ msgid "American Samoa"
461
+ msgstr ""
462
+
463
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:102
464
+ msgid "Andorra"
465
+ msgstr ""
466
+
467
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:103
468
+ msgid "Angola"
469
+ msgstr ""
470
+
471
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:104
472
+ msgid "Anguilla"
473
+ msgstr ""
474
+
475
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:105
476
+ msgid "Antarctica"
477
+ msgstr ""
478
+
479
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:106
480
+ msgid "Antigua and Barbuda"
481
+ msgstr ""
482
+
483
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:107
484
+ msgid "Argentina"
485
+ msgstr ""
486
+
487
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:108
488
+ msgid "Armenia"
489
+ msgstr ""
490
+
491
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:109
492
+ msgid "Aruba"
493
+ msgstr ""
494
+
495
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:110
496
+ msgid "Australia"
497
+ msgstr ""
498
+
499
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:111
500
+ msgid "Austria"
501
+ msgstr ""
502
+
503
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:112
504
+ msgid "Azerbaijan"
505
+ msgstr ""
506
+
507
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:113
508
+ msgid "Bahamas"
509
+ msgstr ""
510
+
511
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:114
512
+ msgid "Bahrain"
513
+ msgstr ""
514
+
515
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:115
516
+ msgid "Bangladesh"
517
+ msgstr ""
518
+
519
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:116
520
+ msgid "Barbados"
521
+ msgstr ""
522
+
523
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:117
524
+ msgid "Belarus"
525
+ msgstr ""
526
+
527
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:118
528
+ msgid "Belgium"
529
+ msgstr ""
530
+
531
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:119
532
+ msgid "Belize"
533
+ msgstr ""
534
+
535
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:120
536
+ msgid "Benin"
537
+ msgstr ""
538
+
539
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:121
540
+ msgid "Bermuda"
541
+ msgstr ""
542
+
543
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:122
544
+ msgid "Bhutan"
545
+ msgstr ""
546
+
547
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:123
548
+ msgid "Bolivia"
549
+ msgstr ""
550
+
551
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:124
552
+ msgid "Bosnia and Herzegovina"
553
+ msgstr ""
554
+
555
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:125
556
+ msgid "Botswana"
557
+ msgstr ""
558
+
559
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:126
560
+ msgid "Bouvet Island"
561
+ msgstr ""
562
+
563
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:127
564
+ msgid "Brazil"
565
+ msgstr ""
566
+
567
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:128
568
+ msgid "British Indian Ocean Territory"
569
+ msgstr ""
570
+
571
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:129
572
+ msgid "Brunei Darrussalam"
573
+ msgstr ""
574
+
575
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:130
576
+ msgid "Bulgaria"
577
+ msgstr ""
578
+
579
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:131
580
+ msgid "Burkina Faso"
581
+ msgstr ""
582
+
583
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:132
584
+ msgid "Burundi"
585
+ msgstr ""
586
+
587
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:133
588
+ msgid "Cambodia"
589
+ msgstr ""
590
+
591
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:134
592
+ msgid "Cameroon"
593
+ msgstr ""
594
+
595
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:135
596
+ msgid "Cape Verde"
597
+ msgstr ""
598
+
599
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:136
600
+ msgid "Cayman Islands"
601
+ msgstr ""
602
+
603
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:137
604
+ msgid "Central African Republic"
605
+ msgstr ""
606
+
607
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:138
608
+ msgid "Chad"
609
+ msgstr ""
610
+
611
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:139
612
+ msgid "Chile"
613
+ msgstr ""
614
+
615
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:140
616
+ msgid "China"
617
+ msgstr ""
618
+
619
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:141
620
+ msgid "Christmas Island"
621
+ msgstr ""
622
+
623
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:142
624
+ msgid "Cocos Islands"
625
+ msgstr ""
626
+
627
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:143
628
+ msgid "Colombia"
629
+ msgstr ""
630
+
631
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:144
632
+ msgid "Comoros"
633
+ msgstr ""
634
+
635
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:145
636
+ msgid "Congo, Democratic People's Republic"
637
+ msgstr ""
638
+
639
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:146
640
+ msgid "Congo, Republic of"
641
+ msgstr ""
642
+
643
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:147
644
+ msgid "Cook Islands"
645
+ msgstr ""
646
+
647
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:148
648
+ msgid "Costa Rica"
649
+ msgstr ""
650
+
651
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:149
652
+ msgid "Cote d'Ivoire"
653
+ msgstr ""
654
+
655
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:150
656
+ msgid "Croatia/Hrvatska"
657
+ msgstr ""
658
+
659
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:151
660
+ msgid "Cuba"
661
+ msgstr ""
662
+
663
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:152
664
+ msgid "Cyprus Island"
665
+ msgstr ""
666
+
667
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:153
668
+ msgid "Czech Republic"
669
+ msgstr ""
670
+
671
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:154
672
+ msgid "Denmark"
673
+ msgstr ""
674
+
675
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:155
676
+ msgid "Djibouti"
677
+ msgstr ""
678
+
679
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:156
680
+ msgid "Dominica"
681
+ msgstr ""
682
+
683
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:157
684
+ msgid "Dominican Republic"
685
+ msgstr ""
686
+
687
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:158
688
+ msgid "East Timor"
689
+ msgstr ""
690
+
691
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:159
692
+ msgid "Ecuador"
693
+ msgstr ""
694
+
695
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:160
696
+ msgid "Egypt"
697
+ msgstr ""
698
+
699
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:161
700
+ msgid "Equatorial Guinea"
701
+ msgstr ""
702
+
703
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:162
704
+ msgid "El Salvador"
705
+ msgstr ""
706
+
707
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:163
708
+ msgid "Eritrea"
709
+ msgstr ""
710
+
711
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:164
712
+ msgid "Estonia"
713
+ msgstr ""
714
+
715
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:165
716
+ msgid "Ethiopia"
717
+ msgstr ""
718
+
719
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:166
720
+ msgid "Falkland Islands"
721
+ msgstr ""
722
+
723
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:167
724
+ msgid "Faroe Islands"
725
+ msgstr ""
726
+
727
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:168
728
+ msgid "Fiji"
729
+ msgstr ""
730
+
731
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:169
732
+ msgid "Finland"
733
+ msgstr ""
734
+
735
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:170
736
+ msgid "France"
737
+ msgstr ""
738
+
739
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:171
740
+ msgid "French Guiana"
741
+ msgstr ""
742
+
743
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:172
744
+ msgid "French Polynesia"
745
+ msgstr ""
746
+
747
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:173
748
+ msgid "French Southern Territories"
749
+ msgstr ""
750
+
751
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:174
752
+ msgid "Gabon"
753
+ msgstr ""
754
+
755
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:175
756
+ msgid "Gambia"
757
+ msgstr ""
758
+
759
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:176
760
+ msgid "Georgia"
761
+ msgstr ""
762
+
763
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:177
764
+ msgid "Germany"
765
+ msgstr ""
766
+
767
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:178
768
+ msgid "Greece"
769
+ msgstr ""
770
+
771
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:179
772
+ msgid "Ghana"
773
+ msgstr ""
774
+
775
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:180
776
+ msgid "Gibraltar"
777
+ msgstr ""
778
+
779
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:181
780
+ msgid "Greenland"
781
+ msgstr ""
782
+
783
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:182
784
+ msgid "Grenada"
785
+ msgstr ""
786
+
787
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:183
788
+ msgid "Guadeloupe"
789
+ msgstr ""
790
+
791
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:184
792
+ msgid "Guam"
793
+ msgstr ""
794
+
795
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:185
796
+ msgid "Guatemala"
797
+ msgstr ""
798
+
799
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:186
800
+ msgid "Guernsey"
801
+ msgstr ""
802
+
803
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:187
804
+ msgid "Guinea"
805
+ msgstr ""
806
+
807
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:188
808
+ msgid "Guinea-Bissau"
809
+ msgstr ""
810
+
811
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:189
812
+ msgid "Guyana"
813
+ msgstr ""
814
+
815
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:190
816
+ msgid "Haiti"
817
+ msgstr ""
818
+
819
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:191
820
+ msgid "Heard and McDonald Islands"
821
+ msgstr ""
822
+
823
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:192
824
+ msgid "Holy See (City Vatican State)"
825
+ msgstr ""
826
+
827
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:193
828
+ msgid "Honduras"
829
+ msgstr ""
830
+
831
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:194
832
+ msgid "Hong Kong"
833
+ msgstr ""
834
+
835
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:195
836
+ msgid "Hungary"
837
+ msgstr ""
838
+
839
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:196
840
+ msgid "Iceland"
841
+ msgstr ""
842
+
843
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:197
844
+ msgid "India"
845
+ msgstr ""
846
+
847
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:198
848
+ msgid "Indonesia"
849
+ msgstr ""
850
+
851
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:199
852
+ msgid "Iran"
853
+ msgstr ""
854
+
855
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:200
856
+ msgid "Iraq"
857
+ msgstr ""
858
+
859
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:201
860
+ msgid "Ireland"
861
+ msgstr ""
862
+
863
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:202
864
+ msgid "Isle of Man"
865
+ msgstr ""
866
+
867
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:203
868
+ msgid "Israel"
869
+ msgstr ""
870
+
871
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:204
872
+ msgid "Italy"
873
+ msgstr ""
874
+
875
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:205
876
+ msgid "Jamaica"
877
+ msgstr ""
878
+
879
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:206
880
+ msgid "Japan"
881
+ msgstr ""
882
+
883
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:207
884
+ msgid "Jersey"
885
+ msgstr ""
886
+
887
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:208
888
+ msgid "Jordan"
889
+ msgstr ""
890
+
891
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:209
892
+ msgid "Kazakhstan"
893
+ msgstr ""
894
+
895
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:210
896
+ msgid "Kenya"
897
+ msgstr ""
898
+
899
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:211
900
+ msgid "Kiribati"
901
+ msgstr ""
902
+
903
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:212
904
+ msgid "Kuwait"
905
+ msgstr ""
906
+
907
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:213
908
+ msgid "Kyrgyzstan"
909
+ msgstr ""
910
+
911
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:214
912
+ msgid "Lao People's Democratic Republic"
913
+ msgstr ""
914
+
915
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:215
916
+ msgid "Latvia"
917
+ msgstr ""
918
+
919
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:216
920
+ msgid "Lebanon"
921
+ msgstr ""
922
+
923
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:217
924
+ msgid "Lesotho"
925
+ msgstr ""
926
+
927
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:218
928
+ msgid "Liberia"
929
+ msgstr ""
930
+
931
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:219
932
+ msgid "Libyan Arab Jamahiriya"
933
+ msgstr ""
934
+
935
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:220
936
+ msgid "Liechtenstein"
937
+ msgstr ""
938
+
939
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:221
940
+ msgid "Lithuania"
941
+ msgstr ""
942
+
943
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:222
944
+ msgid "Luxembourg"
945
+ msgstr ""
946
+
947
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:223
948
+ msgid "Macau"
949
+ msgstr ""
950
+
951
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:224
952
+ msgid "Macedonia"
953
+ msgstr ""
954
+
955
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:225
956
+ msgid "Madagascar"
957
+ msgstr ""
958
+
959
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:226
960
+ msgid "Malawi"
961
+ msgstr ""
962
+
963
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:227
964
+ msgid "Malaysia"
965
+ msgstr ""
966
+
967
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:228
968
+ msgid "Maldives"
969
+ msgstr ""
970
+
971
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:229
972
+ msgid "Mali"
973
+ msgstr ""
974
+
975
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:230
976
+ msgid "Malta"
977
+ msgstr ""
978
+
979
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:231
980
+ msgid "Marshall Islands"
981
+ msgstr ""
982
+
983
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:232
984
+ msgid "Martinique"
985
+ msgstr ""
986
+
987
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:233
988
+ msgid "Mauritania"
989
+ msgstr ""
990
+
991
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:234
992
+ msgid "Mauritius"
993
+ msgstr ""
994
+
995
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:235
996
+ msgid "Mayotte"
997
+ msgstr ""
998
+
999
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:236
1000
+ msgid "Mexico"
1001
+ msgstr ""
1002
+
1003
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:237
1004
+ msgid "Micronesia"
1005
+ msgstr ""
1006
+
1007
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:238
1008
+ msgid "Moldova, Republic of"
1009
+ msgstr ""
1010
+
1011
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:239
1012
+ msgid "Monaco"
1013
+ msgstr ""
1014
+
1015
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:240
1016
+ msgid "Mongolia"
1017
+ msgstr ""
1018
+
1019
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:241
1020
+ msgid "Montenegro"
1021
+ msgstr ""
1022
+
1023
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:242
1024
+ msgid "Montserrat"
1025
+ msgstr ""
1026
+
1027
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:243
1028
+ msgid "Morocco"
1029
+ msgstr ""
1030
+
1031
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:244
1032
+ msgid "Mozambique"
1033
+ msgstr ""
1034
+
1035
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:245
1036
+ msgid "Myanmar"
1037
+ msgstr ""
1038
+
1039
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:246
1040
+ msgid "Namibia"
1041
+ msgstr ""
1042
+
1043
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:247
1044
+ msgid "Nauru"
1045
+ msgstr ""
1046
+
1047
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:248
1048
+ msgid "Nepal"
1049
+ msgstr ""
1050
+
1051
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:249
1052
+ msgid "Netherlands"
1053
+ msgstr ""
1054
+
1055
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:250
1056
+ msgid "Netherlands Antilles"
1057
+ msgstr ""
1058
+
1059
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:251
1060
+ msgid "New Caledonia"
1061
+ msgstr ""
1062
+
1063
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:252
1064
+ msgid "New Zealand"
1065
+ msgstr ""
1066
+
1067
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:253
1068
+ msgid "Nicaragua"
1069
+ msgstr ""
1070
+
1071
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:254
1072
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:391
1073
+ msgid "Niger"
1074
+ msgstr ""
1075
+
1076
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:255
1077
+ msgid "Nigeria"
1078
+ msgstr ""
1079
+
1080
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:256
1081
+ msgid "Niue"
1082
+ msgstr ""
1083
+
1084
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:257
1085
+ msgid "Norfolk Island"
1086
+ msgstr ""
1087
+
1088
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:258
1089
+ msgid "North Korea"
1090
+ msgstr ""
1091
+
1092
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:259
1093
+ msgid "Northern Mariana Islands"
1094
+ msgstr ""
1095
+
1096
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:260
1097
+ msgid "Norway"
1098
+ msgstr ""
1099
+
1100
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:261
1101
+ msgid "Oman"
1102
+ msgstr ""
1103
+
1104
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:262
1105
+ msgid "Pakistan"
1106
+ msgstr ""
1107
+
1108
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:263
1109
+ msgid "Palau"
1110
+ msgstr ""
1111
+
1112
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:264
1113
+ msgid "Palestinian Territories"
1114
+ msgstr ""
1115
+
1116
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:265
1117
+ msgid "Panama"
1118
+ msgstr ""
1119
+
1120
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:266
1121
+ msgid "Papua New Guinea"
1122
+ msgstr ""
1123
+
1124
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:267
1125
+ msgid "Paraguay"
1126
+ msgstr ""
1127
+
1128
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:268
1129
+ msgid "Peru"
1130
+ msgstr ""
1131
+
1132
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:269
1133
+ msgid "Philippines"
1134
+ msgstr ""
1135
+
1136
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:270
1137
+ msgid "Pitcairn Island"
1138
+ msgstr ""
1139
+
1140
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:271
1141
+ msgid "Poland"
1142
+ msgstr ""
1143
+
1144
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:272
1145
+ msgid "Portugal"
1146
+ msgstr ""
1147
+
1148
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:273
1149
+ msgid "Puerto Rico"
1150
+ msgstr ""
1151
+
1152
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:274
1153
+ msgid "Qatar"
1154
+ msgstr ""
1155
+
1156
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:275
1157
+ msgid "Reunion Island"
1158
+ msgstr ""
1159
+
1160
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:276
1161
+ msgid "Romania"
1162
+ msgstr ""
1163
+
1164
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:277
1165
+ msgid "Russian Federation"
1166
+ msgstr ""
1167
+
1168
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:278
1169
+ msgid "Rwanda"
1170
+ msgstr ""
1171
+
1172
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:279
1173
+ msgid "Saint Helena"
1174
+ msgstr ""
1175
+
1176
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:280
1177
+ msgid "Saint Kitts and Nevis"
1178
+ msgstr ""
1179
+
1180
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:281
1181
+ msgid "Saint Lucia"
1182
+ msgstr ""
1183
+
1184
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:282
1185
+ msgid "Saint Pierre and Miquelon"
1186
+ msgstr ""
1187
+
1188
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:283
1189
+ msgid "Saint Vincent and the Grenadines"
1190
+ msgstr ""
1191
+
1192
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:284
1193
+ msgid "San Marino"
1194
+ msgstr ""
1195
+
1196
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:285
1197
+ msgid "Sao Tome and Principe"
1198
+ msgstr ""
1199
+
1200
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:286
1201
+ msgid "Saudi Arabia"
1202
+ msgstr ""
1203
+
1204
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:287
1205
+ msgid "Senegal"
1206
+ msgstr ""
1207
+
1208
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:288
1209
+ msgid "Serbia"
1210
+ msgstr ""
1211
+
1212
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:289
1213
+ msgid "Seychelles"
1214
+ msgstr ""
1215
+
1216
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:290
1217
+ msgid "Sierra Leone"
1218
+ msgstr ""
1219
+
1220
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:291
1221
+ msgid "Singapore"
1222
+ msgstr ""
1223
+
1224
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:292
1225
+ msgid "Slovak Republic"
1226
+ msgstr ""
1227
+
1228
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:293
1229
+ msgid "Slovenia"
1230
+ msgstr ""
1231
+
1232
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:294
1233
+ msgid "Solomon Islands"
1234
+ msgstr ""
1235
+
1236
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:295
1237
+ msgid "Somalia"
1238
+ msgstr ""
1239
+
1240
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:296
1241
+ msgid "South Africa"
1242
+ msgstr ""
1243
+
1244
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:297
1245
+ msgid "South Georgia"
1246
+ msgstr ""
1247
+
1248
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:298
1249
+ msgid "South Korea"
1250
+ msgstr ""
1251
+
1252
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:299
1253
+ msgid "Spain"
1254
+ msgstr ""
1255
+
1256
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:300
1257
+ msgid "Sri Lanka"
1258
+ msgstr ""
1259
+
1260
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:301
1261
+ msgid "Sudan"
1262
+ msgstr ""
1263
+
1264
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:302
1265
+ msgid "Suriname"
1266
+ msgstr ""
1267
+
1268
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:303
1269
+ msgid "Svalbard and Jan Mayen Islands"
1270
+ msgstr ""
1271
+
1272
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:304
1273
+ msgid "Eswatini"
1274
+ msgstr ""
1275
+
1276
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:305
1277
+ msgid "Sweden"
1278
+ msgstr ""
1279
+
1280
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:306
1281
+ msgid "Switzerland"
1282
+ msgstr ""
1283
+
1284
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:307
1285
+ msgid "Syrian Arab Republic"
1286
+ msgstr ""
1287
+
1288
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:308
1289
+ msgid "Taiwan"
1290
+ msgstr ""
1291
+
1292
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:309
1293
+ msgid "Tajikistan"
1294
+ msgstr ""
1295
+
1296
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:310
1297
+ msgid "Tanzania"
1298
+ msgstr ""
1299
+
1300
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:311
1301
+ msgid "Togo"
1302
+ msgstr ""
1303
+
1304
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:312
1305
+ msgid "Tokelau"
1306
+ msgstr ""
1307
+
1308
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:313
1309
+ msgid "Tonga"
1310
+ msgstr ""
1311
+
1312
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:314
1313
+ msgid "Thailand"
1314
+ msgstr ""
1315
+
1316
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:315
1317
+ msgid "Trinidad and Tobago"
1318
+ msgstr ""
1319
+
1320
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:316
1321
+ msgid "Tunisia"
1322
+ msgstr ""
1323
+
1324
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:317
1325
+ msgid "Turkey"
1326
+ msgstr ""
1327
+
1328
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:318
1329
+ msgid "Turkmenistan"
1330
+ msgstr ""
1331
+
1332
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:319
1333
+ msgid "Turks and Caicos Islands"
1334
+ msgstr ""
1335
+
1336
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:320
1337
+ msgid "Tuvalu"
1338
+ msgstr ""
1339
+
1340
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:321
1341
+ msgid "Uganda"
1342
+ msgstr ""
1343
+
1344
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:322
1345
+ msgid "Ukraine"
1346
+ msgstr ""
1347
+
1348
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:323
1349
+ msgid "United Arab Emirates"
1350
+ msgstr ""
1351
+
1352
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:324
1353
+ msgid "Uruguay"
1354
+ msgstr ""
1355
+
1356
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:325
1357
+ msgid "US Minor Outlying Islands"
1358
+ msgstr ""
1359
+
1360
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:326
1361
+ msgid "Uzbekistan"
1362
+ msgstr ""
1363
+
1364
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:327
1365
+ msgid "Vanuatu"
1366
+ msgstr ""
1367
+
1368
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:328
1369
+ msgid "Venezuela"
1370
+ msgstr ""
1371
+
1372
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:329
1373
+ msgid "Vietnam"
1374
+ msgstr ""
1375
+
1376
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:330
1377
+ msgid "Virgin Islands (British)"
1378
+ msgstr ""
1379
+
1380
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:331
1381
+ msgid "Virgin Islands (USA)"
1382
+ msgstr ""
1383
+
1384
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:332
1385
+ msgid "Wallis and Futuna Islands"
1386
+ msgstr ""
1387
+
1388
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:333
1389
+ msgid "Western Sahara"
1390
+ msgstr ""
1391
+
1392
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:334
1393
+ msgid "Western Samoa"
1394
+ msgstr ""
1395
+
1396
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:335
1397
+ msgid "Yemen"
1398
+ msgstr ""
1399
+
1400
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:336
1401
+ msgid "Yugoslavia"
1402
+ msgstr ""
1403
+
1404
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:337
1405
+ msgid "Zambia"
1406
+ msgstr ""
1407
+
1408
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:338
1409
+ msgid "Zimbabwe"
1410
+ msgstr ""
1411
+
1412
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:476
1413
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:734
1414
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1576
1415
+ msgid "State"
1416
+ msgstr ""
1417
+
1418
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:486
1419
+ msgid "District"
1420
+ msgstr ""
1421
+
1422
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:492
1423
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:503
1424
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:520
1425
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:582
1426
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:604
1427
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:642
1428
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:706
1429
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:729
1430
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:756
1431
+ msgid "Province"
1432
+ msgstr ""
1433
+
1434
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:508
1435
+ msgid "Canton"
1436
+ msgstr ""
1437
+
1438
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:515
1439
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:571
1440
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:648
1441
+ msgid "Region"
1442
+ msgstr ""
1443
+
1444
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:576
1445
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:587
1446
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:739
1447
+ msgid "County"
1448
+ msgstr ""
1449
+
1450
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:609
1451
+ msgid "Prefecture"
1452
+ msgstr ""
1453
+
1454
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:659
1455
+ msgid "State / Zone"
1456
+ msgstr ""
1457
+
1458
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/Country.php:711
1459
+ msgid "Municipality"
1460
+ msgstr ""
1461
+
1462
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:22
1463
+ msgid "Adana"
1464
+ msgstr ""
1465
+
1466
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:23
1467
+ msgid "Ad&#305;yaman"
1468
+ msgstr ""
1469
+
1470
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:24
1471
+ msgid "Afyon"
1472
+ msgstr ""
1473
+
1474
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:25
1475
+ msgid "A&#287;r&#305;"
1476
+ msgstr ""
1477
+
1478
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:26
1479
+ msgid "Amasya"
1480
+ msgstr ""
1481
+
1482
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:27
1483
+ msgid "Ankara"
1484
+ msgstr ""
1485
+
1486
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:28
1487
+ msgid "Antalya"
1488
+ msgstr ""
1489
+
1490
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:29
1491
+ msgid "Artvin"
1492
+ msgstr ""
1493
+
1494
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:30
1495
+ msgid "Ayd&#305;n"
1496
+ msgstr ""
1497
+
1498
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:31
1499
+ msgid "Bal&#305;kesir"
1500
+ msgstr ""
1501
+
1502
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:32
1503
+ msgid "Bilecik"
1504
+ msgstr ""
1505
+
1506
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:33
1507
+ msgid "Bing&#246;l"
1508
+ msgstr ""
1509
+
1510
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:34
1511
+ msgid "Bitlis"
1512
+ msgstr ""
1513
+
1514
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:35
1515
+ msgid "Bolu"
1516
+ msgstr ""
1517
+
1518
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:36
1519
+ msgid "Burdur"
1520
+ msgstr ""
1521
+
1522
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:37
1523
+ msgid "Bursa"
1524
+ msgstr ""
1525
+
1526
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:38
1527
+ msgid "&#199;anakkale"
1528
+ msgstr ""
1529
+
1530
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:39
1531
+ msgid "&#199;ank&#305;r&#305;"
1532
+ msgstr ""
1533
+
1534
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:40
1535
+ msgid "&#199;orum"
1536
+ msgstr ""
1537
+
1538
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:41
1539
+ msgid "Denizli"
1540
+ msgstr ""
1541
+
1542
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:42
1543
+ msgid "Diyarbak&#305;r"
1544
+ msgstr ""
1545
+
1546
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:43
1547
+ msgid "Edirne"
1548
+ msgstr ""
1549
+
1550
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:44
1551
+ msgid "Elaz&#305;&#287;"
1552
+ msgstr ""
1553
+
1554
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:45
1555
+ msgid "Erzincan"
1556
+ msgstr ""
1557
+
1558
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:46
1559
+ msgid "Erzurum"
1560
+ msgstr ""
1561
+
1562
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:47
1563
+ msgid "Eski&#351;ehir"
1564
+ msgstr ""
1565
+
1566
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:48
1567
+ msgid "Gaziantep"
1568
+ msgstr ""
1569
+
1570
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:49
1571
+ msgid "Giresun"
1572
+ msgstr ""
1573
+
1574
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:50
1575
+ msgid "G&#252;m&#252;&#351;hane"
1576
+ msgstr ""
1577
+
1578
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:51
1579
+ msgid "Hakkari"
1580
+ msgstr ""
1581
+
1582
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:52
1583
+ msgid "Hatay"
1584
+ msgstr ""
1585
+
1586
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:53
1587
+ msgid "Isparta"
1588
+ msgstr ""
1589
+
1590
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:54
1591
+ msgid "&#304;&#231;el"
1592
+ msgstr ""
1593
+
1594
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:55
1595
+ msgid "&#304;stanbul"
1596
+ msgstr ""
1597
+
1598
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:56
1599
+ msgid "&#304;zmir"
1600
+ msgstr ""
1601
+
1602
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:57
1603
+ msgid "Kars"
1604
+ msgstr ""
1605
+
1606
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:58
1607
+ msgid "Kastamonu"
1608
+ msgstr ""
1609
+
1610
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:59
1611
+ msgid "Kayseri"
1612
+ msgstr ""
1613
+
1614
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:60
1615
+ msgid "K&#305;rklareli"
1616
+ msgstr ""
1617
+
1618
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:61
1619
+ msgid "K&#305;r&#351;ehir"
1620
+ msgstr ""
1621
+
1622
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:62
1623
+ msgid "Kocaeli"
1624
+ msgstr ""
1625
+
1626
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:63
1627
+ msgid "Konya"
1628
+ msgstr ""
1629
+
1630
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:64
1631
+ msgid "K&#252;tahya"
1632
+ msgstr ""
1633
+
1634
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:65
1635
+ msgid "Malatya"
1636
+ msgstr ""
1637
+
1638
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:66
1639
+ msgid "Manisa"
1640
+ msgstr ""
1641
+
1642
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:67
1643
+ msgid "Kahramanmara&#351;"
1644
+ msgstr ""
1645
+
1646
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:68
1647
+ msgid "Mardin"
1648
+ msgstr ""
1649
+
1650
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:69
1651
+ msgid "Mu&#287;la"
1652
+ msgstr ""
1653
+
1654
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:70
1655
+ msgid "Mu&#351;"
1656
+ msgstr ""
1657
+
1658
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:71
1659
+ msgid "Nev&#351;ehir"
1660
+ msgstr ""
1661
+
1662
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:72
1663
+ msgid "Ni&#287;de"
1664
+ msgstr ""
1665
+
1666
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:73
1667
+ msgid "Ordu"
1668
+ msgstr ""
1669
+
1670
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:74
1671
+ msgid "Rize"
1672
+ msgstr ""
1673
+
1674
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:75
1675
+ msgid "Sakarya"
1676
+ msgstr ""
1677
+
1678
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:76
1679
+ msgid "Samsun"
1680
+ msgstr ""
1681
+
1682
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:77
1683
+ msgid "Siirt"
1684
+ msgstr ""
1685
+
1686
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:78
1687
+ msgid "Sinop"
1688
+ msgstr ""
1689
+
1690
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:79
1691
+ msgid "Sivas"
1692
+ msgstr ""
1693
+
1694
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:80
1695
+ msgid "Tekirda&#287;"
1696
+ msgstr ""
1697
+
1698
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:81
1699
+ msgid "Tokat"
1700
+ msgstr ""
1701
+
1702
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:82
1703
+ msgid "Trabzon"
1704
+ msgstr ""
1705
+
1706
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:83
1707
+ msgid "Tunceli"
1708
+ msgstr ""
1709
+
1710
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:84
1711
+ msgid "&#350;anl&#305;urfa"
1712
+ msgstr ""
1713
+
1714
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:85
1715
+ msgid "U&#351;ak"
1716
+ msgstr ""
1717
+
1718
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:86
1719
+ msgid "Van"
1720
+ msgstr ""
1721
+
1722
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:87
1723
+ msgid "Yozgat"
1724
+ msgstr ""
1725
+
1726
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:88
1727
+ msgid "Zonguldak"
1728
+ msgstr ""
1729
+
1730
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:89
1731
+ msgid "Aksaray"
1732
+ msgstr ""
1733
+
1734
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:90
1735
+ msgid "Bayburt"
1736
+ msgstr ""
1737
+
1738
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:91
1739
+ msgid "Karaman"
1740
+ msgstr ""
1741
+
1742
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:92
1743
+ msgid "K&#305;r&#305;kkale"
1744
+ msgstr ""
1745
+
1746
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:93
1747
+ msgid "Batman"
1748
+ msgstr ""
1749
+
1750
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:94
1751
+ msgid "&#350;&#305;rnak"
1752
+ msgstr ""
1753
+
1754
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:95
1755
+ msgid "Bart&#305;n"
1756
+ msgstr ""
1757
+
1758
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:96
1759
+ msgid "Ardahan"
1760
+ msgstr ""
1761
+
1762
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:97
1763
+ msgid "I&#287;d&#305;r"
1764
+ msgstr ""
1765
+
1766
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:98
1767
+ msgid "Yalova"
1768
+ msgstr ""
1769
+
1770
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:99
1771
+ msgid "Karab&#252;k"
1772
+ msgstr ""
1773
+
1774
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:100
1775
+ msgid "Kilis"
1776
+ msgstr ""
1777
+
1778
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:101
1779
+ msgid "Osmaniye"
1780
+ msgstr ""
1781
+
1782
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:102
1783
+ msgid "D&#252;zce"
1784
+ msgstr ""
1785
+
1786
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:118
1787
+ msgid "Alba"
1788
+ msgstr ""
1789
+
1790
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:119
1791
+ msgid "Arad"
1792
+ msgstr ""
1793
+
1794
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:120
1795
+ msgid "Arges"
1796
+ msgstr ""
1797
+
1798
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:121
1799
+ msgid "Bacau"
1800
+ msgstr ""
1801
+
1802
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:122
1803
+ msgid "Bihor"
1804
+ msgstr ""
1805
+
1806
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:123
1807
+ msgid "Bistrita-Nasaud"
1808
+ msgstr ""
1809
+
1810
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:124
1811
+ msgid "Botosani"
1812
+ msgstr ""
1813
+
1814
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:125
1815
+ msgid "Braila"
1816
+ msgstr ""
1817
+
1818
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:126
1819
+ msgid "Brasov"
1820
+ msgstr ""
1821
+
1822
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:127
1823
+ msgid "Bucuresti"
1824
+ msgstr ""
1825
+
1826
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:128
1827
+ msgid "Buzau"
1828
+ msgstr ""
1829
+
1830
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:129
1831
+ msgid "Calarasi"
1832
+ msgstr ""
1833
+
1834
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:130
1835
+ msgid "Caras-Severin"
1836
+ msgstr ""
1837
+
1838
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:131
1839
+ msgid "Cluj"
1840
+ msgstr ""
1841
+
1842
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:132
1843
+ msgid "Constanta"
1844
+ msgstr ""
1845
+
1846
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:133
1847
+ msgid "Covasna"
1848
+ msgstr ""
1849
+
1850
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:134
1851
+ msgid "Dambovita"
1852
+ msgstr ""
1853
+
1854
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:135
1855
+ msgid "Dolj"
1856
+ msgstr ""
1857
+
1858
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:136
1859
+ msgid "Galati"
1860
+ msgstr ""
1861
+
1862
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:137
1863
+ msgid "Giurgiu"
1864
+ msgstr ""
1865
+
1866
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:138
1867
+ msgid "Gorj"
1868
+ msgstr ""
1869
+
1870
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:139
1871
+ msgid "Harghita"
1872
+ msgstr ""
1873
+
1874
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:140
1875
+ msgid "Hunedoara"
1876
+ msgstr ""
1877
+
1878
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:141
1879
+ msgid "Ialomita"
1880
+ msgstr ""
1881
+
1882
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:142
1883
+ msgid "Iasi"
1884
+ msgstr ""
1885
+
1886
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:143
1887
+ msgid "Ilfov"
1888
+ msgstr ""
1889
+
1890
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:144
1891
+ msgid "Maramures"
1892
+ msgstr ""
1893
+
1894
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:145
1895
+ msgid "Mehedinti"
1896
+ msgstr ""
1897
+
1898
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:146
1899
+ msgid "Mures"
1900
+ msgstr ""
1901
+
1902
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:147
1903
+ msgid "Neamt"
1904
+ msgstr ""
1905
+
1906
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:148
1907
+ msgid "Olt"
1908
+ msgstr ""
1909
+
1910
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:149
1911
+ msgid "Prahova"
1912
+ msgstr ""
1913
+
1914
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:150
1915
+ msgid "Salaj"
1916
+ msgstr ""
1917
+
1918
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:151
1919
+ msgid "Satu Mare"
1920
+ msgstr ""
1921
+
1922
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:152
1923
+ msgid "Sibiu"
1924
+ msgstr ""
1925
+
1926
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:153
1927
+ msgid "Suceava"
1928
+ msgstr ""
1929
+
1930
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:154
1931
+ msgid "Teleorman"
1932
+ msgstr ""
1933
+
1934
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:155
1935
+ msgid "Timis"
1936
+ msgstr ""
1937
+
1938
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:156
1939
+ msgid "Tulcea"
1940
+ msgstr ""
1941
+
1942
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:157
1943
+ msgid "Valcea"
1944
+ msgstr ""
1945
+
1946
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:158
1947
+ msgid "Vaslui"
1948
+ msgstr ""
1949
+
1950
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:159
1951
+ msgid "Vrancea"
1952
+ msgstr ""
1953
+
1954
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:175
1955
+ msgid "Azad Kashmir"
1956
+ msgstr ""
1957
+
1958
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:176
1959
+ msgid "Balochistan"
1960
+ msgstr ""
1961
+
1962
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:177
1963
+ msgid "FATA"
1964
+ msgstr ""
1965
+
1966
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:178
1967
+ msgid "Gilgit Baltistan"
1968
+ msgstr ""
1969
+
1970
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:179
1971
+ msgid "Islamabad Capital Territory"
1972
+ msgstr ""
1973
+
1974
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:180
1975
+ msgid "Khyber Pakhtunkhwa"
1976
+ msgstr ""
1977
+
1978
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:181
1979
+ msgid "Punjab"
1980
+ msgstr ""
1981
+
1982
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:182
1983
+ msgid "Sindh"
1984
+ msgstr ""
1985
+
1986
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:198
1987
+ msgid "Abra"
1988
+ msgstr ""
1989
+
1990
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:199
1991
+ msgid "Agusan del Norte"
1992
+ msgstr ""
1993
+
1994
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:200
1995
+ msgid "Agusan del Sur"
1996
+ msgstr ""
1997
+
1998
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:201
1999
+ msgid "Aklan"
2000
+ msgstr ""
2001
+
2002
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:202
2003
+ msgid "Albay"
2004
+ msgstr ""
2005
+
2006
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:203
2007
+ msgid "Antique"
2008
+ msgstr ""
2009
+
2010
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:204
2011
+ msgid "Apayao"
2012
+ msgstr ""
2013
+
2014
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:205
2015
+ msgid "Aurora"
2016
+ msgstr ""
2017
+
2018
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:206
2019
+ msgid "Basilan"
2020
+ msgstr ""
2021
+
2022
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:207
2023
+ msgid "Bataan"
2024
+ msgstr ""
2025
+
2026
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:208
2027
+ msgid "Batanes"
2028
+ msgstr ""
2029
+
2030
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:209
2031
+ msgid "Batangas"
2032
+ msgstr ""
2033
+
2034
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:210
2035
+ msgid "Benguet"
2036
+ msgstr ""
2037
+
2038
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:211
2039
+ msgid "Biliran"
2040
+ msgstr ""
2041
+
2042
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:212
2043
+ msgid "Bohol"
2044
+ msgstr ""
2045
+
2046
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:213
2047
+ msgid "Bukidnon"
2048
+ msgstr ""
2049
+
2050
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:214
2051
+ msgid "Bulacan"
2052
+ msgstr ""
2053
+
2054
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:215
2055
+ msgid "Cagayan"
2056
+ msgstr ""
2057
+
2058
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:216
2059
+ msgid "Camarines Norte"
2060
+ msgstr ""
2061
+
2062
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:217
2063
+ msgid "Camarines Sur"
2064
+ msgstr ""
2065
+
2066
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:218
2067
+ msgid "Camiguin"
2068
+ msgstr ""
2069
+
2070
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:219
2071
+ msgid "Capiz"
2072
+ msgstr ""
2073
+
2074
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:220
2075
+ msgid "Catanduanes"
2076
+ msgstr ""
2077
+
2078
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:221
2079
+ msgid "Cavite"
2080
+ msgstr ""
2081
+
2082
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:222
2083
+ msgid "Cebu"
2084
+ msgstr ""
2085
+
2086
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:223
2087
+ msgid "Compostela Valley"
2088
+ msgstr ""
2089
+
2090
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:224
2091
+ msgid "Cotabato"
2092
+ msgstr ""
2093
+
2094
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:225
2095
+ msgid "Davao del Norte"
2096
+ msgstr ""
2097
+
2098
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:226
2099
+ msgid "Davao del Sur"
2100
+ msgstr ""
2101
+
2102
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:227
2103
+ msgid "Davao Occidental"
2104
+ msgstr ""
2105
+
2106
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:228
2107
+ msgid "Davao Oriental"
2108
+ msgstr ""
2109
+
2110
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:229
2111
+ msgid "Dinagat Islands"
2112
+ msgstr ""
2113
+
2114
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:230
2115
+ msgid "Eastern Samar"
2116
+ msgstr ""
2117
+
2118
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:231
2119
+ msgid "Guimaras"
2120
+ msgstr ""
2121
+
2122
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:232
2123
+ msgid "Ifugao"
2124
+ msgstr ""
2125
+
2126
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:233
2127
+ msgid "Ilocos Norte"
2128
+ msgstr ""
2129
+
2130
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:234
2131
+ msgid "Ilocos Sur"
2132
+ msgstr ""
2133
+
2134
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:235
2135
+ msgid "Iloilo"
2136
+ msgstr ""
2137
+
2138
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:236
2139
+ msgid "Isabela"
2140
+ msgstr ""
2141
+
2142
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:237
2143
+ msgid "Kalinga"
2144
+ msgstr ""
2145
+
2146
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:238
2147
+ msgid "La Union"
2148
+ msgstr ""
2149
+
2150
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:239
2151
+ msgid "Laguna"
2152
+ msgstr ""
2153
+
2154
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:240
2155
+ msgid "Lanao del Norte"
2156
+ msgstr ""
2157
+
2158
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:241
2159
+ msgid "Lanao del Sur"
2160
+ msgstr ""
2161
+
2162
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:242
2163
+ msgid "Leyte"
2164
+ msgstr ""
2165
+
2166
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:243
2167
+ msgid "Maguindanao"
2168
+ msgstr ""
2169
+
2170
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:244
2171
+ msgid "Marinduque"
2172
+ msgstr ""
2173
+
2174
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:245
2175
+ msgid "Masbate"
2176
+ msgstr ""
2177
+
2178
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:246
2179
+ msgid "Misamis Occidental"
2180
+ msgstr ""
2181
+
2182
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:247
2183
+ msgid "Misamis Oriental"
2184
+ msgstr ""
2185
+
2186
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:248
2187
+ msgid "Mountain Province"
2188
+ msgstr ""
2189
+
2190
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:249
2191
+ msgid "Negros Occidental"
2192
+ msgstr ""
2193
+
2194
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:250
2195
+ msgid "Negros Oriental"
2196
+ msgstr ""
2197
+
2198
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:251
2199
+ msgid "Northern Samar"
2200
+ msgstr ""
2201
+
2202
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:252
2203
+ msgid "Nueva Ecija"
2204
+ msgstr ""
2205
+
2206
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:253
2207
+ msgid "Nueva Vizcaya"
2208
+ msgstr ""
2209
+
2210
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:254
2211
+ msgid "Occidental Mindoro"
2212
+ msgstr ""
2213
+
2214
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:255
2215
+ msgid "Oriental Mindoro"
2216
+ msgstr ""
2217
+
2218
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:256
2219
+ msgid "Palawan"
2220
+ msgstr ""
2221
+
2222
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:257
2223
+ msgid "Pampanga"
2224
+ msgstr ""
2225
+
2226
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:258
2227
+ msgid "Pangasinan"
2228
+ msgstr ""
2229
+
2230
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:259
2231
+ msgid "Quezon"
2232
+ msgstr ""
2233
+
2234
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:260
2235
+ msgid "Quirino"
2236
+ msgstr ""
2237
+
2238
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:261
2239
+ msgid "Rizal"
2240
+ msgstr ""
2241
+
2242
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:262
2243
+ msgid "Romblon"
2244
+ msgstr ""
2245
+
2246
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:263
2247
+ msgid "Samar"
2248
+ msgstr ""
2249
+
2250
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:264
2251
+ msgid "Sarangani"
2252
+ msgstr ""
2253
+
2254
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:265
2255
+ msgid "Siquijor"
2256
+ msgstr ""
2257
+
2258
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:266
2259
+ msgid "Sorsogon"
2260
+ msgstr ""
2261
+
2262
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:267
2263
+ msgid "South Cotabato"
2264
+ msgstr ""
2265
+
2266
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:268
2267
+ msgid "Southern Leyte"
2268
+ msgstr ""
2269
+
2270
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:269
2271
+ msgid "Sultan Kudarat"
2272
+ msgstr ""
2273
+
2274
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:270
2275
+ msgid "Sulu"
2276
+ msgstr ""
2277
+
2278
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:271
2279
+ msgid "Surigao del Norte"
2280
+ msgstr ""
2281
+
2282
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:272
2283
+ msgid "Surigao del Sur"
2284
+ msgstr ""
2285
+
2286
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:273
2287
+ msgid "Tarlac"
2288
+ msgstr ""
2289
+
2290
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:274
2291
+ msgid "Tawi-Tawi"
2292
+ msgstr ""
2293
+
2294
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:275
2295
+ msgid "Zambales"
2296
+ msgstr ""
2297
+
2298
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:276
2299
+ msgid "Zamboanga del Norte"
2300
+ msgstr ""
2301
+
2302
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:277
2303
+ msgid "Zamboanga del Sur"
2304
+ msgstr ""
2305
+
2306
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:278
2307
+ msgid "Zamboanga Sibugay"
2308
+ msgstr ""
2309
+
2310
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:279
2311
+ msgid "Metro Manila"
2312
+ msgstr ""
2313
+
2314
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:295
2315
+ msgid "El Callao"
2316
+ msgstr ""
2317
+
2318
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:296
2319
+ msgid "Municipalidad Metropolitana de Lima"
2320
+ msgstr ""
2321
+
2322
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:297
2323
+ msgid "Amazonas"
2324
+ msgstr ""
2325
+
2326
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:298
2327
+ msgid "Ancash"
2328
+ msgstr ""
2329
+
2330
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:299
2331
+ msgid "Apur&iacute;mac"
2332
+ msgstr ""
2333
+
2334
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:300
2335
+ msgid "Arequipa"
2336
+ msgstr ""
2337
+
2338
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:301
2339
+ msgid "Ayacucho"
2340
+ msgstr ""
2341
+
2342
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:302
2343
+ msgid "Cajamarca"
2344
+ msgstr ""
2345
+
2346
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:303
2347
+ msgid "Cusco"
2348
+ msgstr ""
2349
+
2350
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:304
2351
+ msgid "Huancavelica"
2352
+ msgstr ""
2353
+
2354
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:305
2355
+ msgid "Hu&aacute;nuco"
2356
+ msgstr ""
2357
+
2358
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:306
2359
+ msgid "Ica"
2360
+ msgstr ""
2361
+
2362
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:307
2363
+ msgid "Jun&iacute;n"
2364
+ msgstr ""
2365
+
2366
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:308
2367
+ msgid "La Libertad"
2368
+ msgstr ""
2369
+
2370
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:309
2371
+ msgid "Lambayeque"
2372
+ msgstr ""
2373
+
2374
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:310
2375
+ msgid "Lima"
2376
+ msgstr ""
2377
+
2378
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:311
2379
+ msgid "Loreto"
2380
+ msgstr ""
2381
+
2382
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:312
2383
+ msgid "Madre de Dios"
2384
+ msgstr ""
2385
+
2386
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:313
2387
+ msgid "Moquegua"
2388
+ msgstr ""
2389
+
2390
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:314
2391
+ msgid "Pasco"
2392
+ msgstr ""
2393
+
2394
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:315
2395
+ msgid "Piura"
2396
+ msgstr ""
2397
+
2398
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:316
2399
+ msgid "Puno"
2400
+ msgstr ""
2401
+
2402
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:317
2403
+ msgid "San Mart&iacute;n"
2404
+ msgstr ""
2405
+
2406
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:318
2407
+ msgid "Tacna"
2408
+ msgstr ""
2409
+
2410
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:319
2411
+ msgid "Tumbes"
2412
+ msgstr ""
2413
+
2414
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:320
2415
+ msgid "Ucayali"
2416
+ msgstr ""
2417
+
2418
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:336
2419
+ msgid "Bagmati"
2420
+ msgstr ""
2421
+
2422
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:337
2423
+ msgid "Bheri"
2424
+ msgstr ""
2425
+
2426
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:338
2427
+ msgid "Dhaulagiri"
2428
+ msgstr ""
2429
+
2430
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:339
2431
+ msgid "Gandaki"
2432
+ msgstr ""
2433
+
2434
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:340
2435
+ msgid "Janakpur"
2436
+ msgstr ""
2437
+
2438
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:341
2439
+ msgid "Karnali"
2440
+ msgstr ""
2441
+
2442
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:342
2443
+ msgid "Koshi"
2444
+ msgstr ""
2445
+
2446
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:343
2447
+ msgid "Lumbini"
2448
+ msgstr ""
2449
+
2450
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:344
2451
+ msgid "Mahakali"
2452
+ msgstr ""
2453
+
2454
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:345
2455
+ msgid "Mechi"
2456
+ msgstr ""
2457
+
2458
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:346
2459
+ msgid "Narayani"
2460
+ msgstr ""
2461
+
2462
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:347
2463
+ msgid "Rapti"
2464
+ msgstr ""
2465
+
2466
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:348
2467
+ msgid "Sagarmatha"
2468
+ msgstr ""
2469
+
2470
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:349
2471
+ msgid "Seti"
2472
+ msgstr ""
2473
+
2474
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:365
2475
+ msgid "Abia"
2476
+ msgstr ""
2477
+
2478
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:366
2479
+ msgid "Abuja"
2480
+ msgstr ""
2481
+
2482
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:367
2483
+ msgid "Adamawa"
2484
+ msgstr ""
2485
+
2486
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:368
2487
+ msgid "Akwa Ibom"
2488
+ msgstr ""
2489
+
2490
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:369
2491
+ msgid "Anambra"
2492
+ msgstr ""
2493
+
2494
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:370
2495
+ msgid "Bauchi"
2496
+ msgstr ""
2497
+
2498
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:371
2499
+ msgid "Bayelsa"
2500
+ msgstr ""
2501
+
2502
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:372
2503
+ msgid "Benue"
2504
+ msgstr ""
2505
+
2506
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:373
2507
+ msgid "Borno"
2508
+ msgstr ""
2509
+
2510
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:374
2511
+ msgid "Cross River"
2512
+ msgstr ""
2513
+
2514
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:375
2515
+ msgid "Delta"
2516
+ msgstr ""
2517
+
2518
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:376
2519
+ msgid "Ebonyi"
2520
+ msgstr ""
2521
+
2522
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:377
2523
+ msgid "Edo"
2524
+ msgstr ""
2525
+
2526
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:378
2527
+ msgid "Ekiti"
2528
+ msgstr ""
2529
+
2530
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:379
2531
+ msgid "Enugu"
2532
+ msgstr ""
2533
+
2534
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:380
2535
+ msgid "Gombe"
2536
+ msgstr ""
2537
+
2538
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:381
2539
+ msgid "Imo"
2540
+ msgstr ""
2541
+
2542
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:382
2543
+ msgid "Jigawa"
2544
+ msgstr ""
2545
+
2546
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:383
2547
+ msgid "Kaduna"
2548
+ msgstr ""
2549
+
2550
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:384
2551
+ msgid "Kano"
2552
+ msgstr ""
2553
+
2554
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:385
2555
+ msgid "Katsina"
2556
+ msgstr ""
2557
+
2558
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:386
2559
+ msgid "Kebbi"
2560
+ msgstr ""
2561
+
2562
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:387
2563
+ msgid "Kogi"
2564
+ msgstr ""
2565
+
2566
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:388
2567
+ msgid "Kwara"
2568
+ msgstr ""
2569
+
2570
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:389
2571
+ msgid "Lagos"
2572
+ msgstr ""
2573
+
2574
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:390
2575
+ msgid "Nasarawa"
2576
+ msgstr ""
2577
+
2578
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:392
2579
+ msgid "Ogun"
2580
+ msgstr ""
2581
+
2582
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:393
2583
+ msgid "Ondo"
2584
+ msgstr ""
2585
+
2586
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:394
2587
+ msgid "Osun"
2588
+ msgstr ""
2589
+
2590
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:395
2591
+ msgid "Oyo"
2592
+ msgstr ""
2593
+
2594
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:396
2595
+ msgid "Plateau"
2596
+ msgstr ""
2597
+
2598
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:397
2599
+ msgid "Rivers"
2600
+ msgstr ""
2601
+
2602
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:398
2603
+ msgid "Sokoto"
2604
+ msgstr ""
2605
+
2606
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:399
2607
+ msgid "Taraba"
2608
+ msgstr ""
2609
+
2610
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:400
2611
+ msgid "Yobe"
2612
+ msgstr ""
2613
+
2614
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:401
2615
+ msgid "Zamfara"
2616
+ msgstr ""
2617
+
2618
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:417
2619
+ msgid "Distrito Federal"
2620
+ msgstr ""
2621
+
2622
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:418
2623
+ msgid "Jalisco"
2624
+ msgstr ""
2625
+
2626
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:419
2627
+ msgid "Nuevo León"
2628
+ msgstr ""
2629
+
2630
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:420
2631
+ msgid "Aguascalientes"
2632
+ msgstr ""
2633
+
2634
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:421
2635
+ msgid "Baja California"
2636
+ msgstr ""
2637
+
2638
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:422
2639
+ msgid "Baja California Sur"
2640
+ msgstr ""
2641
+
2642
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:423
2643
+ msgid "Campeche"
2644
+ msgstr ""
2645
+
2646
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:424
2647
+ msgid "Chiapas"
2648
+ msgstr ""
2649
+
2650
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:425
2651
+ msgid "Chihuahua"
2652
+ msgstr ""
2653
+
2654
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:426
2655
+ msgid "Coahuila"
2656
+ msgstr ""
2657
+
2658
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:427
2659
+ msgid "Colima"
2660
+ msgstr ""
2661
+
2662
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:428
2663
+ msgid "Durango"
2664
+ msgstr ""
2665
+
2666
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:429
2667
+ msgid "Guanajuato"
2668
+ msgstr ""
2669
+
2670
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:430
2671
+ msgid "Guerrero"
2672
+ msgstr ""
2673
+
2674
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:431
2675
+ msgid "Hidalgo"
2676
+ msgstr ""
2677
+
2678
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:432
2679
+ msgid "Edo. de México"
2680
+ msgstr ""
2681
+
2682
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:433
2683
+ msgid "Michoacán"
2684
+ msgstr ""
2685
+
2686
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:434
2687
+ msgid "Morelos"
2688
+ msgstr ""
2689
+
2690
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:435
2691
+ msgid "Nayarit"
2692
+ msgstr ""
2693
+
2694
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:436
2695
+ msgid "Oaxaca"
2696
+ msgstr ""
2697
+
2698
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:437
2699
+ msgid "Puebla"
2700
+ msgstr ""
2701
+
2702
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:438
2703
+ msgid "Querétaro"
2704
+ msgstr ""
2705
+
2706
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:439
2707
+ msgid "Quintana Roo"
2708
+ msgstr ""
2709
+
2710
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:440
2711
+ msgid "San Luis Potosí"
2712
+ msgstr ""
2713
+
2714
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:441
2715
+ msgid "Sinaloa"
2716
+ msgstr ""
2717
+
2718
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:442
2719
+ msgid "Sonora"
2720
+ msgstr ""
2721
+
2722
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:443
2723
+ msgid "Tabasco"
2724
+ msgstr ""
2725
+
2726
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:444
2727
+ msgid "Tamaulipas"
2728
+ msgstr ""
2729
+
2730
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:445
2731
+ msgid "Tlaxcala"
2732
+ msgstr ""
2733
+
2734
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:446
2735
+ msgid "Veracruz"
2736
+ msgstr ""
2737
+
2738
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:447
2739
+ msgid "Yucatán"
2740
+ msgstr ""
2741
+
2742
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:448
2743
+ msgid "Zacatecas"
2744
+ msgstr ""
2745
+
2746
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:464
2747
+ msgid "Hokkaido"
2748
+ msgstr ""
2749
+
2750
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:465
2751
+ msgid "Aomori"
2752
+ msgstr ""
2753
+
2754
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:466
2755
+ msgid "Iwate"
2756
+ msgstr ""
2757
+
2758
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:467
2759
+ msgid "Miyagi"
2760
+ msgstr ""
2761
+
2762
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:468
2763
+ msgid "Akita"
2764
+ msgstr ""
2765
+
2766
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:469
2767
+ msgid "Yamagata"
2768
+ msgstr ""
2769
+
2770
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:470
2771
+ msgid "Fukushima"
2772
+ msgstr ""
2773
+
2774
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:471
2775
+ msgid "Ibaraki"
2776
+ msgstr ""
2777
+
2778
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:472
2779
+ msgid "Tochigi"
2780
+ msgstr ""
2781
+
2782
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:473
2783
+ msgid "Gunma"
2784
+ msgstr ""
2785
+
2786
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:474
2787
+ msgid "Saitama"
2788
+ msgstr ""
2789
+
2790
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:475
2791
+ msgid "Chiba"
2792
+ msgstr ""
2793
+
2794
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:476
2795
+ msgid "Tokyo"
2796
+ msgstr ""
2797
+
2798
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:477
2799
+ msgid "Kanagawa"
2800
+ msgstr ""
2801
+
2802
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:478
2803
+ msgid "Niigata"
2804
+ msgstr ""
2805
+
2806
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:479
2807
+ msgid "Toyama"
2808
+ msgstr ""
2809
+
2810
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:480
2811
+ msgid "Ishikawa"
2812
+ msgstr ""
2813
+
2814
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:481
2815
+ msgid "Fukui"
2816
+ msgstr ""
2817
+
2818
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:482
2819
+ msgid "Yamanashi"
2820
+ msgstr ""
2821
+
2822
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:483
2823
+ msgid "Nagano"
2824
+ msgstr ""
2825
+
2826
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:484
2827
+ msgid "Gifu"
2828
+ msgstr ""
2829
+
2830
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:485
2831
+ msgid "Shizuoka"
2832
+ msgstr ""
2833
+
2834
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:486
2835
+ msgid "Aichi"
2836
+ msgstr ""
2837
+
2838
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:487
2839
+ msgid "Mie"
2840
+ msgstr ""
2841
+
2842
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:488
2843
+ msgid "Shiga"
2844
+ msgstr ""
2845
+
2846
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:489
2847
+ msgid "Kyoto"
2848
+ msgstr ""
2849
+
2850
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:490
2851
+ msgid "Osaka"
2852
+ msgstr ""
2853
+
2854
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:491
2855
+ msgid "Hyogo"
2856
+ msgstr ""
2857
+
2858
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:492
2859
+ msgid "Nara"
2860
+ msgstr ""
2861
+
2862
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:493
2863
+ msgid "Wakayama"
2864
+ msgstr ""
2865
+
2866
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:494
2867
+ msgid "Tottori"
2868
+ msgstr ""
2869
+
2870
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:495
2871
+ msgid "Shimane"
2872
+ msgstr ""
2873
+
2874
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:496
2875
+ msgid "Okayama"
2876
+ msgstr ""
2877
+
2878
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:497
2879
+ msgid "Hiroshima"
2880
+ msgstr ""
2881
+
2882
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:498
2883
+ msgid "Yamaguchi"
2884
+ msgstr ""
2885
+
2886
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:499
2887
+ msgid "Tokushima"
2888
+ msgstr ""
2889
+
2890
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:500
2891
+ msgid "Kagawa"
2892
+ msgstr ""
2893
+
2894
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:501
2895
+ msgid "Ehime"
2896
+ msgstr ""
2897
+
2898
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:502
2899
+ msgid "Kochi"
2900
+ msgstr ""
2901
+
2902
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:503
2903
+ msgid "Fukuoka"
2904
+ msgstr ""
2905
+
2906
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:504
2907
+ msgid "Saga"
2908
+ msgstr ""
2909
+
2910
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:505
2911
+ msgid "Nagasaki"
2912
+ msgstr ""
2913
+
2914
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:506
2915
+ msgid "Kumamoto"
2916
+ msgstr ""
2917
+
2918
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:507
2919
+ msgid "Oita"
2920
+ msgstr ""
2921
+
2922
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:508
2923
+ msgid "Miyazaki"
2924
+ msgstr ""
2925
+
2926
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:509
2927
+ msgid "Kagoshima"
2928
+ msgstr ""
2929
+
2930
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:510
2931
+ msgid "Okinawa"
2932
+ msgstr ""
2933
+
2934
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:526
2935
+ msgid "Agrigento"
2936
+ msgstr ""
2937
+
2938
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:527
2939
+ msgid "Alessandria"
2940
+ msgstr ""
2941
+
2942
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:528
2943
+ msgid "Ancona"
2944
+ msgstr ""
2945
+
2946
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:529
2947
+ msgid "Aosta"
2948
+ msgstr ""
2949
+
2950
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:530
2951
+ msgid "Arezzo"
2952
+ msgstr ""
2953
+
2954
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:531
2955
+ msgid "Ascoli Piceno"
2956
+ msgstr ""
2957
+
2958
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:532
2959
+ msgid "Asti"
2960
+ msgstr ""
2961
+
2962
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:533
2963
+ msgid "Avellino"
2964
+ msgstr ""
2965
+
2966
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:534
2967
+ msgid "Bari"
2968
+ msgstr ""
2969
+
2970
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:535
2971
+ msgid "Barletta-Andria-Trani"
2972
+ msgstr ""
2973
+
2974
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:536
2975
+ msgid "Belluno"
2976
+ msgstr ""
2977
+
2978
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:537
2979
+ msgid "Benevento"
2980
+ msgstr ""
2981
+
2982
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:538
2983
+ msgid "Bergamo"
2984
+ msgstr ""
2985
+
2986
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:539
2987
+ msgid "Biella"
2988
+ msgstr ""
2989
+
2990
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:540
2991
+ msgid "Bologna"
2992
+ msgstr ""
2993
+
2994
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:541
2995
+ msgid "Bolzano"
2996
+ msgstr ""
2997
+
2998
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:542
2999
+ msgid "Brescia"
3000
+ msgstr ""
3001
+
3002
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:543
3003
+ msgid "Brindisi"
3004
+ msgstr ""
3005
+
3006
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:544
3007
+ msgid "Cagliari"
3008
+ msgstr ""
3009
+
3010
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:545
3011
+ msgid "Caltanissetta"
3012
+ msgstr ""
3013
+
3014
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:546
3015
+ msgid "Campobasso"
3016
+ msgstr ""
3017
+
3018
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:547
3019
+ msgid "Carbonia-Iglesias"
3020
+ msgstr ""
3021
+
3022
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:548
3023
+ msgid "Caserta"
3024
+ msgstr ""
3025
+
3026
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:549
3027
+ msgid "Catania"
3028
+ msgstr ""
3029
+
3030
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:550
3031
+ msgid "Catanzaro"
3032
+ msgstr ""
3033
+
3034
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:551
3035
+ msgid "Chieti"
3036
+ msgstr ""
3037
+
3038
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:552
3039
+ msgid "Como"
3040
+ msgstr ""
3041
+
3042
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:553
3043
+ msgid "Cosenza"
3044
+ msgstr ""
3045
+
3046
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:554
3047
+ msgid "Cremona"
3048
+ msgstr ""
3049
+
3050
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:555
3051
+ msgid "Crotone"
3052
+ msgstr ""
3053
+
3054
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:556
3055
+ msgid "Cuneo"
3056
+ msgstr ""
3057
+
3058
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:557
3059
+ msgid "Enna"
3060
+ msgstr ""
3061
+
3062
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:558
3063
+ msgid "Fermo"
3064
+ msgstr ""
3065
+
3066
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:559
3067
+ msgid "Ferrara"
3068
+ msgstr ""
3069
+
3070
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:560
3071
+ msgid "Firenze"
3072
+ msgstr ""
3073
+
3074
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:561
3075
+ msgid "Foggia"
3076
+ msgstr ""
3077
+
3078
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:562
3079
+ msgid "Forlì-Cesena"
3080
+ msgstr ""
3081
+
3082
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:563
3083
+ msgid "Frosinone"
3084
+ msgstr ""
3085
+
3086
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:564
3087
+ msgid "Genova"
3088
+ msgstr ""
3089
+
3090
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:565
3091
+ msgid "Gorizia"
3092
+ msgstr ""
3093
+
3094
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:566
3095
+ msgid "Grosseto"
3096
+ msgstr ""
3097
+
3098
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:567
3099
+ msgid "Imperia"
3100
+ msgstr ""
3101
+
3102
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:568
3103
+ msgid "Isernia"
3104
+ msgstr ""
3105
+
3106
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:569
3107
+ msgid "La Spezia"
3108
+ msgstr ""
3109
+
3110
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:570
3111
+ msgid "L'Aquila"
3112
+ msgstr ""
3113
+
3114
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:571
3115
+ msgid "Latina"
3116
+ msgstr ""
3117
+
3118
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:572
3119
+ msgid "Lecce"
3120
+ msgstr ""
3121
+
3122
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:573
3123
+ msgid "Lecco"
3124
+ msgstr ""
3125
+
3126
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:574
3127
+ msgid "Livorno"
3128
+ msgstr ""
3129
+
3130
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:575
3131
+ msgid "Lodi"
3132
+ msgstr ""
3133
+
3134
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:576
3135
+ msgid "Lucca"
3136
+ msgstr ""
3137
+
3138
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:577
3139
+ msgid "Macerata"
3140
+ msgstr ""
3141
+
3142
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:578
3143
+ msgid "Mantova"
3144
+ msgstr ""
3145
+
3146
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:579
3147
+ msgid "Massa-Carrara"
3148
+ msgstr ""
3149
+
3150
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:580
3151
+ msgid "Matera"
3152
+ msgstr ""
3153
+
3154
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:581
3155
+ msgid "Messina"
3156
+ msgstr ""
3157
+
3158
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:582
3159
+ msgid "Milano"
3160
+ msgstr ""
3161
+
3162
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:583
3163
+ msgid "Modena"
3164
+ msgstr ""
3165
+
3166
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:584
3167
+ msgid "Monza e della Brianza"
3168
+ msgstr ""
3169
+
3170
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:585
3171
+ msgid "Napoli"
3172
+ msgstr ""
3173
+
3174
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:586
3175
+ msgid "Novara"
3176
+ msgstr ""
3177
+
3178
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:587
3179
+ msgid "Nuoro"
3180
+ msgstr ""
3181
+
3182
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:588
3183
+ msgid "Olbia-Tempio"
3184
+ msgstr ""
3185
+
3186
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:589
3187
+ msgid "Oristano"
3188
+ msgstr ""
3189
+
3190
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:590
3191
+ msgid "Padova"
3192
+ msgstr ""
3193
+
3194
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:591
3195
+ msgid "Palermo"
3196
+ msgstr ""
3197
+
3198
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:592
3199
+ msgid "Parma"
3200
+ msgstr ""
3201
+
3202
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:593
3203
+ msgid "Pavia"
3204
+ msgstr ""
3205
+
3206
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:594
3207
+ msgid "Perugia"
3208
+ msgstr ""
3209
+
3210
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:595
3211
+ msgid "Pesaro e Urbino"
3212
+ msgstr ""
3213
+
3214
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:596
3215
+ msgid "Pescara"
3216
+ msgstr ""
3217
+
3218
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:597
3219
+ msgid "Piacenza"
3220
+ msgstr ""
3221
+
3222
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:598
3223
+ msgid "Pisa"
3224
+ msgstr ""
3225
+
3226
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:599
3227
+ msgid "Pistoia"
3228
+ msgstr ""
3229
+
3230
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:600
3231
+ msgid "Pordenone"
3232
+ msgstr ""
3233
+
3234
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:601
3235
+ msgid "Potenza"
3236
+ msgstr ""
3237
+
3238
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:602
3239
+ msgid "Prato"
3240
+ msgstr ""
3241
+
3242
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:603
3243
+ msgid "Ragusa"
3244
+ msgstr ""
3245
+
3246
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:604
3247
+ msgid "Ravenna"
3248
+ msgstr ""
3249
+
3250
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:605
3251
+ msgid "Reggio Calabria"
3252
+ msgstr ""
3253
+
3254
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:606
3255
+ msgid "Reggio Emilia"
3256
+ msgstr ""
3257
+
3258
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:607
3259
+ msgid "Rieti"
3260
+ msgstr ""
3261
+
3262
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:608
3263
+ msgid "Rimini"
3264
+ msgstr ""
3265
+
3266
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:609
3267
+ msgid "Roma"
3268
+ msgstr ""
3269
+
3270
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:610
3271
+ msgid "Rovigo"
3272
+ msgstr ""
3273
+
3274
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:611
3275
+ msgid "Salerno"
3276
+ msgstr ""
3277
+
3278
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:612
3279
+ msgid "Medio Campidano"
3280
+ msgstr ""
3281
+
3282
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:613
3283
+ msgid "Sassari"
3284
+ msgstr ""
3285
+
3286
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:614
3287
+ msgid "Savona"
3288
+ msgstr ""
3289
+
3290
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:615
3291
+ msgid "Siena"
3292
+ msgstr ""
3293
+
3294
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:616
3295
+ msgid "Siracusa"
3296
+ msgstr ""
3297
+
3298
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:617
3299
+ msgid "Sondrio"
3300
+ msgstr ""
3301
+
3302
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:618
3303
+ msgid "Taranto"
3304
+ msgstr ""
3305
+
3306
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:619
3307
+ msgid "Teramo"
3308
+ msgstr ""
3309
+
3310
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:620
3311
+ msgid "Terni"
3312
+ msgstr ""
3313
+
3314
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:621
3315
+ msgid "Torino"
3316
+ msgstr ""
3317
+
3318
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:622
3319
+ msgid "Ogliastra"
3320
+ msgstr ""
3321
+
3322
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:623
3323
+ msgid "Trapani"
3324
+ msgstr ""
3325
+
3326
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:624
3327
+ msgid "Trento"
3328
+ msgstr ""
3329
+
3330
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:625
3331
+ msgid "Treviso"
3332
+ msgstr ""
3333
+
3334
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:626
3335
+ msgid "Trieste"
3336
+ msgstr ""
3337
+
3338
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:627
3339
+ msgid "Udine"
3340
+ msgstr ""
3341
+
3342
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:628
3343
+ msgid "Varese"
3344
+ msgstr ""
3345
+
3346
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:629
3347
+ msgid "Venezia"
3348
+ msgstr ""
3349
+
3350
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:630
3351
+ msgid "Verbano-Cusio-Ossola"
3352
+ msgstr ""
3353
+
3354
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:631
3355
+ msgid "Vercelli"
3356
+ msgstr ""
3357
+
3358
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:632
3359
+ msgid "Verona"
3360
+ msgstr ""
3361
+
3362
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:633
3363
+ msgid "Vibo Valentia"
3364
+ msgstr ""
3365
+
3366
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:634
3367
+ msgid "Vicenza"
3368
+ msgstr ""
3369
+
3370
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:635
3371
+ msgid "Viterbo"
3372
+ msgstr ""
3373
+
3374
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:651
3375
+ msgid "Khuzestan (خوزستان)"
3376
+ msgstr ""
3377
+
3378
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:652
3379
+ msgid "Tehran (تهران)"
3380
+ msgstr ""
3381
+
3382
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:653
3383
+ msgid "Ilaam (ایلام)"
3384
+ msgstr ""
3385
+
3386
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:654
3387
+ msgid "Bushehr (بوشهر)"
3388
+ msgstr ""
3389
+
3390
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:655
3391
+ msgid "Ardabil (اردبیل)"
3392
+ msgstr ""
3393
+
3394
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:656
3395
+ msgid "Isfahan (اصفهان)"
3396
+ msgstr ""
3397
+
3398
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:657
3399
+ msgid "Yazd (یزد)"
3400
+ msgstr ""
3401
+
3402
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:658
3403
+ msgid "Kermanshah (کرمانشاه)"
3404
+ msgstr ""
3405
+
3406
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:659
3407
+ msgid "Kerman (کرمان)"
3408
+ msgstr ""
3409
+
3410
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:660
3411
+ msgid "Hamadan (همدان)"
3412
+ msgstr ""
3413
+
3414
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:661
3415
+ msgid "Ghazvin (قزوین)"
3416
+ msgstr ""
3417
+
3418
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:662
3419
+ msgid "Zanjan (زنجان)"
3420
+ msgstr ""
3421
+
3422
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:663
3423
+ msgid "Luristan (لرستان)"
3424
+ msgstr ""
3425
+
3426
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:664
3427
+ msgid "Alborz (البرز)"
3428
+ msgstr ""
3429
+
3430
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:665
3431
+ msgid "East Azarbaijan (آذربایجان شرقی)"
3432
+ msgstr ""
3433
+
3434
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:666
3435
+ msgid "West Azarbaijan (آذربایجان غربی)"
3436
+ msgstr ""
3437
+
3438
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:667
3439
+ msgid "Chaharmahal and Bakhtiari (چهارمحال و بختیاری)"
3440
+ msgstr ""
3441
+
3442
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:668
3443
+ msgid "South Khorasan (خراسان جنوبی)"
3444
+ msgstr ""
3445
+
3446
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:669
3447
+ msgid "Razavi Khorasan (خراسان رضوی)"
3448
+ msgstr ""
3449
+
3450
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:670
3451
+ msgid "North Khorasan (خراسان جنوبی)"
3452
+ msgstr ""
3453
+
3454
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:671
3455
+ msgid "Semnan (سمنان)"
3456
+ msgstr ""
3457
+
3458
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:672
3459
+ msgid "Fars (فارس)"
3460
+ msgstr ""
3461
+
3462
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:673
3463
+ msgid "Qom (قم)"
3464
+ msgstr ""
3465
+
3466
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:674
3467
+ msgid "Kurdistan / کردستان)"
3468
+ msgstr ""
3469
+
3470
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:675
3471
+ msgid "Kohgiluyeh and BoyerAhmad (کهگیلوییه و بویراحمد)"
3472
+ msgstr ""
3473
+
3474
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:676
3475
+ msgid "Golestan (گلستان)"
3476
+ msgstr ""
3477
+
3478
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:677
3479
+ msgid "Gilan (گیلان)"
3480
+ msgstr ""
3481
+
3482
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:678
3483
+ msgid "Mazandaran (مازندران)"
3484
+ msgstr ""
3485
+
3486
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:679
3487
+ msgid "Markazi (مرکزی)"
3488
+ msgstr ""
3489
+
3490
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:680
3491
+ msgid "Hormozgan (هرمزگان)"
3492
+ msgstr ""
3493
+
3494
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:681
3495
+ msgid "Sistan and Baluchestan (سیستان و بلوچستان)"
3496
+ msgstr ""
3497
+
3498
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:697
3499
+ msgid "Antrim"
3500
+ msgstr ""
3501
+
3502
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:698
3503
+ msgid "Armagh"
3504
+ msgstr ""
3505
+
3506
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:699
3507
+ msgid "Clare"
3508
+ msgstr ""
3509
+
3510
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:700
3511
+ msgid "Cork"
3512
+ msgstr ""
3513
+
3514
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:701
3515
+ msgid "Cavan"
3516
+ msgstr ""
3517
+
3518
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:702
3519
+ msgid "Carlow"
3520
+ msgstr ""
3521
+
3522
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:703
3523
+ msgid "Donegal"
3524
+ msgstr ""
3525
+
3526
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:704
3527
+ msgid "Dublin"
3528
+ msgstr ""
3529
+
3530
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:705
3531
+ msgid "Down"
3532
+ msgstr ""
3533
+
3534
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:706
3535
+ msgid "Derry"
3536
+ msgstr ""
3537
+
3538
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:707
3539
+ msgid "Fermanagh"
3540
+ msgstr ""
3541
+
3542
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:708
3543
+ msgid "Galway"
3544
+ msgstr ""
3545
+
3546
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:709
3547
+ msgid "Kildare"
3548
+ msgstr ""
3549
+
3550
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:710
3551
+ msgid "Kilkenny"
3552
+ msgstr ""
3553
+
3554
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:711
3555
+ msgid "Kerry"
3556
+ msgstr ""
3557
+
3558
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:712
3559
+ msgid "Longford"
3560
+ msgstr ""
3561
+
3562
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:713
3563
+ msgid "Louth"
3564
+ msgstr ""
3565
+
3566
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:714
3567
+ msgid "Limerick"
3568
+ msgstr ""
3569
+
3570
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:715
3571
+ msgid "Leitrim"
3572
+ msgstr ""
3573
+
3574
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:716
3575
+ msgid "Laois"
3576
+ msgstr ""
3577
+
3578
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:717
3579
+ msgid "Meath"
3580
+ msgstr ""
3581
+
3582
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:718
3583
+ msgid "Monaghan"
3584
+ msgstr ""
3585
+
3586
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:719
3587
+ msgid "Mayo"
3588
+ msgstr ""
3589
+
3590
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:720
3591
+ msgid "Offaly"
3592
+ msgstr ""
3593
+
3594
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:721
3595
+ msgid "Roscommon"
3596
+ msgstr ""
3597
+
3598
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:722
3599
+ msgid "Sligo"
3600
+ msgstr ""
3601
+
3602
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:723
3603
+ msgid "Tyrone"
3604
+ msgstr ""
3605
+
3606
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:724
3607
+ msgid "Tipperary"
3608
+ msgstr ""
3609
+
3610
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:725
3611
+ msgid "Waterford"
3612
+ msgstr ""
3613
+
3614
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:726
3615
+ msgid "Westmeath"
3616
+ msgstr ""
3617
+
3618
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:727
3619
+ msgid "Wicklow"
3620
+ msgstr ""
3621
+
3622
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:728
3623
+ msgid "Wexford"
3624
+ msgstr ""
3625
+
3626
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:744
3627
+ msgid "Αττική"
3628
+ msgstr ""
3629
+
3630
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:745
3631
+ msgid "Ανατολική Μακεδονία και Θράκη"
3632
+ msgstr ""
3633
+
3634
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:746
3635
+ msgid "Κεντρική Μακεδονία"
3636
+ msgstr ""
3637
+
3638
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:747
3639
+ msgid "Δυτική Μακεδονία"
3640
+ msgstr ""
3641
+
3642
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:748
3643
+ msgid "Ήπειρος"
3644
+ msgstr ""
3645
+
3646
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:749
3647
+ msgid "Θεσσαλία"
3648
+ msgstr ""
3649
+
3650
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:750
3651
+ msgid "Ιόνιοι Νήσοι"
3652
+ msgstr ""
3653
+
3654
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:751
3655
+ msgid "Δυτική Ελλάδα"
3656
+ msgstr ""
3657
+
3658
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:752
3659
+ msgid "Στερεά Ελλάδα"
3660
+ msgstr ""
3661
+
3662
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:753
3663
+ msgid "Πελοπόννησος"
3664
+ msgstr ""
3665
+
3666
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:754
3667
+ msgid "Βόρειο Αιγαίο"
3668
+ msgstr ""
3669
+
3670
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:755
3671
+ msgid "Νότιο Αιγαίο"
3672
+ msgstr ""
3673
+
3674
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:756
3675
+ msgid "Κρήτη"
3676
+ msgstr ""
3677
+
3678
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:772
3679
+ msgid "Chuquisaca"
3680
+ msgstr ""
3681
+
3682
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:773
3683
+ msgid "Beni"
3684
+ msgstr ""
3685
+
3686
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:774
3687
+ msgid "Cochabamba"
3688
+ msgstr ""
3689
+
3690
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:775
3691
+ msgid "La Paz"
3692
+ msgstr ""
3693
+
3694
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:776
3695
+ msgid "Oruro"
3696
+ msgstr ""
3697
+
3698
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:777
3699
+ msgid "Pando"
3700
+ msgstr ""
3701
+
3702
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:778
3703
+ msgid "Potosí"
3704
+ msgstr ""
3705
+
3706
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:779
3707
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:937
3708
+ msgid "Santa Cruz"
3709
+ msgstr ""
3710
+
3711
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:780
3712
+ msgid "Tarija"
3713
+ msgstr ""
3714
+
3715
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:796
3716
+ msgid "Blagoevgrad"
3717
+ msgstr ""
3718
+
3719
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:797
3720
+ msgid "Burgas"
3721
+ msgstr ""
3722
+
3723
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:798
3724
+ msgid "Dobrich"
3725
+ msgstr ""
3726
+
3727
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:799
3728
+ msgid "Gabrovo"
3729
+ msgstr ""
3730
+
3731
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:800
3732
+ msgid "Haskovo"
3733
+ msgstr ""
3734
+
3735
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:801
3736
+ msgid "Kardzhali"
3737
+ msgstr ""
3738
+
3739
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:802
3740
+ msgid "Kyustendil"
3741
+ msgstr ""
3742
+
3743
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:803
3744
+ msgid "Lovech"
3745
+ msgstr ""
3746
+
3747
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:804
3748
+ msgid "Montana"
3749
+ msgstr ""
3750
+
3751
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:805
3752
+ msgid "Pazardzhik"
3753
+ msgstr ""
3754
+
3755
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:806
3756
+ msgid "Pernik"
3757
+ msgstr ""
3758
+
3759
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:807
3760
+ msgid "Pleven"
3761
+ msgstr ""
3762
+
3763
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:808
3764
+ msgid "Plovdiv"
3765
+ msgstr ""
3766
+
3767
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:809
3768
+ msgid "Razgrad"
3769
+ msgstr ""
3770
+
3771
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:810
3772
+ msgid "Ruse"
3773
+ msgstr ""
3774
+
3775
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:811
3776
+ msgid "Shumen"
3777
+ msgstr ""
3778
+
3779
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:812
3780
+ msgid "Silistra"
3781
+ msgstr ""
3782
+
3783
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:813
3784
+ msgid "Sliven"
3785
+ msgstr ""
3786
+
3787
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:814
3788
+ msgid "Smolyan"
3789
+ msgstr ""
3790
+
3791
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:815
3792
+ msgid "Sofia"
3793
+ msgstr ""
3794
+
3795
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:816
3796
+ msgid "Sofia-Grad"
3797
+ msgstr ""
3798
+
3799
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:817
3800
+ msgid "Stara Zagora"
3801
+ msgstr ""
3802
+
3803
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:818
3804
+ msgid "Targovishte"
3805
+ msgstr ""
3806
+
3807
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:819
3808
+ msgid "Varna"
3809
+ msgstr ""
3810
+
3811
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:820
3812
+ msgid "Veliko Tarnovo"
3813
+ msgstr ""
3814
+
3815
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:821
3816
+ msgid "Vidin"
3817
+ msgstr ""
3818
+
3819
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:822
3820
+ msgid "Vratsa"
3821
+ msgstr ""
3822
+
3823
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:823
3824
+ msgid "Yambol"
3825
+ msgstr ""
3826
+
3827
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:839
3828
+ msgid "Bagerhat"
3829
+ msgstr ""
3830
+
3831
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:840
3832
+ msgid "Bandarban"
3833
+ msgstr ""
3834
+
3835
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:841
3836
+ msgid "Barguna"
3837
+ msgstr ""
3838
+
3839
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:842
3840
+ msgid "Barisal"
3841
+ msgstr ""
3842
+
3843
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:843
3844
+ msgid "Bhola"
3845
+ msgstr ""
3846
+
3847
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:844
3848
+ msgid "Bogra"
3849
+ msgstr ""
3850
+
3851
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:845
3852
+ msgid "Brahmanbaria"
3853
+ msgstr ""
3854
+
3855
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:846
3856
+ msgid "Chandpur"
3857
+ msgstr ""
3858
+
3859
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:847
3860
+ msgid "Chittagong"
3861
+ msgstr ""
3862
+
3863
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:848
3864
+ msgid "Chuadanga"
3865
+ msgstr ""
3866
+
3867
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:849
3868
+ msgid "Comilla"
3869
+ msgstr ""
3870
+
3871
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:850
3872
+ msgid "Cox's Bazar"
3873
+ msgstr ""
3874
+
3875
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:851
3876
+ msgid "Dhaka"
3877
+ msgstr ""
3878
+
3879
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:852
3880
+ msgid "Dinajpur"
3881
+ msgstr ""
3882
+
3883
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:853
3884
+ msgid "Faridpur "
3885
+ msgstr ""
3886
+
3887
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:854
3888
+ msgid "Feni"
3889
+ msgstr ""
3890
+
3891
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:855
3892
+ msgid "Gaibandha"
3893
+ msgstr ""
3894
+
3895
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:856
3896
+ msgid "Gazipur"
3897
+ msgstr ""
3898
+
3899
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:857
3900
+ msgid "Gopalganj"
3901
+ msgstr ""
3902
+
3903
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:858
3904
+ msgid "Habiganj"
3905
+ msgstr ""
3906
+
3907
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:859
3908
+ msgid "Jamalpur"
3909
+ msgstr ""
3910
+
3911
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:860
3912
+ msgid "Jessore"
3913
+ msgstr ""
3914
+
3915
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:861
3916
+ msgid "Jhalokati"
3917
+ msgstr ""
3918
+
3919
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:862
3920
+ msgid "Jhenaidah"
3921
+ msgstr ""
3922
+
3923
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:863
3924
+ msgid "Joypurhat"
3925
+ msgstr ""
3926
+
3927
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:864
3928
+ msgid "Khagrachhari"
3929
+ msgstr ""
3930
+
3931
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:865
3932
+ msgid "Khulna"
3933
+ msgstr ""
3934
+
3935
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:866
3936
+ msgid "Kishoreganj"
3937
+ msgstr ""
3938
+
3939
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:867
3940
+ msgid "Kurigram"
3941
+ msgstr ""
3942
+
3943
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:868
3944
+ msgid "Kushtia"
3945
+ msgstr ""
3946
+
3947
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:869
3948
+ msgid "Lakshmipur"
3949
+ msgstr ""
3950
+
3951
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:870
3952
+ msgid "Lalmonirhat"
3953
+ msgstr ""
3954
+
3955
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:871
3956
+ msgid "Madaripur"
3957
+ msgstr ""
3958
+
3959
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:872
3960
+ msgid "Magura"
3961
+ msgstr ""
3962
+
3963
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:873
3964
+ msgid "Manikganj "
3965
+ msgstr ""
3966
+
3967
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:874
3968
+ msgid "Meherpur"
3969
+ msgstr ""
3970
+
3971
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:875
3972
+ msgid "Moulvibazar"
3973
+ msgstr ""
3974
+
3975
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:876
3976
+ msgid "Munshiganj"
3977
+ msgstr ""
3978
+
3979
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:877
3980
+ msgid "Mymensingh"
3981
+ msgstr ""
3982
+
3983
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:878
3984
+ msgid "Naogaon"
3985
+ msgstr ""
3986
+
3987
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:879
3988
+ msgid "Narail"
3989
+ msgstr ""
3990
+
3991
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:880
3992
+ msgid "Narayanganj"
3993
+ msgstr ""
3994
+
3995
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:881
3996
+ msgid "Narsingdi"
3997
+ msgstr ""
3998
+
3999
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:882
4000
+ msgid "Natore"
4001
+ msgstr ""
4002
+
4003
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:883
4004
+ msgid "Nawabganj"
4005
+ msgstr ""
4006
+
4007
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:884
4008
+ msgid "Netrakona"
4009
+ msgstr ""
4010
+
4011
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:885
4012
+ msgid "Nilphamari"
4013
+ msgstr ""
4014
+
4015
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:886
4016
+ msgid "Noakhali"
4017
+ msgstr ""
4018
+
4019
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:887
4020
+ msgid "Pabna"
4021
+ msgstr ""
4022
+
4023
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:888
4024
+ msgid "Panchagarh"
4025
+ msgstr ""
4026
+
4027
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:889
4028
+ msgid "Patuakhali"
4029
+ msgstr ""
4030
+
4031
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:890
4032
+ msgid "Pirojpur"
4033
+ msgstr ""
4034
+
4035
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:891
4036
+ msgid "Rajbari"
4037
+ msgstr ""
4038
+
4039
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:892
4040
+ msgid "Rajshahi"
4041
+ msgstr ""
4042
+
4043
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:893
4044
+ msgid "Rangamati"
4045
+ msgstr ""
4046
+
4047
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:894
4048
+ msgid "Rangpur"
4049
+ msgstr ""
4050
+
4051
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:895
4052
+ msgid "Satkhira"
4053
+ msgstr ""
4054
+
4055
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:896
4056
+ msgid "Shariatpur"
4057
+ msgstr ""
4058
+
4059
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:897
4060
+ msgid "Sherpur"
4061
+ msgstr ""
4062
+
4063
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:898
4064
+ msgid "Sirajganj"
4065
+ msgstr ""
4066
+
4067
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:899
4068
+ msgid "Sunamganj"
4069
+ msgstr ""
4070
+
4071
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:900
4072
+ msgid "Sylhet"
4073
+ msgstr ""
4074
+
4075
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:901
4076
+ msgid "Tangail"
4077
+ msgstr ""
4078
+
4079
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:902
4080
+ msgid "Thakurgaon"
4081
+ msgstr ""
4082
+
4083
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:918
4084
+ msgid "Ciudad Aut&oacute;noma de Buenos Aires"
4085
+ msgstr ""
4086
+
4087
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:919
4088
+ msgid "Buenos Aires"
4089
+ msgstr ""
4090
+
4091
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:920
4092
+ msgid "Catamarca"
4093
+ msgstr ""
4094
+
4095
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:921
4096
+ msgid "Chaco"
4097
+ msgstr ""
4098
+
4099
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:922
4100
+ msgid "Chubut"
4101
+ msgstr ""
4102
+
4103
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:923
4104
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1526
4105
+ msgid "C&oacute;rdoba"
4106
+ msgstr ""
4107
+
4108
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:924
4109
+ msgid "Corrientes"
4110
+ msgstr ""
4111
+
4112
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:925
4113
+ msgid "Entre R&iacute;os"
4114
+ msgstr ""
4115
+
4116
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:926
4117
+ msgid "Formosa"
4118
+ msgstr ""
4119
+
4120
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:927
4121
+ msgid "Jujuy"
4122
+ msgstr ""
4123
+
4124
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:928
4125
+ msgid "La Pampa"
4126
+ msgstr ""
4127
+
4128
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:929
4129
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1535
4130
+ msgid "La Rioja"
4131
+ msgstr ""
4132
+
4133
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:930
4134
+ msgid "Mendoza"
4135
+ msgstr ""
4136
+
4137
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:931
4138
+ msgid "Misiones"
4139
+ msgstr ""
4140
+
4141
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:932
4142
+ msgid "Neuqu&eacute;n"
4143
+ msgstr ""
4144
+
4145
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:933
4146
+ msgid "R&iacute;o Negro"
4147
+ msgstr ""
4148
+
4149
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:934
4150
+ msgid "Salta"
4151
+ msgstr ""
4152
+
4153
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:935
4154
+ msgid "San Juan"
4155
+ msgstr ""
4156
+
4157
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:936
4158
+ msgid "San Luis"
4159
+ msgstr ""
4160
+
4161
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:938
4162
+ msgid "Santa Fe"
4163
+ msgstr ""
4164
+
4165
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:939
4166
+ msgid "Santiago del Estero"
4167
+ msgstr ""
4168
+
4169
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:940
4170
+ msgid "Tierra del Fuego"
4171
+ msgstr ""
4172
+
4173
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:941
4174
+ msgid "Tucum&aacute;n"
4175
+ msgstr ""
4176
+
4177
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1038
4178
+ msgid "Alberta"
4179
+ msgstr ""
4180
+
4181
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1039
4182
+ msgid "British Columbia"
4183
+ msgstr ""
4184
+
4185
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1040
4186
+ msgid "Manitoba"
4187
+ msgstr ""
4188
+
4189
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1041
4190
+ msgid "New Brunswick"
4191
+ msgstr ""
4192
+
4193
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1042
4194
+ msgid "Newfoundland and Labrador"
4195
+ msgstr ""
4196
+
4197
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1043
4198
+ msgid "Nova Scotia"
4199
+ msgstr ""
4200
+
4201
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1044
4202
+ msgid "Northwest Territories"
4203
+ msgstr ""
4204
+
4205
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1045
4206
+ msgid "Nunavut"
4207
+ msgstr ""
4208
+
4209
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1046
4210
+ msgid "Ontario"
4211
+ msgstr ""
4212
+
4213
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1047
4214
+ msgid "Prince Edward Island"
4215
+ msgstr ""
4216
+
4217
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1048
4218
+ msgid "Quebec"
4219
+ msgstr ""
4220
+
4221
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1049
4222
+ msgid "Saskatchewan"
4223
+ msgstr ""
4224
+
4225
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1050
4226
+ msgid "Yukon"
4227
+ msgstr ""
4228
+
4229
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1509
4230
+ msgid "A Coru&ntilde;a"
4231
+ msgstr ""
4232
+
4233
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1510
4234
+ msgid "Álava"
4235
+ msgstr ""
4236
+
4237
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1511
4238
+ msgid "Albacete"
4239
+ msgstr ""
4240
+
4241
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1512
4242
+ msgid "Alicante"
4243
+ msgstr ""
4244
+
4245
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1513
4246
+ msgid "Almer&iacute;a"
4247
+ msgstr ""
4248
+
4249
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1514
4250
+ msgid "Asturias"
4251
+ msgstr ""
4252
+
4253
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1515
4254
+ msgid "&Aacute;vila"
4255
+ msgstr ""
4256
+
4257
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1516
4258
+ msgid "Badajoz"
4259
+ msgstr ""
4260
+
4261
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1517
4262
+ msgid "Baleares"
4263
+ msgstr ""
4264
+
4265
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1518
4266
+ msgid "Barcelona"
4267
+ msgstr ""
4268
+
4269
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1519
4270
+ msgid "Burgos"
4271
+ msgstr ""
4272
+
4273
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1520
4274
+ msgid "C&aacute;ceres"
4275
+ msgstr ""
4276
+
4277
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1521
4278
+ msgid "C&aacute;diz"
4279
+ msgstr ""
4280
+
4281
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1522
4282
+ msgid "Cantabria"
4283
+ msgstr ""
4284
+
4285
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1523
4286
+ msgid "Castell&oacute;n"
4287
+ msgstr ""
4288
+
4289
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1524
4290
+ msgid "Ceuta"
4291
+ msgstr ""
4292
+
4293
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1525
4294
+ msgid "Ciudad Real"
4295
+ msgstr ""
4296
+
4297
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1527
4298
+ msgid "Cuenca"
4299
+ msgstr ""
4300
+
4301
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1528
4302
+ msgid "Girona"
4303
+ msgstr ""
4304
+
4305
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1529
4306
+ msgid "Granada"
4307
+ msgstr ""
4308
+
4309
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1530
4310
+ msgid "Guadalajara"
4311
+ msgstr ""
4312
+
4313
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1531
4314
+ msgid "Gipuzkoa"
4315
+ msgstr ""
4316
+
4317
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1532
4318
+ msgid "Huelva"
4319
+ msgstr ""
4320
+
4321
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1533
4322
+ msgid "Huesca"
4323
+ msgstr ""
4324
+
4325
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1534
4326
+ msgid "Ja&eacute;n"
4327
+ msgstr ""
4328
+
4329
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1536
4330
+ msgid "Las Palmas"
4331
+ msgstr ""
4332
+
4333
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1537
4334
+ msgid "Le&oacute;n"
4335
+ msgstr ""
4336
+
4337
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1538
4338
+ msgid "Lleida"
4339
+ msgstr ""
4340
+
4341
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1539
4342
+ msgid "Lugo"
4343
+ msgstr ""
4344
+
4345
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1540
4346
+ msgid "Madrid"
4347
+ msgstr ""
4348
+
4349
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1541
4350
+ msgid "M&aacute;laga"
4351
+ msgstr ""
4352
+
4353
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1542
4354
+ msgid "Melilla"
4355
+ msgstr ""
4356
+
4357
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1543
4358
+ msgid "Murcia"
4359
+ msgstr ""
4360
+
4361
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1544
4362
+ msgid "Navarra"
4363
+ msgstr ""
4364
+
4365
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1545
4366
+ msgid "Ourense"
4367
+ msgstr ""
4368
+
4369
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1546
4370
+ msgid "Palencia"
4371
+ msgstr ""
4372
+
4373
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1547
4374
+ msgid "Pontevedra"
4375
+ msgstr ""
4376
+
4377
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1548
4378
+ msgid "Salamanca"
4379
+ msgstr ""
4380
+
4381
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1549
4382
+ msgid "Santa Cruz de Tenerife"
4383
+ msgstr ""
4384
+
4385
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1550
4386
+ msgid "Segovia"
4387
+ msgstr ""
4388
+
4389
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1551
4390
+ msgid "Sevilla"
4391
+ msgstr ""
4392
+
4393
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1552
4394
+ msgid "Soria"
4395
+ msgstr ""
4396
+
4397
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1553
4398
+ msgid "Tarragona"
4399
+ msgstr ""
4400
+
4401
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1554
4402
+ msgid "Teruel"
4403
+ msgstr ""
4404
+
4405
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1555
4406
+ msgid "Toledo"
4407
+ msgstr ""
4408
+
4409
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1556
4410
+ msgid "Valencia"
4411
+ msgstr ""
4412
+
4413
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1557
4414
+ msgid "Valladolid"
4415
+ msgstr ""
4416
+
4417
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1558
4418
+ msgid "Bizkaia"
4419
+ msgstr ""
4420
+
4421
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1559
4422
+ msgid "Zamora"
4423
+ msgstr ""
4424
+
4425
+ #: src/Tickets/Commerce/Gateways/PayPal/Location/State.php:1560
4426
+ msgid "Zaragoza"
4427
+ msgstr ""
4428
+
4429
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/On_Boarding_Endpoint.php:141
4430
+ msgid "Unexpected response from PayPal when on boarding"
4431
  msgstr ""
4432
 
4433
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:341
4434
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:379
4435
+ msgid "Order ID in PayPal"
4436
  msgstr ""
4437
 
4438
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:354
4439
+ msgid "Payer ID token from PayPal"
4440
  msgstr ""
4441
 
4442
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:392
4443
+ msgid "To which status the failing should change this order to"
 
 
 
 
4444
  msgstr ""
4445
 
4446
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:405
4447
+ msgid "Why this particular order has failed."
4448
  msgstr ""
4449
 
4450
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:459
4451
+ msgid "Creating new PayPal order failed. Please try again."
4452
  msgstr ""
4453
 
4454
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:460
4455
+ msgid "Your PayPal order was cancelled."
4456
  msgstr ""
4457
 
4458
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:461
4459
+ msgid "Provided Order id is not valid."
 
 
 
 
4460
  msgstr ""
4461
 
4462
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:462
4463
+ msgid "There was a problem while processing your payment, please try again."
4464
  msgstr ""
4465
 
4466
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php:463
4467
+ msgid "There was a problem with the Order status change, please try again."
4468
  msgstr ""
4469
 
4470
  #. Translators: %s: The event type.
4482
  msgid "Failed PayPal webhook event verification"
4483
  msgstr ""
4484
 
4485
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php:223
4486
  msgid "Processes the Webhook as long as it includes valid Payment Event data"
4487
  msgstr ""
4488
 
4489
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php:230
4490
  msgid "Whether the processing was successful"
4491
  msgstr ""
4492
 
4493
+ #: src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php:239
4494
  msgid "The webhook was invalid and was not processed"
4495
  msgstr ""
4496
 
4499
  msgstr ""
4500
 
4501
  #. Translators: %s: The PayPal telephone number.
4502
+ #: src/Tickets/Commerce/Gateways/PayPal/Settings.php:86
4503
  msgid "Please call a PayPal support representative at %s"
4504
  msgstr ""
4505
 
4506
+ #: src/Tickets/Commerce/Gateways/PayPal/Settings.php:90
4507
  msgid ""
4508
  "Please reach out to PayPal support from your PayPal account Resolution Center"
4509
  msgstr ""
4510
 
4511
+ #: src/Tickets/Commerce/Gateways/PayPal/Settings.php:93
4512
  msgid " and relay the following message:"
4513
  msgstr ""
4514
 
4515
+ #: src/Tickets/Commerce/Gateways/PayPal/Signup.php:301
4516
+ msgid ""
4517
+ "There was a problem with the status check for your account. Please try "
4518
+ "disconnecting and connecting again. If the problem persists, please contact "
4519
+ "support."
4520
+ msgstr ""
4521
+
4522
+ #: src/Tickets/Commerce/Gateways/PayPal/Signup.php:311
4523
+ msgid "Set up an account to receive payment from PayPal"
4524
+ msgstr ""
4525
+
4526
+ #: src/Tickets/Commerce/Gateways/PayPal/Signup.php:315
4527
+ msgid "Confirm your primary email address"
4528
+ msgstr ""
4529
+
4530
+ #: src/Tickets/Commerce/Gateways/PayPal/Signup.php:326
4531
+ msgid ""
4532
+ "Your account was expected to be able to accept custom payments, but is not. "
4533
+ "Please make sure your\n"
4534
+ "\t\t\t\taccount country matches the country setting. If the problem "
4535
+ "persists, please contact PayPal."
4536
+ msgstr ""
4537
+
4538
+ #: src/Tickets/Commerce/Gateways/PayPal/Signup.php:345
4539
+ msgid "Reach out to PayPal to enable PPCP_CUSTOM for your account"
4540
+ msgstr ""
4541
+
4542
+ #: src/Tickets/Commerce/Gateways/PayPal/Signup.php:357
4543
+ msgid "Reach out to PayPal to resolve the following capabilities:"
4544
+ msgstr ""
4545
+
4546
  #: src/Tickets/Commerce/Gateways/PayPal/Tickets_Form.php:77
4547
  #: src/Tribe/Commerce/PayPal/Main.php:1908 src/Tribe/RSVP.php:2355
4548
  msgid "Return to the %1$sAttendees Report%2$s."
4580
  "confirmation."
4581
  msgstr ""
4582
 
4583
+ #: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Events.php:76
4584
+ msgid "Completed payments"
4585
+ msgstr ""
4586
+
4587
+ #: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Events.php:77
4588
+ msgid "Denied payments"
4589
+ msgstr ""
4590
+
4591
+ #: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Events.php:78
4592
+ msgid "Refunds"
4593
+ msgstr ""
4594
+
4595
+ #: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Events.php:79
4596
+ #: src/Tickets/Commerce/Status/Reversed.php:27
4597
+ msgid "Reversed"
4598
+ msgstr ""
4599
+
4600
  #. Translators: %s: The PayPal payment event.
4601
  #: src/Tickets/Commerce/Gateways/PayPal/Webhooks/Handler.php:72
4602
  msgid "Missing PayPal payment for webhook event: %s"
4617
  msgid "Change %1$s in PayPal from webhook: %2$s"
4618
  msgstr ""
4619
 
4620
+ #: src/Tickets/Commerce/Legacy_Compat.php:61
4621
  msgid "Tribe Commerce ( Legacy PayPal, not recommended )"
4622
  msgstr ""
4623
 
4624
+ #: src/Tickets/Commerce/Models/Attendee_Model.php:62
4625
  #: src/Tribe/Commerce/PayPal/Main.php:2959 src/Tribe/RSVP.php:2014
4626
  msgid "(deleted)"
4627
  msgstr ""
4628
 
4629
+ #: src/Tickets/Commerce/Module.php:20
4630
  msgid "Tickets Commerce"
4631
  msgstr ""
4632
 
4633
+ #: src/Tickets/Commerce/Order.php:192
4634
+ #: src/Tickets/Commerce/Reports/Orders.php:200
4635
+ #: src/Tribe/Commerce/PayPal/Main.php:468
4636
  msgid "Orders"
4637
  msgstr ""
4638
 
4639
+ #: src/Tickets/Commerce/Payments_Tab.php:38
4640
+ msgid "Payments"
4641
+ msgstr ""
4642
+
4643
+ #: src/Tickets/Commerce/Payments_Tab.php:53 src/Tribe/Admin/Notices.php:214
4644
+ #: src/Tribe/Main.php:666 src/admin-views/admin-welcome-message.php:56
4645
+ #: src/admin-views/tribe-commerce-settings.php:4
4646
+ msgid "Event Tickets Plus"
4647
+ msgstr ""
4648
+
4649
+ #: src/Tickets/Commerce/Payments_Tab.php:57
4650
+ #: src/admin-views/tribe-commerce-settings.php:9
4651
+ msgid "Check it out!"
4652
+ msgstr ""
4653
+
4654
+ #. Translators: %1$s: The Event Tickets Plus link, %2$s: The word "ticket" in
4655
+ #. lowercase, %3$s: The "Check it out!" link.
4656
+ #: src/Tickets/Commerce/Payments_Tab.php:61
4657
+ msgctxt "about Tickets Commerce"
4658
+ msgid ""
4659
+ "Tickets Commerce is a light implementation of a commerce gateway using "
4660
+ "PayPal and simplified stock handling. If you need more advanced features, "
4661
+ "take a look at %1$s. In addition to integrating with your favorite ecommerce "
4662
+ "provider, Event Tickets Plus includes options to collect custom information "
4663
+ "for attendees, check attendees in via QR codes, and share stock between "
4664
+ "%2$s. %3$s"
4665
+ msgstr ""
4666
+
4667
+ #: src/Tickets/Commerce/Payments_Tab.php:85
4668
+ msgid "Enable Tickets Commerce"
4669
+ msgstr ""
4670
+
4671
  #: src/Tickets/Commerce/Reports/Attendance_Totals.php:84
4672
  #: src/Tribe/Commerce/PayPal/Attendance_Totals.php:77
4673
  #: src/Tribe/RSVP/Attendance_Totals.php:49
4687
  msgid "Cancelled:"
4688
  msgstr ""
4689
 
4690
+ #. translators: The title of an event's Attendee List page in the dashboard.
4691
+ #. %1$s is the name of the event. %2$d is numeric the event ID.
4692
+ #: src/Tickets/Commerce/Reports/Attendees.php:50
4693
+ msgid "Attendees for: %1$s [#%2$d]"
4694
+ msgstr ""
4695
+
4696
+ #: src/Tickets/Commerce/Reports/Attendees.php:85
4697
+ msgid "Tickets Commerce Attendees"
4698
+ msgstr ""
4699
+
4700
+ #. translators: The title of an event's Attendee List page in the dashboard.
4701
+ #. %1$s is the name of the event.
4702
+ #: src/Tickets/Commerce/Reports/Attendees.php:117
4703
+ msgid "%1$s - Attendee list"
4704
+ msgstr ""
4705
+
4706
+ #: src/Tickets/Commerce/Reports/Attendees.php:399 src/Tribe/Attendees.php:659
4707
+ msgid "attendees"
4708
+ msgstr ""
4709
+
4710
+ #: src/Tickets/Commerce/Reports/Attendees.php:483 src/Tribe/Attendees.php:513
4711
+ msgctxt "attendee export"
4712
+ msgid "Order ID"
4713
+ msgstr ""
4714
+
4715
+ #: src/Tickets/Commerce/Reports/Attendees.php:484 src/Tribe/Attendees.php:514
4716
+ msgctxt "attendee export"
4717
+ msgid "Order Status"
4718
+ msgstr ""
4719
+
4720
+ #: src/Tickets/Commerce/Reports/Attendees.php:485 src/Tribe/Attendees.php:515
4721
+ msgctxt "attendee export"
4722
+ msgid "%s ID"
4723
+ msgstr ""
4724
+
4725
+ #: src/Tickets/Commerce/Reports/Attendees.php:486 src/Tribe/Attendees.php:516
4726
+ msgctxt "attendee export"
4727
+ msgid "Ticket Holder Name"
4728
+ msgstr ""
4729
+
4730
+ #: src/Tickets/Commerce/Reports/Attendees.php:487 src/Tribe/Attendees.php:517
4731
+ msgctxt "attendee export"
4732
+ msgid "Ticket Holder Email Address"
4733
+ msgstr ""
4734
+
4735
+ #: src/Tickets/Commerce/Reports/Attendees.php:488 src/Tribe/Attendees.php:518
4736
+ msgctxt "attendee export"
4737
+ msgid "Purchaser Name"
4738
+ msgstr ""
4739
+
4740
+ #: src/Tickets/Commerce/Reports/Attendees.php:489 src/Tribe/Attendees.php:519
4741
+ msgctxt "attendee export"
4742
+ msgid "Purchaser Email Address"
4743
+ msgstr ""
4744
+
4745
+ #: src/Tickets/Commerce/Reports/Attendees.php:522 src/Tribe/Attendees.php:548
4746
+ #: src/admin-views/tribe-commerce-settings.php:93
4747
+ #: src/admin-views/tribe-commerce-settings.php:105
4748
+ msgid "Yes"
4749
+ msgstr ""
4750
+
4751
+ #: src/Tickets/Commerce/Reports/Orders.php:48 src/admin-views/tpp-orders.php:32
4752
+ msgid "Orders Report"
4753
+ msgstr ""
4754
+
4755
+ #: src/Tickets/Commerce/Reports/Orders.php:92
4756
  #: src/Tribe/Commerce/PayPal/Main.php:1724
4757
  msgid "Sales report"
4758
  msgstr ""
4759
 
4760
+ #: src/Tickets/Commerce/Reports/Orders.php:133
4761
  #: src/Tribe/Commerce/PayPal/Main.php:1750
4762
  msgid "Report"
4763
  msgstr ""
4764
 
4765
+ #: src/Tickets/Commerce/Reports/Orders.php:198
4766
+ msgid "See Tickets Commerce purchases for this %s"
 
 
 
 
 
 
4767
  msgstr ""
4768
 
4769
+ #: src/Tickets/Commerce/Reports/Orders.php:228
4770
+ msgid "Tickets Commerce Orders"
 
4771
  msgstr ""
4772
 
4773
+ #: src/Tickets/Commerce/Reports/Orders.php:288
4774
+ msgctxt "Browser title"
4775
+ msgid "%s - Tickets Commerce Orders"
 
 
 
 
 
 
 
 
4776
  msgstr ""
4777
 
4778
+ #: src/Tickets/Commerce/Settings.php:138
4779
+ msgid "Tickets Commerce Test Mode Active"
4780
  msgstr ""
4781
 
4782
+ #: src/Tickets/Commerce/Settings.php:174
4783
  msgid "-- No page set --"
4784
  msgstr ""
4785
 
4786
+ #: src/Tickets/Commerce/Settings.php:189
4787
  msgid "Tickets Commerce Settings"
4788
  msgstr ""
4789
 
4790
+ #: src/Tickets/Commerce/Settings.php:193
4791
  msgid "Enable Test Mode"
4792
  msgstr ""
4793
 
4794
+ #: src/Tickets/Commerce/Settings.php:194
4795
  msgid ""
4796
  "Enables Test mode for testing payments. Any payments made will be done on "
4797
  "\"sandbox\" accounts."
4798
  msgstr ""
4799
 
4800
+ #: src/Tickets/Commerce/Settings.php:200
4801
  #: src/admin-views/tribe-commerce-settings.php:136
4802
  msgid "Currency Code"
4803
  msgstr ""
4804
 
4805
+ #: src/Tickets/Commerce/Settings.php:201
4806
  msgid "The currency that will be used for Tickets Commerce transactions."
4807
  msgstr ""
4808
 
4809
+ #: src/Tickets/Commerce/Settings.php:208
4810
  #: src/admin-views/tribe-commerce-settings.php:144
4811
  msgid "Stock Handling"
4812
  msgstr ""
4813
 
4814
  #. Translators: %s: The word "ticket" in lowercase.
4815
+ #: src/Tickets/Commerce/Settings.php:212
4816
  msgctxt "tickets fields settings paypal stock handling"
4817
  msgid ""
4818
  "When a customer purchases a %s, the payment gateway might flag the order as "
4822
 
4823
  #. Translators: %1$s: The word "ticket" in lowercase. %2$s: `<strong>` opening
4824
  #. tag. %3$s: `</strong>` closing tag.
4825
+ #: src/Tickets/Commerce/Settings.php:221
4826
  msgid ""
4827
  "Decrease available %1$s stock as soon as a %2$sPending%3$s order is created."
4828
  msgstr ""
4829
 
4830
  #. Translators: %1$s: The word "ticket" in lowercase. %2$s: `<strong>` opening
4831
  #. tag. %3$s: `</strong>` closing tag.
4832
+ #: src/Tickets/Commerce/Settings.php:228
4833
  msgid ""
4834
  "Only decrease available %1$s stock if an order is confirmed as %2$sCompleted"
4835
  "%3$s by the payment gateway."
4836
  msgstr ""
4837
 
4838
+ #: src/Tickets/Commerce/Settings.php:238
4839
  msgid "Checkout page"
4840
  msgstr ""
4841
 
4842
  #. Translators: %s: The [shortcode] for the success page.
4843
+ #: src/Tickets/Commerce/Settings.php:242
4844
  msgid ""
4845
  "This is the page where customers go to complete their purchase. Use the %s "
4846
  "shortcode to display the checkout experience in the page content."
4847
  msgstr ""
4848
 
4849
+ #: src/Tickets/Commerce/Settings.php:253
4850
  #: src/admin-views/tribe-commerce-settings.php:162
4851
  msgid "Success page"
4852
  msgstr ""
4853
 
4854
  #. Translators: %s: The [shortcode] for the success page.
4855
+ #: src/Tickets/Commerce/Settings.php:257
4856
  msgid ""
4857
  "After a successful order, users will be redirected to this page. Use the %s "
4858
  "shortcode to display the order confirmation to the user in the page content."
4859
  msgstr ""
4860
 
4861
+ #: src/Tickets/Commerce/Settings.php:268
4862
  #: src/admin-views/tribe-commerce-settings.php:176
4863
  msgid "Confirmation email sender address"
4864
  msgstr ""
4865
 
4866
  #. Translators: %s: The word "tickets" in lowercase.
4867
+ #: src/Tickets/Commerce/Settings.php:272
4868
  msgctxt "tickets fields settings confirmation email"
4869
  msgid ""
4870
  "Email address that %s customers will receive confirmation from. Leave empty "
4871
  "to use the default WordPress site email address."
4872
  msgstr ""
4873
 
4874
+ #: src/Tickets/Commerce/Settings.php:283
4875
  #: src/admin-views/tribe-commerce-settings.php:185
4876
  msgid "Confirmation email sender name"
4877
  msgstr ""
4878
 
4879
  #. Translators: %s: The word "ticket" in lowercase.
4880
+ #: src/Tickets/Commerce/Settings.php:287
4881
  #: src/admin-views/tribe-commerce-settings.php:186
4882
  msgctxt "tickets fields settings paypal email sender"
4883
  msgid ""
4885
  "purchase."
4886
  msgstr ""
4887
 
4888
+ #: src/Tickets/Commerce/Settings.php:298
4889
  #: src/admin-views/tribe-commerce-settings.php:194
4890
  msgid "Confirmation email subject"
4891
  msgstr ""
4892
 
4893
  #. Translators: %s: The word "ticket" in lowercase.
4894
+ #: src/Tickets/Commerce/Settings.php:302
4895
  #: src/admin-views/tribe-commerce-settings.php:195
4896
  msgctxt "tickets fields settings paypal email subject"
4897
  msgid ""
4900
  msgstr ""
4901
 
4902
  #. Translators: %s: The word "tickets" in lowercase.
4903
+ #: src/Tickets/Commerce/Settings.php:310
4904
  #: src/admin-views/tribe-commerce-settings.php:197
4905
  msgctxt "tickets fields settings paypal email subject"
4906
  msgid "You have %s!"
4936
  msgid "Pending"
4937
  msgstr ""
4938
 
4939
+ #: src/Tickets/Commerce/Status/Pending.php:94
4940
  msgid "This order contained an invalid Ticket (ID: %1$d)"
4941
  msgstr ""
4942
 
4943
+ #: src/Tickets/Commerce/Status/Pending.php:109
4944
  msgid "This order contained a Ticket with an invalid Event (Event ID: %1$d)"
4945
  msgstr ""
4946
 
4947
+ #: src/Tickets/Commerce/Status/Pending.php:123
4948
  msgid "Cannot purchase zero of \"%1$s\""
4949
  msgstr ""
4950
 
4951
+ #: src/Tickets/Commerce/Status/Pending.php:140
4952
  msgid "Insufficient stock for \"%1$s\""
4953
  msgstr ""
4954
 
4955
+ #: src/Tickets/Commerce/Status/Pending.php:156
4956
  msgid "%s will be available on %s at %s"
4957
  msgstr ""
4958
 
4959
+ #: src/Tickets/Commerce/Status/Pending.php:158 src/Tribe/Tickets.php:3147
4960
  msgid "%s are no longer available."
4961
  msgstr ""
4962
 
4963
+ #: src/Tickets/Commerce/Status/Pending.php:160 src/Tribe/Tickets.php:3149
4964
  msgid "There are no %s available at this time."
4965
  msgstr ""
4966
 
4968
  msgid "Refunded"
4969
  msgstr ""
4970
 
 
 
 
 
4971
  #: src/Tickets/Commerce/Status/Undefined.php:28
4972
  msgid "Undefined"
4973
  msgstr ""
4980
  msgid "Tickets Commerce Success Page"
4981
  msgstr ""
4982
 
4983
+ #: src/Tickets/Commerce/Ticket.php:139 src/Tribe/Commerce/PayPal/Main.php:440
4984
  msgid "Tickets"
4985
  msgstr ""
4986
 
4987
+ #: src/Tickets/Commerce/Ticket.php:141
4988
  msgid "Tickets Commerce Tickets"
4989
  msgstr ""
4990
 
4991
+ #: src/Tickets/Commerce/Ticket.php:142
4992
  msgid "Tickets Commerce Ticket"
4993
  msgstr ""
4994
 
5029
  msgstr ""
5030
 
5031
  #: src/Tribe/Admin/Move_Ticket_Types.php:72
5032
+ #: src/Tribe/Admin/Move_Tickets.php:263
5033
  msgid "All supported types"
5034
  msgstr ""
5035
 
5057
  msgstr ""
5058
 
5059
  #: src/Tribe/Admin/Move_Ticket_Types.php:320
5060
+ #: src/Tribe/Admin/Move_Tickets.php:758
5061
  msgid "Changes to your tickets from %s"
5062
  msgstr ""
5063
 
5087
  msgid "Loading, please wait&hellip;"
5088
  msgstr ""
5089
 
5090
+ #: src/Tribe/Admin/Move_Tickets.php:236
5091
  msgctxt "attendee screen bulk actions"
5092
  msgid "Move"
5093
  msgstr ""
5094
 
5095
+ #: src/Tribe/Admin/Move_Tickets.php:450
5096
  msgid ""
5097
  "%1$s could not be moved: valid %2$s IDs or a destination ID were not "
5098
  "provided."
5099
  msgstr ""
5100
 
5101
+ #: src/Tribe/Admin/Move_Tickets.php:462
5102
  msgid ""
5103
  "%s could not be moved: there was an unexpected failure during reassignment."
5104
  msgstr ""
5105
 
5106
+ #: src/Tribe/Admin/Move_Tickets.php:471
5107
  msgctxt "moved tickets success message fragment"
5108
  msgid "assigned to %s"
5109
  msgstr ""
5110
 
5111
+ #: src/Tribe/Admin/Move_Tickets.php:478
5112
  msgctxt "moved tickets success message fragment"
5113
  msgid "moved to %s and"
5114
  msgstr ""
5115
 
5116
+ #: src/Tribe/Admin/Move_Tickets.php:485
5117
  msgid ""
5118
  "%1$d attendee for %2$s was successfully %3$s. By default, we adjust capacity "
5119
  "and stock, however, we recommend reviewing each as needed to ensure numbers "
5127
  msgstr[0] ""
5128
  msgstr[1] ""
5129
 
5130
+ #: src/Tribe/Admin/Move_Tickets.php:633
5131
  msgid "This ticket was moved to %1$s %2$s from %3$s %4$s"
5132
  msgstr ""
5133
 
5134
+ #: src/Tribe/Admin/Move_Tickets.php:820
5135
  msgid "This ticket was moved to %1$s from %2$s"
5136
  msgstr ""
5137
 
5186
  "for %2$s."
5187
  msgstr ""
5188
 
5189
+ #: src/Tribe/Admin/Settings/Service_Provider.php:52
5190
  #: src/admin-views/admin-welcome-message.php:135
5191
  msgid "Getting Started Guide"
5192
  msgstr ""
5193
 
5194
+ #: src/Tribe/Admin/Settings/Service_Provider.php:56
5195
+ msgid "Event Tickets Manual"
5196
  msgstr ""
5197
 
5198
+ #: src/Tribe/Admin/Settings/Service_Provider.php:60
5199
+ msgid "What is Tickets Commerce?"
5200
  msgstr ""
5201
 
5202
+ #: src/Tribe/Admin/Settings/Service_Provider.php:65
5203
+ msgid "Configuring Tickets Commerce"
5204
  msgstr ""
5205
 
5206
+ #: src/Tribe/Admin/Settings/Service_Provider.php:70
5207
+ msgid "Using RSVPs"
5208
  msgstr ""
5209
 
5210
+ #: src/Tribe/Admin/Settings/Service_Provider.php:74
5211
+ msgid "Managing Orders and Attendees"
5212
  msgstr ""
5213
 
5214
+ #: src/Tribe/Admin/Settings/Service_Provider.php:81
5215
  msgid "Switching from Tribe Commerce to WooCommerce"
5216
  msgstr ""
5217
 
5218
+ #: src/Tribe/Admin/Settings/Service_Provider.php:85
5219
  msgid "Setting Up E-Commerce Plugins for Selling Tickets"
5220
  msgstr ""
5221
 
5222
+ #: src/Tribe/Admin/Settings/Service_Provider.php:89
5223
  msgid "Tickets & WooCommerce"
5224
  msgstr ""
5225
 
5226
+ #: src/Tribe/Admin/Settings/Service_Provider.php:93
5227
  msgid "Creating Tickets"
5228
  msgstr ""
5229
 
5230
+ #: src/Tribe/Admin/Settings/Service_Provider.php:97
5231
  msgid "Event Tickets and Event Tickets Plus Settings Overview"
5232
  msgstr ""
5233
 
5234
+ #: src/Tribe/Admin/Settings/Service_Provider.php:101
5235
  msgid "Event Tickets Plus Manual"
5236
  msgstr ""
5237
 
5238
+ #: src/Tribe/Admin/Settings/Service_Provider.php:142
5239
+ #: src/Tribe/Admin/Settings/Service_Provider.php:190
5240
+ msgid "Upgrade to Tickets Commerce"
5241
+ msgstr ""
5242
+
5243
+ #: src/Tribe/Admin/Settings/Service_Provider.php:143
5244
+ msgid ""
5245
+ "Try our new Tickets Commerce payment system! It’s fast and simple to set up "
5246
+ "and offers a better experience and features. Best of all, <i>it’s free!</i>"
5247
+ msgstr ""
5248
+
5249
+ #: src/Tribe/Admin/Settings/Service_Provider.php:144
5250
+ msgid "Get started"
5251
+ msgstr ""
5252
+
5253
+ #: src/Tribe/Admin/Settings/Service_Provider.php:146
5254
+ #: src/Tribe/Admin/Settings/Service_Provider.php:194
5255
+ #: src/admin-views/admin-welcome-message.php:157
5256
+ #: src/admin-views/admin-welcome-message.php:179
5257
+ #: src/admin-views/admin-welcome-message.php:199
5258
+ msgid "Learn more"
5259
+ msgstr ""
5260
+
5261
+ #: src/Tribe/Admin/Settings/Service_Provider.php:191
5262
+ msgid ""
5263
+ "Tribe Commerce has been replaced by our new payments system, Tickets "
5264
+ "Commerce. It’s fast, free and simple to set up! You can <a href=\"https://"
5265
+ "evnt.is/1axu\" rel=\"noopener noreferrer\" target=\"_blank\">still continue "
5266
+ "using Tribe Commerce</a> but we highly recommend upgrading to Tickets "
5267
+ "Commerce."
5268
+ msgstr ""
5269
+
5270
+ #: src/Tribe/Admin/Settings/Service_Provider.php:192
5271
+ msgid "Get Started"
5272
+ msgstr ""
5273
+
5274
+ #: src/Tribe/Admin/Settings/Service_Provider.php:203
5275
+ #: src/admin-views/tribe-commerce-settings.php:55
5276
+ msgid "Tribe Commerce"
5277
+ msgstr ""
5278
+
5279
  #: src/Tribe/Admin/Ticket_History.php:34
5280
  msgctxt "attendee table"
5281
  msgid "View history"
5298
  msgid "Unticketed"
5299
  msgstr ""
5300
 
5301
+ #: src/Tribe/Assets.php:209 src/views/tickets/tpp-success.php:97
5302
  msgid "%s header image"
5303
  msgstr ""
5304
 
5305
+ #: src/Tribe/Assets.php:210
5306
  msgid "Set as %s header"
5307
  msgstr ""
5308
 
5309
+ #: src/Tribe/Assets.php:266
5310
  msgid "Are you sure you want to delete this ticket? This cannot be undone."
5311
  msgstr ""
5312
 
5313
+ #: src/Tribe/Assets.php:272
5314
  msgid ""
5315
  "It looks like you have modified your shared capacity setting but have not "
5316
  "saved or updated the post."
5317
  msgstr ""
5318
 
5319
+ #: src/Tribe/Assets.php:292 src/Tribe/Metabox.php:575
5320
  msgid "Please enter in without thousand separators and currency symbols."
5321
  msgstr ""
5322
 
5323
+ #: src/Tribe/Assets.php:485
5324
  msgid ""
5325
  "There is unsaved attendee information. Are you sure you want to continue?"
5326
  msgstr ""
5330
  msgid "Deleted Attendees:"
5331
  msgstr ""
5332
 
5333
+ #: src/Tribe/Attendee_Registration/Template.php:398
5334
+ #: src/views/v2/rsvp/ari/sidebar/title.php:15
5335
+ msgid "Attendee Registration"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5336
  msgstr ""
5337
 
5338
+ #: src/Tribe/Attendees.php:84
5339
+ msgid "Post type"
 
5340
  msgstr ""
5341
 
5342
+ #: src/Tribe/Attendees.php:113
5343
+ msgctxt "attendee event actions"
5344
+ msgid "Edit %s"
5345
  msgstr ""
5346
 
5347
+ #: src/Tribe/Attendees.php:114
5348
+ msgctxt "attendee event actions"
5349
+ msgid "View %s"
5350
  msgstr ""
5351
 
5352
+ #: src/Tribe/Attendees.php:117
5353
+ msgctxt "attendee event actions"
5354
+ msgid "Edit"
5355
  msgstr ""
5356
 
5357
+ #: src/Tribe/Attendees.php:118
5358
+ msgctxt "attendee event actions"
5359
+ msgid "View"
5360
  msgstr ""
5361
 
5362
+ #: src/Tribe/Attendees.php:145
5363
+ msgctxt "attendee summary"
5364
+ msgid "Checked in:"
5365
  msgstr ""
5366
 
5367
+ #: src/Tribe/Attendees.php:210 src/admin-views/list.php:93
5368
+ msgid "See who purchased tickets to this event"
 
5369
  msgstr ""
5370
 
5371
+ #: src/Tribe/Attendees.php:440
5372
+ msgid "%s - Attendee list"
5373
  msgstr ""
5374
 
5375
+ #: src/Tribe/Attendees.php:697
5376
  msgid "Invalid Event ID"
5377
  msgstr ""
5378
 
5379
+ #: src/Tribe/Attendees.php:714
5380
  msgid "Cheatin Huh?"
5381
  msgstr ""
5382
 
5383
+ #: src/Tribe/Attendees.php:720
5384
  msgid "Empty user and email"
5385
  msgstr ""
5386
 
5387
+ #: src/Tribe/Attendees.php:732
5388
  msgid "Invalid Email"
5389
  msgstr ""
5390
 
5391
+ #: src/Tribe/Attendees.php:738 src/Tribe/Attendees.php:754
5392
  msgid "Invalid User ID"
5393
  msgstr ""
5394
 
5395
+ #: src/Tribe/Attendees.php:774
5396
  msgid "Attendee List for: %s"
5397
  msgstr ""
5398
 
5399
+ #: src/Tribe/Attendees.php:775
5400
  msgid "Error when sending the email"
5401
  msgstr ""
5402
 
5403
+ #: src/Tribe/Attendees.php:782
5404
  msgid "Email sent successfully!"
5405
  msgstr ""
5406
 
5407
+ #: src/Tribe/Attendees.php:997 src/Tribe/Attendees_Table.php:609
5408
+ #: src/admin-views/commerce/reports/attendees.php:27
5409
  msgid "Export"
5410
  msgstr ""
5411
 
5412
+ #: src/Tribe/Attendees_Table.php:116
 
 
 
 
5413
  msgctxt "attendee table"
5414
  msgid "Primary Information"
5415
  msgstr ""
5416
 
5417
+ #: src/Tribe/Attendees_Table.php:117
5418
  msgctxt "attendee table"
5419
  msgid "Security Code"
5420
  msgstr ""
5421
 
5422
+ #: src/Tribe/Attendees_Table.php:118
5423
  msgctxt "attendee table"
5424
  msgid "Status"
5425
  msgstr ""
5426
 
5427
+ #: src/Tribe/Attendees_Table.php:119 src/Tribe/Attendees_Table.php:126
5428
  msgctxt "attendee table"
5429
  msgid "Check in"
5430
  msgstr ""
5431
 
5432
+ #: src/Tribe/Attendees_Table.php:505
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5433
  msgid "View order"
5434
  msgstr ""
5435
 
5436
+ #: src/Tribe/Attendees_Table.php:608
5437
  msgid "Print"
5438
  msgstr ""
5439
 
5440
+ #: src/Tribe/Attendees_Table.php:643 src/admin-views/list.php:41
 
 
 
 
 
 
 
 
 
5441
  msgid "Delete"
5442
  msgstr ""
5443
 
5444
+ #: src/Tribe/Attendees_Table.php:644
5445
  msgid "Check in"
5446
  msgstr ""
5447
 
5448
+ #: src/Tribe/Attendees_Table.php:645
5449
  msgid "Undo Check in"
5450
  msgstr ""
5451
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5452
  #: src/Tribe/CSV_Importer/Column_Names.php:34
5453
  msgid "Event Name or ID or Slug"
5454
  msgstr ""
5690
  msgstr ""
5691
 
5692
  #: src/Tribe/Commerce/PayPal/Orders/Report.php:108
5693
+ #: src/Tribe/Commerce/PayPal/Orders/Report.php:161
5694
  #: src/Tribe/Commerce/PayPal/Orders/Tab.php:33
5695
  msgid "PayPal Orders"
5696
  msgstr ""
5697
 
5698
+ #: src/Tribe/Commerce/PayPal/Orders/Report.php:220
5699
  msgctxt "Browser title"
5700
  msgid "%s - PayPal Orders"
5701
  msgstr ""
5702
 
5703
+ #: src/Tribe/Commerce/PayPal/Orders/Report.php:325
5704
+ #: src/admin-views/commerce/reports/attendees.php:52
5705
+ #: src/admin-views/commerce/reports/orders.php:38
5706
  msgid "Search Orders"
5707
  msgstr ""
5708
 
5714
  msgid "Number of orders per page:"
5715
  msgstr ""
5716
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5717
  #: src/Tribe/Commerce/PayPal/Orders/Table.php:184
5718
  msgid "Refunded with %s"
5719
  msgstr ""
5720
 
 
 
 
 
5721
  #: src/Tribe/Commerce/PayPal/Oversell/Admin_Notice_Decorator.php:111
5722
  msgid "An event"
5723
  msgstr ""
5791
  msgid "Are you sure you want to cancel?"
5792
  msgstr ""
5793
 
5794
+ #: src/Tribe/Editor/Blocks/Tickets.php:297 src/Tribe/Tickets.php:4201
5795
  msgctxt "Error message title, will be followed by the error code."
5796
  msgid "API Error"
5797
  msgstr ""
5798
 
5799
+ #: src/Tribe/Editor/Blocks/Tickets.php:298 src/Tribe/Tickets.php:4202
5800
  msgid ""
5801
  "Refresh this page or wait a few minutes before trying again. If this happens "
5802
  "repeatedly, please contact the Site Admin."
5803
  msgstr ""
5804
 
5805
+ #: src/Tribe/Editor/Blocks/Tickets.php:299 src/Tribe/Tickets.php:4203
5806
  msgid ""
5807
  "The ticket for this event has sold out and has been removed from your cart."
5808
  msgstr ""
5809
 
5810
+ #: src/Tribe/Editor/Blocks/Tickets.php:300 src/Tribe/Tickets.php:4204
5811
+ #: src/views/v2/commerce/order/header/title-empty.php:28
5812
  msgid "Whoops!"
5813
  msgstr ""
5814
 
5815
+ #: src/Tribe/Editor/Blocks/Tickets.php:301 src/Tribe/Tickets.php:4205
5816
  msgctxt "The %s will change based on the error produced."
5817
  msgid "You have %s ticket(s) with a field that requires information."
5818
  msgstr ""
6977
  msgstr ""
6978
 
6979
  #: src/Tribe/Status/Abstract_Commerce.php:246
6980
+ #: src/admin-views/commerce/reports/orders/summary.php:65
6981
  msgid "Sold counts tickets from completed orders only."
6982
  msgstr ""
6983
 
6984
  #: src/Tribe/Status/Abstract_Commerce.php:266
6985
+ #: src/admin-views/commerce/reports/orders/summary.php:111
6986
  msgid "Total Sales counts %s from all completed orders."
6987
  msgstr ""
6988
 
6989
  #: src/Tribe/Status/Abstract_Commerce.php:282
6990
+ #: src/admin-views/commerce/reports/orders/summary.php:136
6991
  msgid ""
6992
  "Total Ordered counts tickets from orders of any status, including pending "
6993
  "and refunded."
7006
  msgid "Capacity"
7007
  msgstr ""
7008
 
7009
+ #: src/Tribe/Tickets.php:472
7010
  msgctxt "delete link"
7011
  msgid "Delete %s"
7012
  msgstr ""
7013
 
7014
+ #: src/Tribe/Tickets.php:554
7015
  msgid "Move %s"
7016
  msgstr ""
7017
 
7018
+ #: src/Tribe/Tickets.php:1757
7019
  msgid "Shared capacity with other tickets"
7020
  msgstr ""
7021
 
7022
+ #: src/Tribe/Tickets.php:1758
7023
  msgid "Set capacity for this ticket only"
7024
  msgstr ""
7025
 
7026
  #. translators: %1$s: The singular of "RSVP" or "ticket", %2$s: The plural of
7027
  #. "RSVPs" or "tickets", %3$s: The site name.
7028
+ #: src/Tribe/Tickets.php:2375
7029
  msgctxt "The default RSVP/ticket email subject"
7030
  msgid "Your %1$s from %3$s"
7031
  msgid_plural "Your %2$s from %3$s"
7032
  msgstr[0] ""
7033
  msgstr[1] ""
7034
 
7035
+ #: src/Tribe/Tickets.php:3099
7036
  msgid "%s are not available as this %s has passed."
7037
  msgstr ""
7038
 
7039
+ #: src/Tribe/Tickets.php:3135
7040
  msgid "%s will be available on "
7041
  msgstr ""
7042
 
7043
+ #: src/Tribe/Tickets.php:3141
7044
  msgid " at "
7045
  msgstr ""
7046
 
7047
  #. translators: %s: Tickets label
7048
+ #: src/Tribe/Tickets.php:3144 src/views/blocks/tickets/content-inactive.php:19
7049
  #: src/views/v2/tickets/item/content/inactive.php:53
7050
  #: src/views/v2/tickets/item/inactive.php:63
7051
  msgid "%s are not yet available"
7132
 
7133
  #: src/admin-views/admin-welcome-message.php:102
7134
  #: src/admin-views/admin-welcome-message.php:112
7135
+ msgid "Set Up Tickets Commerce"
7136
  msgstr ""
7137
 
7138
  #: src/admin-views/admin-welcome-message.php:118
7183
  msgid "Need a language other than English? We've got you covered here."
7184
  msgstr ""
7185
 
 
 
 
 
 
 
7186
  #: src/admin-views/admin-welcome-message.php:164
7187
  msgid "Illustration of a phone screen with a person's face"
7188
  msgstr ""
7265
  msgid "Select..."
7266
  msgstr ""
7267
 
7268
+ #: src/admin-views/attendees-email.php:28
7269
  msgid "Send the attendee list by email"
7270
  msgstr ""
7271
 
7272
+ #: src/admin-views/attendees-email.php:34
7273
  msgid "Select a User:"
7274
  msgstr ""
7275
 
7276
+ #: src/admin-views/attendees-email.php:37
7277
  #: src/views/modal/registration-js.php:129
7278
  msgid "or"
7279
  msgstr ""
7280
 
7281
+ #: src/admin-views/attendees-email.php:39
7282
  msgid "Email Address:"
7283
  msgstr ""
7284
 
7285
+ #: src/admin-views/attendees-email.php:61
7286
  msgid "Send Email"
7287
  msgstr ""
7288
 
 
 
 
 
7289
  #: src/admin-views/attendees-table/check-in-button.php:31
7290
  msgid "Undo Check In"
7291
  msgstr ""
7292
 
7293
  #: src/admin-views/attendees.php:71
7294
+ #: src/admin-views/commerce/reports/attendees/summary.php:22
7295
  msgctxt "attendee screen summary"
7296
  msgid "%s Details"
7297
  msgstr ""
7298
 
7299
  #: src/admin-views/attendees.php:113
7300
+ #: src/admin-views/commerce/reports/attendees/summary.php:76
7301
  msgctxt "attendee screen summary"
7302
  msgid "Overview"
7303
  msgstr ""
7319
  msgid "Leave blank for unlimited"
7320
  msgstr ""
7321
 
7322
+ #: src/admin-views/commerce/metabox/sku.php:24
7323
  #: src/admin-views/tpp-metabox-sku.php:20
7324
  msgid "SKU:"
7325
  msgstr ""
7326
 
7327
+ #: src/admin-views/commerce/metabox/sku.php:37
7328
  #: src/admin-views/tpp-metabox-sku.php:33
7329
  msgid "A unique identifying code for each %s type you're selling"
7330
  msgstr ""
7331
 
7332
+ #: src/admin-views/commerce/reports/orders/summary.php:15
7333
+ #: src/admin-views/tpp-orders.php:62
7334
+ msgctxt "post type details"
7335
+ msgid "%s Details"
7336
+ msgstr ""
7337
+
7338
+ #: src/admin-views/commerce/reports/orders/summary.php:60
7339
+ #: src/admin-views/tpp-orders.php:107
7340
+ msgid "Sales by %s Type"
7341
+ msgstr ""
7342
+
7343
+ #: src/admin-views/commerce/reports/orders/summary.php:99
7344
+ #: src/admin-views/tpp-orders.php:132
7345
+ msgid "Total %s Sales"
7346
+ msgstr ""
7347
+
7348
+ #: src/admin-views/commerce/reports/orders/summary.php:120
7349
+ #: src/admin-views/tpp-orders.php:150
7350
+ msgid "Total %s Ordered"
7351
+ msgstr ""
7352
+
7353
  #: src/admin-views/editor/button-view-orders.php:46
7354
  msgid "View Orders"
7355
  msgstr ""
7996
  msgid "Beginner Resources"
7997
  msgstr ""
7998
 
7999
+ #: src/admin-views/settings/getting-started.php:36
8000
  msgid "Advanced Plus Features"
8001
  msgstr ""
8002
 
8003
+ #: src/admin-views/settings/getting-started.php:39
8004
  msgid "Need To Upgrade?"
8005
  msgstr ""
8006
 
8007
+ #: src/admin-views/settings/tickets-commerce/banner/new-badge.php:23
8008
+ msgid "New!"
8009
+ msgstr ""
8010
+
8011
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/actions/refresh-access-token.php:28
8012
+ msgid "Refresh Access Token"
8013
+ msgstr ""
8014
+
8015
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/actions/refresh-connection.php:31
8016
+ msgid "Resync payment connection"
8017
+ msgstr ""
8018
+
8019
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/actions/refresh-user-info.php:29
8020
+ msgid "Refresh User Info"
8021
+ msgstr ""
8022
+
8023
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/actions/refresh-webhook.php:29
8024
+ msgid "Refresh Webhook"
8025
+ msgstr ""
8026
+
8027
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/connection.php:27
8028
  msgid "Connected as:"
8029
  msgstr ""
8030
 
8031
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/connection.php:37
8032
  msgid "Disconnect"
8033
  msgstr ""
8034
 
8035
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/paypal-status.php:25
8036
  msgid "PayPal Status:"
8037
  msgstr ""
8038
 
8039
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/paypal-status.php:29
8040
  msgid "Connected"
8041
  msgstr ""
8042
 
8043
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/webhooks.php:34
8044
+ msgid "Webhooks:"
8045
  msgstr ""
8046
 
8047
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/active/webhooks.php:51
8048
+ msgid "payment connection error"
8049
  msgstr ""
8050
 
8051
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/help-links/configuring.php:29
8052
+ msgid "Learn more about configuring PayPal payments"
8053
  msgstr ""
8054
 
8055
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/help-links/troubleshooting.php:24
8056
+ msgid "Get troubleshooting help"
8057
+ msgstr ""
8058
+
8059
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/inactive.php:24
8060
  msgid "Accept online payments with PayPal!"
8061
  msgstr ""
8062
 
8063
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/inactive.php:29
8064
  msgid ""
8065
  "Start selling tickets to your events today with PayPal. Attendees can "
8066
+ "purchase tickets directly on your site using debit or credit cards with no "
8067
  "additional fees."
8068
  msgstr ""
8069
 
8070
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/logo/features.php:19
8071
  msgid "Credit and debit card payments"
8072
  msgstr ""
8073
 
8074
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/logo/features.php:22
8075
  msgid "Easy no-API key connection"
8076
  msgstr ""
8077
 
8078
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/logo/features.php:25
8079
  msgid "Accept payments from around the world"
8080
  msgstr ""
8081
 
8082
+ #: src/admin-views/settings/tickets-commerce/paypal/connect/logo/features.php:28
8083
  msgid "Supports 3D Secure payments"
8084
  msgstr ""
8085
 
8087
  msgid "PayPal Logo Image"
8088
  msgstr ""
8089
 
8090
+ #: src/admin-views/settings/tickets-commerce/paypal/signup-link.php:21
8091
+ msgid "Select your country of operation"
8092
+ msgstr ""
8093
+
8094
+ #: src/admin-views/settings/tickets-commerce/paypal/signup-link.php:43
8095
  msgid "Connect Automatically with <i>PayPal</i>"
8096
  msgstr ""
8097
 
8108
  msgid "Click to hide history"
8109
  msgstr ""
8110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8111
  #: src/admin-views/tribe-commerce-settings.php:13
8112
  msgctxt "about Tribe Commerce"
8113
  msgid ""
8115
  "and simplified stock handling. If you need more advanced features, take a "
8116
  "look at %1$s. In addition to integrating with your favorite ecommerce "
8117
  "provider, Event Tickets Plus includes options to collect custom information "
8118
+ "for attendees, check attendees in via QR codes, and share stock between "
8119
+ "%2$s. %3$s"
8120
  msgstr ""
8121
 
8122
  #: src/admin-views/tribe-commerce-settings.php:40
8141
  msgid "Your site address is: %s"
8142
  msgstr ""
8143
 
 
 
 
 
8144
  #: src/admin-views/tribe-commerce-settings.php:63
8145
  msgid "Enable Tribe Commerce "
8146
  msgstr ""
8517
 
8518
  #: src/views/blocks/attendees/view-link.php:40
8519
  #: src/views/tickets/orders-pp-tickets.php:30
8520
+ #: src/views/tickets/orders-rsvp.php:28
8521
+ #: src/views/tickets/orders-tc-tickets.php:22 src/views/tickets/orders.php:95
8522
  #: src/views/tickets/view-link.php:56
8523
  msgctxt "fallback post type singular name"
8524
  msgid "Post"
8987
  msgid "%s Type"
8988
  msgstr ""
8989
 
 
 
 
 
8990
  #. Translators: 1: plural RSVP label, 2: post type label.
8991
+ #. Translators: 1: plural Tickets label, 2: post type label.
8992
  #: src/views/tickets/orders-pp-tickets.php:38
8993
  #: src/views/tickets/orders-rsvp.php:37
8994
+ #: src/views/tickets/orders-tc-tickets.php:31
8995
  msgid "My %1$s for this %2$s"
8996
  msgstr ""
8997
 
9007
 
9008
  #: src/views/tickets/orders-pp-tickets.php:77
9009
  #: src/views/tickets/orders-rsvp.php:78
9010
+ #: src/views/tickets/orders-tc-tickets.php:90
9011
  msgid "Attendee %d"
9012
  msgstr ""
9013
 
9031
  msgid "RSVP: "
9032
  msgstr ""
9033
 
9034
+ #. Translators: 1: order number, 2: count of attendees in the order, 3: ticket
9035
+ #. label (dynamically singular or plural), 4: purchaser name, 5: linked
9036
+ #. purchaser email, 6: date of purchase.
9037
+ #: src/views/tickets/orders-tc-tickets.php:60
9038
+ msgid "Order #%1$s: %2$d %3$s reserved by %4$s (%5$s) on %6$s"
9039
+ msgstr ""
9040
+
9041
+ #: src/views/tickets/orders.php:79
9042
  msgctxt "notice if user does not have tickets"
9043
  msgid "You don't have %s for this event"
9044
  msgstr ""
9045
 
9046
+ #: src/views/tickets/orders.php:84
9047
  msgctxt "notice if user does not have rsvps"
9048
  msgid "You don't have %s for this event"
9049
  msgstr ""
9050
 
9051
  #. Translators: %s: post type label.
9052
+ #: src/views/tickets/orders.php:104
9053
  msgid "View %s"
9054
  msgstr ""
9055
 
9056
+ #: src/views/tickets/orders.php:169
9057
  msgid "Update %s"
9058
  msgstr ""
9059
 
9185
  msgid "Less info"
9186
  msgstr ""
9187
 
9188
+ #: src/views/v2/commerce/checkout/footer/gateway-error.php:42
9189
+ #: src/views/v2/commerce/checkout.php:28
9190
  msgid "Checkout Unavailable!"
9191
  msgstr ""
9192
 
9193
+ #: src/views/v2/commerce/checkout/footer/gateway-error.php:43
9194
  msgid ""
9195
  "Checkout is not available at this time because a payment method has not been "
9196
  "set up. Please notify the site administrator."
9205
  msgid "back"
9206
  msgstr ""
9207
 
 
 
 
 
9208
  #. Translators: %1$s: Plural `Tickets` label.
9209
  #: src/views/v2/commerce/checkout/header/title.php:31
9210
  msgid "Purchase %1$s"
9223
  msgid "create a new account"
9224
  msgstr ""
9225
 
9226
+ #: src/views/v2/commerce/checkout.php:29
9227
+ msgid ""
9228
+ "Checkout is not available at this time because a payment method has not been "
9229
+ "set up for this event. Please notify the site administrator."
9230
+ msgstr ""
9231
+
9232
+ #: src/views/v2/commerce/checkout.php:53
9233
+ msgid "Checkout Error!"
9234
+ msgstr ""
9235
+
9236
+ #: src/views/v2/commerce/gateway/paypal/advanced-payments/fields/card-name.php:35
9237
+ #: src/views/v2/commerce/gateway/paypal/advanced-payments/fields/card-name.php:43
9238
+ msgid "Name on Card"
9239
+ msgstr ""
9240
+
9241
+ #: src/views/v2/commerce/gateway/paypal/advanced-payments/fields/card-number.php:35
9242
+ msgid "Card Number"
9243
+ msgstr ""
9244
+
9245
+ #: src/views/v2/commerce/gateway/paypal/advanced-payments/fields/cvv.php:35
9246
+ msgid "CVV"
9247
+ msgstr ""
9248
+
9249
+ #: src/views/v2/commerce/gateway/paypal/advanced-payments/fields/expiration-date.php:35
9250
+ msgid "Expiration Date"
9251
+ msgstr ""
9252
+
9253
+ #: src/views/v2/commerce/gateway/paypal/advanced-payments/fields/submit.php:27
9254
+ msgid "Purchase Tickets"
9255
+ msgstr ""
9256
+
9257
+ #: src/views/v2/commerce/gateway/paypal/advanced-payments/separator.php:25
9258
+ msgid "or pay with card"
9259
+ msgstr ""
9260
+
9261
+ #: src/views/v2/commerce/gateway/paypal/order/details/capture-id.php:40
9262
+ msgid "PayPal Capture ID:"
9263
+ msgstr ""
9264
+
9265
+ #: src/views/v2/commerce/order/description/order-empty.php:28
9266
+ msgid "No order information is available because no purchase was made."
9267
+ msgstr ""
9268
+
9269
  #. Translators: %1$s: Plural `tickets` in lowercase.
9270
+ #: src/views/v2/commerce/order/description/order.php:31
9271
  msgid ""
9272
  "Thank you. Your order has been received. A receipt for purchase and any "
9273
  "digital %1$s ordered will be emailed to you shortly."
9285
  msgid "Order number:"
9286
  msgstr ""
9287
 
9288
+ #: src/views/v2/commerce/order/details/payment-method.php:34
9289
  msgid "Payment method:"
9290
  msgstr ""
9291
 
9293
  msgid "Total:"
9294
  msgstr ""
9295
 
9296
+ #: src/views/v2/commerce/order/footer/links/back-home.php:29
9297
  msgid "back home"
9298
  msgstr ""
9299
 
9300
  #. Translators: %1$s: Plural `events` in lowercase.
9301
+ #: src/views/v2/commerce/order/footer/links/browse-events.php:36
9302
  msgid "browse more %1$s"
9303
  msgstr ""
9304
 
9305
+ #: src/views/v2/commerce/order/header/title.php:28
9306
  msgid "Order Received!"
9307
  msgstr ""
9308
 
readme.txt CHANGED
@@ -2,10 +2,10 @@
2
 
3
  Contributors: theeventscalendar, brianjessee, camwynsp, paulkim, aguseo, bordoni, borkweb, GeoffBel, geoffgraham, jentheo, leahkoerper, lucatume, neillmcshea, vicskf, zbtirrell, juanfra
4
  Tags: tickets, registration, The Events Calendar, RSVP, ticket sales, attendee management
5
- Requires at least: 4.9.18
6
  Tested up to: 5.8.1
7
- Stable tag: 5.1.10
8
- Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -116,11 +116,12 @@ Event Tickets is translated into multiple languages, including German, Danish, a
116
 
117
  1. RSVP on event.
118
  2. Front-end ticket in page.
119
- 3. PayPal checkout.
120
  4. Attendee report.
121
  5. Emailed ticket.
122
  6. Tickets settings.
123
  7. Add new ticket.
 
124
 
125
  == Frequently Asked Questions ==
126
 
@@ -170,7 +171,7 @@ The following add-ons are available for The Events Calendar:
170
 
171
  = I have a feature idea. What's the best way to tell you about it? =
172
 
173
- We've got a [ProductStash](https://app.productstash.io/the-events-calendar-suite-roadmap#/ideas) page where we're actively watching for feature ideas from the community. Vote up existing feature requests or add your own, and help us shape the future of the products business in a way that best meets the community's needs.
174
 
175
  = I've still got questions. Where can I find answers? =
176
 
@@ -178,6 +179,11 @@ Check out our extensive [knowledgebase](https://evnt.is/18wm) for articles on us
178
 
179
  == Changelog ==
180
 
 
 
 
 
 
181
  = [5.1.10] 2021-09-27 =
182
 
183
  * Enhancement - When editing an RSVP or ticket in the block editor, allow title to wrap to multiple lines. [ET-1089]
@@ -201,61 +207,4 @@ Check out our extensive [knowledgebase](https://evnt.is/18wm) for articles on us
201
  * Fix - Updated deprecated hook `block_categories` to use `block_categories_all`. [ET-1156]
202
  * Language - 37 new strings added, 162 updated, 6 fuzzied, and 20 obsoleted
203
 
204
- = [5.1.8] 2021-08-24 =
205
-
206
- * Tweak - Add new event repository schema for finding all events with RSVPs or Tickets.
207
- * Language - 0 new strings added, 1 updated, 0 fuzzied, and 0 obsoleted
208
-
209
- = [5.1.7] 2021-08-03 =
210
-
211
- * Feature - Added export button next to the page title on the Attendees page. [ET-1145]
212
- * Tweak - Changed the word `Purchaser` to `Attendee` when email confirmation is sent for purchasing a ticket. [ETP-655]
213
- * Tweak - Added `$attendees` parameter to the `tribe_report_page_after_text_label` action. [ET-1145]
214
- * Tweak - Removed the edit column when printing the Attendees list. [ETP-702]
215
- * Tweak - Added "Delete" functionality for the tickets area in the classic editor. [ET-1107]
216
- * Language - 1 new strings added, 61 updated, 0 fuzzied, and 0 obsoleted
217
-
218
- = [5.1.6] 2021-07-07 =
219
-
220
- * Tweak - Added support for HTML in Ticket description field. [ET-1135]
221
- * Tweak - Added `$ticket_id` parameter to the `tribe_events_tickets_metabox_edit_ajax_advanced` filter. [ETP-111]
222
- * Tweak - Update the plugin screenshots on the WordPress.org page. [ET-1143]
223
- * Fix - Fixed the ticket block allowing to add more tickets than available when using shared capacity. [ET-1137]
224
- * Fix - Sync WooCommerce decimal separator with in Ticket edit form. [ETP-725]
225
- * Fix - Prevent Tribe Commerce "Confirmation email sender name" from displaying improperly when a single quote is added. [ET-1134]
226
- * Language - 115 new strings added, 118 updated, 0 fuzzied, and 0 obsoleted
227
-
228
- = [5.1.5] 2021-06-09 =
229
-
230
- * Fix - Fixed shared capacity stock sync after attendee deletion, for TribeCommerce tickets. [ETP-285]
231
- * Fix - Fix the price number calculation for tickets that are using no decimals and thousand separator. [ET-1114]
232
- * Fix - Revert to not hiding past sale tickets from Cost range in Events [ET-1133]
233
- * Fix - Resolved issue where events with tickets were being shown as Free on the day of the event. [ET-1133]
234
- * Tweak - When using The Events Calendar and Event Tickets split the admin footer rating link 50/50. [ET-1120]
235
- * Tweak - Move complete list of changelog entries from `readme.txt` to `changelog.txt`. [ET-1121]
236
- * Language - 0 new strings added, 24 updated, 0 fuzzied, and 0 obsoleted
237
-
238
- = [5.1.4] 2021-05-12 =
239
-
240
- * Fix - Show total Attendance count for Attendee List Block view. [ET-791]
241
- * Fix - Add label to the quantity input in the RSVP & Tickets forms to improve accessibility. [ET-767]
242
- * Fix - Fix a JavaScript localization error that was breaking the manual attendees functionality. [ETP-719]
243
- * Tweak - Update the footer calculations on the tickets block to only visible items so it can be used from the Attendee Registration Modal cart. [ETP-715]
244
- * Tweak - Adjust dimensions of tickets table for the classic editor UI. [ETP-594]
245
- * Tweak - Adjust the width of the Check-In column in the attendees report to make it work properly in different languages. [ET-768]
246
- * Tweak - Added filters: `tribe_tickets_admin_manager_request`, `event_tickets_should_enqueue_admin_settings_assets`, `tribe_tickets_assets_should_enqueue_tickets_loader`, `tribe_tickets_attendee_repository_update_attendee_data_args_before_update`, `tribe_tickets_attendee_repository_set_attendee_args`, `tribe_tickets_attendee_repository_set_attendee_args_`, `tribe_tickets_attendee_repository_save_extra_attendee_data_args`, `tribe_tickets_attendee_repository_save_extra_attendee_data_args_`, `tribe_tickets_attendee_repository_create_order_for_attendee_order_args`, `tribe_tickets_attendees_csv_export_delimiter`, `tribe_tickets_repositories_order_statuses`, `tribe_tickets_repositories_order_public_statuses`, `tribe_tickets_repositories_order_private_statuses`, `tribe_tickets_repositories_order_create_order_for_ticket_order_args`, `tribe_tickets_ticket_object_is_ticket_cache_enabled`, `tribe_tickets_attendee_activity_log_data`, `event_tickets_exclude_past_tickets_from_cost_range`, `tribe_tickets_attendee_lookup_user_from_email`, `tribe_tickets_attendee_create_user_from_email`, `tribe_tickets_attendee_create_user_from_email_send_new_user_info`, `tribe_tickets_handler_email_max_resend_limit`, `tribe_tickets_repositories_order_map`, `tribe_tickets_block_ticket_html_attributes`
247
- * Tweak - Removed filters: `tribe_tickets_rsvp_create_attendee_lookup_user_from_email`
248
- * Language - 1 new strings added, 27 updated, 1 fuzzied, and 0 obsoleted
249
-
250
- = [5.1.3] 2021-04-22 =
251
-
252
- * Fix - Add TwentyTwentyOne theme compatibility for Tickets and RSVPs. [ET-1047]
253
- * Fix - Added translation support for "Going" and "Not going" status labels. [ET-1056]
254
- * Fix - Disabled check-in for RSVP with "Not Going" status. [ET-984]
255
- * Fix - Fixed an issue with Tickets and RSVP blocks where long descriptions were breaking the block. They now use an auto-resizing textarea. [ET-1078]
256
- * Tweak - Introduce a new "Attendees" link to the WP Admin bar which can take you directly to the Attendees Report page. [ET-1079]
257
- * Tweak - Added the new `tribe_tickets_attendees_csv_export_delimiter` filter to allow changing the delimiter used when generating a CSV export of attendees. [ET-1055]
258
- * Tweak - Adjusted some template override folder paths documented in some of our Tickets-related templates. [ET-1051]
259
- * Language - 2 new strings added, 70 updated, 0 fuzzied, and 1 obsoleted
260
-
261
  [See changelog for all versions](https://raw.githubusercontent.com/the-events-calendar/event-tickets/master/changelog.txt)
2
 
3
  Contributors: theeventscalendar, brianjessee, camwynsp, paulkim, aguseo, bordoni, borkweb, GeoffBel, geoffgraham, jentheo, leahkoerper, lucatume, neillmcshea, vicskf, zbtirrell, juanfra
4
  Tags: tickets, registration, The Events Calendar, RSVP, ticket sales, attendee management
5
+ Requires at least: 5.6
6
  Tested up to: 5.8.1
7
+ Stable tag: 5.2.0
8
+ Requires PHP: 7.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
116
 
117
  1. RSVP on event.
118
  2. Front-end ticket in page.
119
+ 3. Tickets Commerce PayPal checkout.
120
  4. Attendee report.
121
  5. Emailed ticket.
122
  6. Tickets settings.
123
  7. Add new ticket.
124
+ 8. Tickets Commerce settings.
125
 
126
  == Frequently Asked Questions ==
127
 
171
 
172
  = I have a feature idea. What's the best way to tell you about it? =
173
 
174
+ We've got a [LoopedIn](https://app.loopedin.io/the-events-calendar-suite-roadmap#/ideas) page where we're actively watching for feature ideas from the community. Vote up existing feature requests or add your own, and help us shape the future of the products business in a way that best meets the community's needs.
175
 
176
  = I've still got questions. Where can I find answers? =
177
 
179
 
180
  == Changelog ==
181
 
182
+ = [5.2.0] 2021-11-04 =
183
+
184
+ * Feature - Introduction of Tickets Commerce, the new and improved solution you can set up to sell tickets with Event Tickets.
185
+ * Language - 840 new strings added, 432 updated, 26 fuzzied, and 16 obsoleted
186
+
187
  = [5.1.10] 2021-09-27 =
188
 
189
  * Enhancement - When editing an RSVP or ticket in the block editor, allow title to wrap to multiple lines. [ET-1089]
207
  * Fix - Updated deprecated hook `block_categories` to use `block_categories_all`. [ET-1156]
208
  * Language - 37 new strings added, 162 updated, 6 fuzzied, and 20 obsoleted
209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  [See changelog for all versions](https://raw.githubusercontent.com/the-events-calendar/event-tickets/master/changelog.txt)
src/Tickets/Assets.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Handles registering and setup for assets on Tickets.
4
  *
5
- * @since 5.1.6
6
  *
7
  * @package TEC\Tickets
8
  */
@@ -14,7 +14,7 @@ use \tad_DI52_ServiceProvider;
14
  /**
15
  * Class Assets.
16
  *
17
- * @since 5.1.6
18
  *
19
  * @package TEC\Tickets
20
  */
@@ -26,7 +26,25 @@ class Assets extends tad_DI52_ServiceProvider {
26
  * @since 5.1.6
27
  */
28
  public function register() {
 
29
 
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- }
 
2
  /**
3
  * Handles registering and setup for assets on Tickets.
4
  *
5
+ * @since 5.1.6
6
  *
7
  * @package TEC\Tickets
8
  */
14
  /**
15
  * Class Assets.
16
  *
17
+ * @since 5.1.6
18
  *
19
  * @package TEC\Tickets
20
  */
26
  * @since 5.1.6
27
  */
28
  public function register() {
29
+ $plugin = tribe( 'tickets.main' );
30
 
31
+ tribe_asset(
32
+ $plugin,
33
+ 'tribe-tickets-provider',
34
+ 'tickets-provider.js',
35
+ [
36
+ 'tribe-common',
37
+ ],
38
+ null,
39
+ [
40
+ 'localize' => [
41
+ 'name' => 'tecTicketsSettings',
42
+ 'data' => [
43
+ 'debug' => defined( 'WP_DEBUG' ) && WP_DEBUG
44
+ ],
45
+ ],
46
+ ]
47
+ );
48
 
49
+ }
50
+ }
src/Tickets/Commerce/Admin/Notices.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Admin;
4
+
5
+ use \tad_DI52_ServiceProvider;
6
+ use TEC\Tickets\Commerce\Checkout;
7
+ use TEC\Tickets\Commerce\Success;
8
+ use \Tribe__Settings;
9
+
10
+ /**
11
+ * Class Notices
12
+ *
13
+ * @since 5.2.0
14
+ *
15
+ * @package TEC\Tickets\Commerce\Admin
16
+ */
17
+ class Notices extends tad_DI52_ServiceProvider {
18
+
19
+ /**
20
+ * @inheritdoc
21
+ */
22
+ public function register() {
23
+
24
+ tribe_notice(
25
+ 'event-tickets-tickets-commerce-checkout-not-set',
26
+ [ $this, 'render_checkout_notice' ],
27
+ [ 'dismiss' => false, 'type' => 'error' ],
28
+ [ $this, 'should_render_checkout_notice' ]
29
+ );
30
+
31
+ tribe_notice(
32
+ 'event-tickets-tickets-commerce-success-not-set',
33
+ [ $this, 'render_success_notice' ],
34
+ [ 'dismiss' => false, 'type' => 'error' ],
35
+ [ $this, 'should_render_success_notice' ]
36
+ );
37
+ }
38
+
39
+ /**
40
+ * Display a notice when Tickets Commerce is enabled, yet a checkout page is not setup properly.
41
+ *
42
+ * @since 5.2.0
43
+ *
44
+ * @return bool
45
+ */
46
+ public function should_render_checkout_notice() {
47
+ // If we're not on our own settings page, bail.
48
+ if ( Tribe__Settings::$parent_slug !== tribe_get_request_var( 'page' ) ) {
49
+ return false;
50
+ }
51
+
52
+ if ( tribe( Checkout::class )->page_has_shortcode() ) {
53
+ return false;
54
+ }
55
+
56
+ return true;
57
+ }
58
+
59
+ /**
60
+ * Gets the HTML for the notice that is shown when checkout setting is not set.
61
+ *
62
+ * @since 5.2.0
63
+ *
64
+ * @return string Notice HTML.
65
+ */
66
+ public function render_checkout_notice() {
67
+ $notice_link = sprintf(
68
+ '<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>',
69
+ esc_url( 'https://evnt.is/1axv' ),
70
+ esc_html__( 'Learn More', 'event-tickets' )
71
+ );
72
+ $notice_header = esc_html__( 'Set up your checkout page', 'event-tickets' );
73
+ $notice_text = sprintf(
74
+ // translators: %1$s: Link to knowledgebase article.
75
+ esc_html__( 'In order to start selling with Tickets Commerce, you\'ll need to set up your checkout page. Please configure the setting on Settings > Payments and confirm that the page you have selected has the proper shortcode. %1$s', 'event-tickets' ),
76
+ $notice_link
77
+ );
78
+
79
+ return sprintf(
80
+ '<p><strong>%1$s</strong></p><p>%2$s</p>',
81
+ $notice_header,
82
+ $notice_text
83
+ );
84
+ }
85
+
86
+ /**
87
+ * Display a notice when Tickets Commerce is enabled, yet a success page is not setup properly.
88
+ *
89
+ * @since 5.2.0
90
+ */
91
+ public function should_render_success_notice() {
92
+ // If we're not on our own settings page, bail.
93
+ if ( Tribe__Settings::$parent_slug !== tribe_get_request_var( 'page' ) ) {
94
+ return false;
95
+ }
96
+
97
+ if ( tribe( Success::class )->page_has_shortcode() ) {
98
+ return false;
99
+ }
100
+
101
+ return true;
102
+ }
103
+
104
+ /**
105
+ * Gets the HTML for the notice that is shown when checkout setting is not set.
106
+ *
107
+ * @since 5.2.0
108
+ *
109
+ * @return string Notice HTML.
110
+ */
111
+ public function render_success_notice() {
112
+ $notice_link = sprintf(
113
+ '<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>',
114
+ esc_url( 'https://evnt.is/1axv' ),
115
+ esc_html__( 'Learn More', 'event-tickets' )
116
+ );
117
+ $notice_header = esc_html__( 'Set up your order success page', 'event-tickets' );
118
+ $notice_text = sprintf(
119
+ // translators: %1$s: Link to knowledgebase article.
120
+ esc_html__( 'In order to start selling with Tickets Commerce, you\'ll need to set up your order success page. Please configure the setting on Settings > Payments and confirm that the page you have selected has the proper shortcode. %1$s', 'event-tickets' ),
121
+ $notice_link
122
+ );
123
+
124
+ return sprintf(
125
+ '<p><strong>%1$s</strong></p><p>%2$s</p>',
126
+ $notice_header,
127
+ $notice_text
128
+ );
129
+ }
130
+ }
src/Tickets/Commerce/Admin_Tables/Attendees.php ADDED
@@ -0,0 +1,660 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Attendees Table
4
+ *
5
+ * @package TEC\Tickets
6
+ */
7
+
8
+ namespace TEC\Tickets\Commerce\Admin_Tables;
9
+
10
+ if ( ! class_exists( 'WP_List_Table' ) ) {
11
+ require_once ABSPATH . 'wp-admin/includes/screen.php';
12
+ require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
13
+ }
14
+
15
+ use TEC\Tickets\Commerce\Attendee;
16
+ use TEC\Tickets\Commerce\Order;
17
+ use TEC\Tickets\Commerce\Ticket;
18
+ use WP_List_Table;
19
+
20
+ /**
21
+ * Class Admin Tables for Attendees
22
+ *
23
+ * @since 5.2.0
24
+ */
25
+ class Attendees extends WP_List_Table {
26
+
27
+ /**
28
+ * Legacy Attendees Table Controller
29
+ *
30
+ * @var \Tribe__Tickets__Attendees_Table
31
+ */
32
+ private $legacy_attendees_table;
33
+
34
+ /**
35
+ * The name attribute of the search box input
36
+ *
37
+ * @var string
38
+ */
39
+ private $search_box_input_name = 's';
40
+
41
+ /**
42
+ * Documented in WP_List_Table
43
+ *
44
+ * @since 5.2.0
45
+ *
46
+ * @param array|string $args Array or string of arguments.
47
+ */
48
+ public function __construct( $args = [] ) {
49
+ $this->legacy_attendees_table = new \Tribe__Tickets__Attendees_Table();
50
+
51
+ /**
52
+ * This class' parent defaults to 's', but we want to change that on the front-end (e.g. Community) to avoid
53
+ * the possibility of triggering the theme's Search template.
54
+ */
55
+ if ( ! is_admin() ) {
56
+ $this->search_box_input_name = 'search';
57
+ }
58
+
59
+ $screen = get_current_screen();
60
+
61
+ $args = wp_parse_args(
62
+ $args,
63
+ [
64
+ 'singular' => 'attendee',
65
+ 'plural' => 'attendees',
66
+ 'ajax' => true,
67
+ 'screen' => $screen,
68
+ ]
69
+ );
70
+
71
+ $this->per_page_option = \Tribe__Tickets__Admin__Screen_Options__Attendees::$per_page_user_option;
72
+
73
+ if ( ! is_null( $screen ) ) {
74
+ $screen->add_option(
75
+ 'per_page',
76
+ [
77
+ 'label' => __( 'Number of attendees per page:', 'event-tickets' ),
78
+ 'option' => $this->per_page_option,
79
+ ]
80
+ );
81
+ }
82
+
83
+ // Fetch the event Object.
84
+ if ( ! empty( $_GET['event_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
85
+ $this->event = get_post( absint( $_GET['event_id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
86
+ }
87
+
88
+ parent::__construct( apply_filters( 'tribe_events_tickets_attendees_table_args', $args ) );
89
+ }
90
+
91
+ /**
92
+ * Enqueues the JS and CSS for the attendees page in the admin
93
+ *
94
+ * @since 5.2.0
95
+ *
96
+ * @param string $hook The current admin page.
97
+ */
98
+ public function enqueue_assets( $hook ) {
99
+ /**
100
+ * Filter the Page Slugs the Attendees Page CSS and JS Loads
101
+ *
102
+ * @param array array( $this->page_id ) an array of admin slugs
103
+ */
104
+ if ( ! in_array( $hook, apply_filters( 'tribe_filter_attendee_page_slug', [ $this->page_id ] ) ) ) {
105
+ return;
106
+ }
107
+
108
+ $tickets_main = tribe( 'tickets.main' );
109
+
110
+ tribe_asset(
111
+ $tickets_main,
112
+ 'tickets-report-css',
113
+ 'tickets-report.css',
114
+ [],
115
+ null,
116
+ []
117
+ );
118
+
119
+ tribe_asset(
120
+ $tickets_main,
121
+ 'tickets-report-print-css',
122
+ 'tickets-report-print.css',
123
+ [],
124
+ null,
125
+ [
126
+ 'media' => 'print',
127
+ ]
128
+ );
129
+
130
+ tribe_asset(
131
+ $tickets_main,
132
+ 'tickets-commerce-report-attendees',
133
+ 'tickets-attendees.js',
134
+ [ 'jquery' ],
135
+ null,
136
+ []
137
+ );
138
+
139
+ tribe_asset_enqueue( 'tickets-report-css' );
140
+ tribe_asset_enqueue( 'tickets-report-print-css' );
141
+ tribe_asset_enqueue( 'tickets-commerce-report-attendees' );
142
+
143
+ add_thickbox();
144
+
145
+ $move_url_args = [
146
+ 'dialog' => \Tribe__Tickets__Main::instance()->move_tickets()->dialog_name(),
147
+ 'check' => wp_create_nonce( 'move_tickets' ),
148
+ 'TB_iframe' => 'true',
149
+ ];
150
+
151
+ $config_data = [
152
+ 'nonce' => wp_create_nonce( 'email-attendee-list' ),
153
+ 'required' => esc_html__( 'You need to select a user or type a valid email address', 'event-tickets' ),
154
+ 'sending' => esc_html__( 'Sending...', 'event-tickets' ),
155
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
156
+ 'checkin_nonce' => wp_create_nonce( 'checkin' ),
157
+ 'uncheckin_nonce' => wp_create_nonce( 'uncheckin' ),
158
+ 'cannot_move' => esc_html__( 'You must first select one or more tickets before you can move them!', 'event-tickets' ),
159
+ 'move_url' => add_query_arg( $move_url_args ),
160
+ 'confirmation' => esc_html__( 'Please confirm that you would like to delete this attendee.', 'event-tickets' ),
161
+ 'bulk_confirmation' => esc_html__( 'Please confirm you would like to delete these attendees.', 'event-tickets' ),
162
+ ];
163
+
164
+ /**
165
+ * Allow filtering the configuration data for the Attendee objects on Attendees report page.
166
+ *
167
+ * @since 5.2.0
168
+ *
169
+ * @param array $config_data List of configuration data to be localized.
170
+ */
171
+ $config_data = apply_filters( 'tribe_tickets_attendees_report_js_config', $config_data );
172
+
173
+ wp_localize_script( $this->slug() . '-js', 'Attendees', $config_data );
174
+ }
175
+
176
+ /**
177
+ * Loads the WP-Pointer for the Attendees screen
178
+ *
179
+ * @since 5.2.0
180
+ *
181
+ * @param string $hook The current admin page.
182
+ */
183
+ public function load_pointers( $hook ) {
184
+
185
+ $dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
186
+ $pointer = [];
187
+
188
+ if ( version_compare( get_bloginfo( 'version' ), '3.3', '>' ) && ! in_array( 'attendees_filters', $dismissed ) ) {
189
+ $pointer = [
190
+ 'pointer_id' => 'attendees_filters',
191
+ 'target' => '#screen-options-link-wrap',
192
+ 'options' => [
193
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Columns', 'event-tickets' ), esc_html__( 'You can use Screen Options to select which columns you want to see. The selection works in the table below, in the email, for print and for the CSV export.', 'event-tickets' ) ),
194
+ 'position' => [
195
+ 'edge' => 'top',
196
+ 'align' => 'right',
197
+ ],
198
+ ],
199
+ ];
200
+ wp_enqueue_script( 'wp-pointer' );
201
+ wp_enqueue_style( 'wp-pointer' );
202
+ }
203
+
204
+ wp_localize_script( $this->slug() . '-js', 'AttendeesPointer', $pointer );
205
+ }
206
+
207
+ /**
208
+ * Returns the list of columns.
209
+ *
210
+ * @since 5.2.0
211
+ * @return array An associative array in the format [ <slug> => <title> ]
212
+ */
213
+ public function get_columns() {
214
+ $columns = [
215
+ 'cb' => __( 'Checkbox', 'event-tickets' ),
216
+ 'ticket' => __( 'Ticket', 'event-tickets' ),
217
+ 'primary_info' => __( 'Primary Information', 'event-tickets' ),
218
+ 'meta_details' => __( 'Details', 'event-tickets' ),
219
+ 'security_code' => __( 'Security Code', 'event-tickets' ),
220
+ 'status' => __( 'Status', 'event-tickets' ),
221
+ 'check_in' => __( 'Check In', 'event-tickets' ),
222
+ ];
223
+
224
+ return $columns;
225
+ }
226
+
227
+ /**
228
+ * Prepares the list of items for displaying.
229
+ *
230
+ * @since 5.2.0
231
+ */
232
+ public function prepare_items() {
233
+ $this->legacy_attendees_table->process_actions();
234
+
235
+ $post_id = tribe_get_request_var( 'post_id', 0 );
236
+ $post_id = tribe_get_request_var( 'event_id', $post_id );
237
+
238
+ $this->post_id = $post_id;
239
+
240
+ $search = tribe_get_request_var( $this->search_box_input_name );
241
+ $page = absint( tribe_get_request_var( 'paged', 0 ) );
242
+
243
+ $arguments = [
244
+ 'page' => $page,
245
+ 'posts_per_page' => $this->per_page_option,
246
+ 'return_total_found' => true,
247
+ ];
248
+
249
+ if ( ! empty( $search ) ) {
250
+ $arguments['search'] = $search;
251
+
252
+ $search_keys = array_keys( $this->get_search_options() );
253
+
254
+ /**
255
+ * Filters the item keys that can be used to filter attendees while searching them.
256
+ *
257
+ * @since 5.2.0
258
+ * @since 5.2.0
259
+ *
260
+ * @param array $search_keys The keys that can be used to search attendees.
261
+ * @param array $items (deprecated) The attendees list.
262
+ * @param string $search The current search string.
263
+ */
264
+ $search_keys = apply_filters( 'tribe_tickets_search_attendees_by', $search_keys, [], $search );
265
+
266
+ // Default selection.
267
+ $search_key = 'purchaser_name';
268
+
269
+ $search_type = sanitize_text_field( tribe_get_request_var( 'tribe_attendee_search_type' ) );
270
+
271
+ if (
272
+ $search_type
273
+ && in_array( $search_type, $search_keys, true )
274
+ ) {
275
+ $search_key = $search_type;
276
+ }
277
+
278
+ $search_like_keys = [
279
+ 'purchaser_name',
280
+ 'purchaser_email',
281
+ 'holder_name',
282
+ 'holder_email',
283
+ ];
284
+
285
+ /**
286
+ * Filters the item keys that support LIKE matching to filter attendees while searching them.
287
+ *
288
+ * @since 5.2.0
289
+ *
290
+ * @param array $search_like_keys The keys that support LIKE matching.
291
+ * @param array $search_keys The keys that can be used to search attendees.
292
+ * @param string $search The current search string.
293
+ */
294
+ $search_like_keys = apply_filters( 'tribe_tickets_search_attendees_by_like', $search_like_keys, $search_keys, $search );
295
+
296
+ // Update search key if it supports LIKE matching.
297
+ if ( in_array( $search_key, $search_like_keys, true ) ) {
298
+ $search_key .= '__like';
299
+ $search = '%' . $search . '%';
300
+ }
301
+
302
+ // Only get matches that have search phrase in the key.
303
+ $arguments['by'] = [
304
+ $search_key => [
305
+ $search,
306
+ ],
307
+ ];
308
+ }
309
+
310
+ if ( ! empty( $post_id ) ) {
311
+ $arguments['events'] = $post_id;
312
+ }
313
+
314
+ $item_data = \Tribe__Tickets__Tickets::get_event_attendees_by_args( $post_id, $arguments );
315
+
316
+ $this->items = array_map(
317
+ function ( $attendee ) {
318
+ $attendee = new \WP_Post( (object) $attendee );
319
+
320
+ return tribe( Attendee::class )->get_attendee( $attendee );
321
+ },
322
+ $item_data['attendees']
323
+ );
324
+
325
+ // $this->items = $item_data['attendees'];
326
+
327
+ $pagination_args = [
328
+ 'total_items' => count( $this->items ),
329
+ 'per_page' => $this->per_page_option,
330
+ ];
331
+
332
+ if ( ! empty( $this->items ) ) {
333
+ $pagination_args['total_items'] = count( $this->items );
334
+ }
335
+
336
+ $this->set_pagination_args( $pagination_args );
337
+ }
338
+
339
+ /**
340
+ * Get the allowed search types and their descriptions.
341
+ *
342
+ * @see \Tribe__Tickets__Attendee_Repository::__construct() List of valid ORM args.
343
+ *
344
+ * @since 5.2.0
345
+ *
346
+ * @return array
347
+ */
348
+ private function get_search_options() {
349
+ return [
350
+ 'purchaser_name' => esc_html_x( 'Search by Purchaser Name', 'Attendees Table search options', 'event-tickets' ),
351
+ 'purchaser_email' => esc_html_x( 'Search by Purchaser Email', 'Attendees Table search options', 'event-tickets' ),
352
+ 'holder_name' => esc_html_x( 'Search by Ticket Holder Name', 'Attendees Table search options', 'event-tickets' ),
353
+ 'holder_email' => esc_html_x( 'Search by Ticket Holder Email', 'Attendees Table search options', 'event-tickets' ),
354
+ 'user' => esc_html_x( 'Search by User ID', 'Attendees Table search options', 'event-tickets' ),
355
+ 'order_status' => esc_html_x( 'Search by Order Status', 'Attendees Table search options', 'event-tickets' ),
356
+ 'order' => esc_html_x( 'Search by Order ID', 'Attendees Table search options', 'event-tickets' ),
357
+ 'security_code' => esc_html_x( 'Search by Security Code', 'Attendees Table search options', 'event-tickets' ),
358
+ 'ID' => esc_html( sprintf( _x( 'Search by %s ID', 'Attendees Table search options', 'event-tickets' ), tribe_get_ticket_label_singular( 'attendees_table_search_box_ticket_id' ) ) ),
359
+ 'product_id' => esc_html_x( 'Search by Product ID', 'Attendees Table search options', 'event-tickets' ),
360
+ ];
361
+ }
362
+
363
+ /**
364
+ * Generates content for a single row of the table
365
+ *
366
+ * @since 5.2.0
367
+ *
368
+ * @param \WP_Post $item row object.
369
+ */
370
+ public function single_row( $item ) {
371
+ $checked = '';
372
+ if ( 1 === (int) $item->check_in ) {
373
+ $checked = ' tickets_checked ';
374
+ }
375
+
376
+ $status = 'complete';
377
+ if ( ! empty( $item->order_status ) ) {
378
+ $status = $item->order_status;
379
+ }
380
+
381
+ echo '<tr class="' . esc_attr( $checked . $status ) . '">';
382
+ $this->single_row_columns( $item );
383
+ echo '</tr>';
384
+
385
+ /**
386
+ * Hook to allow for the insertion of data after an attendee table row.
387
+ *
388
+ * @var $item array of an Attendee's data
389
+ */
390
+ do_action( 'event_tickets_attendees_table_after_row', (array) $item );
391
+ }
392
+
393
+ /**
394
+ * Handler for the columns that don't have a specific column_{name} handler function.
395
+ *
396
+ * @param \WP_Post $item row object.
397
+ * @param string $column the column name.
398
+ *
399
+ * @return string
400
+ */
401
+ public function column_default( $item, $column ) {
402
+ $value = empty( $item->{$column} ) ? '' : $item->{$column};
403
+
404
+ return apply_filters( 'tribe_events_tickets_attendees_table_column', $value, (array) $item, $column );
405
+ }
406
+
407
+ /**
408
+ * Content for the ticket column
409
+ *
410
+ * @since 5.2.0
411
+ *
412
+ * @param \WP_Post $item row object.
413
+ *
414
+ * @return string
415
+ */
416
+ public function column_ticket( $item ) {
417
+ $unique_id = tribe( Attendee::class )->get_unique_id( $item );
418
+ $ticket = get_post( tribe( Attendee::class )->get_ticket_id( $item ) );
419
+ $dash = '';
420
+ $title = $ticket->post_title;
421
+ $attendee_id = ! empty( $item->attendee_id ) ? $item->attendee_id : $item->ID;
422
+
423
+ if ( ! empty( $title ) ) {
424
+ $dash = ' &ndash; ';
425
+ }
426
+
427
+ $output[] = sprintf(
428
+ '<div class="event-tickets-ticket-name">%1$s [#%2$d]%3$s %4$s</div>',
429
+ esc_html( $unique_id ),
430
+ (int) $attendee_id,
431
+ esc_html( $dash ),
432
+ esc_html( $title )
433
+ );
434
+
435
+ $output[] = $this->get_row_actions( $item );
436
+
437
+ /**
438
+ * Hook to allow for the insertion of additional content in the ticket table cell
439
+ *
440
+ * @param \WP_Post $item row object.
441
+ */
442
+ do_action( 'event_tickets_attendees_table_ticket_column', $item );
443
+
444
+ return implode( '', $output );
445
+ }
446
+
447
+ /**
448
+ * Content for the primary info column
449
+ *
450
+ * @since 5.2.0
451
+ *
452
+ * @param \WP_Post $item row object.
453
+ *
454
+ * @return string
455
+ */
456
+ public function column_primary_info( $item ) {
457
+
458
+ $name = $item->holder_name ? $item->holder_name : '';
459
+ $email = $item->holder_email ? $item->holder_email : '';
460
+
461
+ return sprintf(
462
+ '
463
+ <div class="purchaser_name">%1$s</div>
464
+ <div class="purchaser_email">%2$s</div>
465
+ ',
466
+ esc_html( $name ),
467
+ esc_html( $email )
468
+ );
469
+ }
470
+
471
+ /**
472
+ * Content for the security code column
473
+ *
474
+ * @since 5.2.0
475
+ *
476
+ * @param \WP_Post $item row object.
477
+ *
478
+ * @return string
479
+ */
480
+ public function column_security_code( $item ) {
481
+ $security_code = tribe( Attendee::class )->get_security_code( $item );
482
+
483
+ return esc_html( $security_code );
484
+ }
485
+
486
+ /**
487
+ * Content for the status column
488
+ *
489
+ * @since 5.2.0
490
+ *
491
+ * @param \WP_Post $item row object.
492
+ *
493
+ * @return string
494
+ */
495
+ public function column_status( $item ) {
496
+ if ( $item->is_legacy_attendee ) {
497
+ return $this->legacy_attendees_table->column_status( (array) $item );
498
+ }
499
+
500
+ return tribe( Attendee::class )->get_status_label( $item );
501
+ }
502
+
503
+ /**
504
+ * Content for the check in column
505
+ *
506
+ * @since 5.2.0
507
+ *
508
+ * @param \WP_Post $item row object.
509
+ *
510
+ * @return false|string
511
+ */
512
+ public function column_check_in( $item ) {
513
+ return $this->legacy_attendees_table->column_check_in( (array) $item );
514
+ }
515
+
516
+ /**
517
+ * Content for the checkbox column
518
+ *
519
+ * @since 5.2.0
520
+ *
521
+ * @param \WP_Post $item row object.
522
+ *
523
+ * @return string
524
+ */
525
+ public function column_cb( $item ) {
526
+ $provider = ! empty( $item->provider ) ? $item->provider : null;
527
+
528
+ return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', esc_attr( $this->_args['singular'] ), esc_attr( $item->attendee_id . '|' . $provider ) );
529
+ }
530
+
531
+ /**
532
+ * Adds a set of default row actions to each item in the attendee list table.
533
+ *
534
+ * @since 5.2.0
535
+ *
536
+ * @param \WP_Post $item row object.
537
+ *
538
+ * @return string
539
+ */
540
+ public function get_row_actions( $item ) {
541
+ /** @var Tribe__Tickets__Attendees $attendees */
542
+ $attendees = tribe( 'tickets.attendees' );
543
+
544
+ if ( ! $attendees->user_can_manage_attendees( 0, $this->event_id ) ) {
545
+ return '';
546
+ }
547
+
548
+ $default_actions = [];
549
+ $provider = ! empty( $item->provider ) ? $item->provider : null;
550
+ $not_going = empty( $item->order_status ) || 'no' === $item->order_status || 'cancelled' === $item->order_status || 'refunded' === $item->order_status;
551
+
552
+ if ( ! $not_going ) {
553
+ $default_actions[] = sprintf(
554
+ '<span class="inline">
555
+ <a href="#" class="tickets_checkin" data-attendee-id="%1$d" data-event-id="%2$d" data-provider="%3$s">' . esc_html_x( 'Check In', 'row action', 'event-tickets' ) . '</a>
556
+ <a href="#" class="tickets_uncheckin" data-attendee-id="%1$d" data-event-id="%2$d" data-provider="%3$s">' . esc_html_x( 'Undo Check In', 'row action', 'event-tickets' ) . '</a>
557
+ </span>',
558
+ esc_attr( $item->attendee_id ),
559
+ esc_attr( $this->event_id ),
560
+ esc_attr( $provider )
561
+ );
562
+ }
563
+
564
+ if ( is_admin() ) {
565
+ $default_actions[] = '<span class="inline move-ticket"> <a href="#">' . esc_html_x( 'Move', 'row action', 'event-tickets' ) . '</a> </span>';
566
+ }
567
+
568
+ $attendee = esc_attr( $item->attendee_id . '|' . $provider );
569
+ $nonce = wp_create_nonce( 'do_item_action_' . $attendee );
570
+
571
+ $delete_url = esc_url(
572
+ add_query_arg(
573
+ [
574
+ 'action' => 'delete_attendee',
575
+ 'nonce' => $nonce,
576
+ 'attendee' => $attendee,
577
+ ]
578
+ )
579
+ );
580
+
581
+ $default_actions[] = '<span class="trash"><a href="' . $delete_url . '">' . esc_html_x( 'Delete', 'row action', 'event-tickets' ) . '</a></span>';
582
+
583
+ $default_actions = apply_filters( 'event_tickets_attendees_table_row_actions', $default_actions, (array) $item );
584
+
585
+ $row_actions = implode( ' | ', $default_actions );
586
+
587
+ return empty( $row_actions ) ? '' : '<div class="row-actions">' . $row_actions . '</div>';
588
+ }
589
+
590
+ /**
591
+ * Displays the search box.
592
+ *
593
+ * @since 5.2.0
594
+ *
595
+ * @param string $text The 'submit' button label.
596
+ * @param string $input_id ID attribute value for the search input field.
597
+ */
598
+ public function search_box( $text, $input_id ) {
599
+ return $this->legacy_attendees_table->search_box( $text, $input_id );
600
+ }
601
+
602
+ /**
603
+ * Retrieves the list of bulk actions available for this table.
604
+ *
605
+ * @since 5.2.0
606
+ *
607
+ * @return array
608
+ */
609
+ public function get_bulk_actions() {
610
+ return $this->legacy_attendees_table->get_bulk_actions();
611
+ }
612
+
613
+ /**
614
+ * Extra controls to be displayed between bulk actions and pagination.
615
+ *
616
+ * @since 5.2.0
617
+ *
618
+ * @param string $which the control name.
619
+ */
620
+ public function extra_tablenav( $which ) {
621
+ return $this->legacy_attendees_table->extra_tablenav( $which );
622
+ }
623
+
624
+ /**
625
+ * Message to be displayed when there are no items
626
+ *
627
+ * @since 5.2.0
628
+ */
629
+ public function no_items() {
630
+ esc_html_e( 'No matching attendees found.', 'event-tickets' );
631
+ }
632
+
633
+ /**
634
+ * Overrides the list of CSS classes for the WP_List_Table table tag.
635
+ * This function is not hookable in core, so it needs to be overridden!
636
+ *
637
+ * @since 5.2.0
638
+ *
639
+ * @return array List of CSS classes for the table tag.
640
+ */
641
+ protected function get_table_classes() {
642
+ $classes = [ 'widefat', 'striped', 'attendees', 'tribe-attendees' ];
643
+
644
+ if ( is_admin() ) {
645
+ $classes[] = 'fixed';
646
+ }
647
+
648
+ /**
649
+ * Filters the default classes added to the attendees report `WP_List_Table`.
650
+ *
651
+ * @since 4.10.7
652
+ *
653
+ * @param array $classes The array of classes to be applied.
654
+ */
655
+ $classes = apply_filters( 'tribe_tickets_attendees_table_classes', $classes );
656
+
657
+ return $classes;
658
+ }
659
+
660
+ }
src/Tickets/Commerce/Admin_Tables/Orders.php ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Admin_Tables;
4
+
5
+ use TEC\Tickets\Commerce\Gateways\Manager;
6
+ use TEC\Tickets\Commerce\Status\Completed;
7
+ use TEC\Tickets\Commerce\Status\Refunded;
8
+ use TEC\Tickets\Commerce\Status\Status_Handler;
9
+ use \Tribe__Utils__Array as Arr;
10
+
11
+ use \WP_List_Table;
12
+ use \WP_Post;
13
+
14
+ if ( ! class_exists( 'WP_List_Table' ) ) {
15
+ require_once( ABSPATH . 'wp-admin/includes/screen.php' );
16
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
17
+ }
18
+
19
+ /**
20
+ * Class Admin Tables for Orders.
21
+ *
22
+ * @since 5.2.0
23
+ *
24
+ */
25
+ class Orders extends WP_List_Table {
26
+
27
+ /**
28
+ * The user option that will be used to store the number of orders per page to show.
29
+ *
30
+ * @var string
31
+ */
32
+ public $per_page_option = 20;
33
+
34
+ /**
35
+ * The current post ID
36
+ *
37
+ * @var int
38
+ */
39
+ public $post_id;
40
+
41
+ /**
42
+ * Orders Table constructor.
43
+ *
44
+ * @since 5.2.0
45
+ */
46
+ public function __construct() {
47
+ $args = [
48
+ 'singular' => 'order',
49
+ 'plural' => 'orders',
50
+ 'ajax' => true,
51
+ ];
52
+
53
+ parent::__construct( $args );
54
+ }
55
+
56
+ /**
57
+ * Overrides the list of CSS classes for the WP_List_Table table tag.
58
+ * This function is not hookable in core, so it needs to be overridden!
59
+ *
60
+ * @since 5.2.0
61
+ *
62
+ * @return array List of CSS classes for the table tag.
63
+ */
64
+ protected function get_table_classes() {
65
+ $classes = [ 'widefat', 'striped', 'tribe-tickets-commerce-report-orders' ];
66
+
67
+ if ( is_admin() ) {
68
+ $classes[] = 'fixed';
69
+ }
70
+
71
+ /**
72
+ * Filters the default classes added to the Tickets Commerce order report `WP_List_Table`.
73
+ *
74
+ * @since 5.2.0
75
+ *
76
+ * @param array $classes The array of classes to be applied.
77
+ */
78
+ return apply_filters( 'tec_tickets_commerce_reports_orders_table_classes', $classes );
79
+ }
80
+
81
+ /**
82
+ * Checks the current user's permissions
83
+ *
84
+ * @since 5.2.0
85
+ */
86
+ public function ajax_user_can() {
87
+ $post_type = get_post_type_object( $this->screen->post_type );
88
+
89
+ return ! empty( $post_type->cap->edit_posts ) && current_user_can( $post_type->cap->edit_posts );
90
+ }
91
+
92
+ /**
93
+ * Returns the list of columns.
94
+ *
95
+ * @since 5.2.0
96
+ *
97
+ * @return array An associative array in the format [ <slug> => <title> ]
98
+ */
99
+ public function get_columns() {
100
+ $columns = [
101
+ 'order' => __( 'Order', 'event-tickets' ),
102
+ 'purchaser' => __( 'Purchaser', 'event-tickets' ),
103
+ 'email' => __( 'Email', 'event-tickets' ),
104
+ 'purchased' => __( 'Purchased', 'event-tickets' ),
105
+ 'date' => __( 'Date', 'event-tickets' ),
106
+ 'gateway' => __( 'Gateway', 'event-tickets' ),
107
+ 'gateway_order_id' => __( 'Gateway ID', 'event-tickets' ),
108
+ 'status' => __( 'Status', 'event-tickets' ),
109
+ 'total' => __( 'Total', 'event-tickets' ),
110
+ ];
111
+
112
+ return $columns;
113
+ }
114
+
115
+ /**
116
+ * Generates content for a single row of the table
117
+ *
118
+ * @since 5.2.0
119
+ *
120
+ * @param WP_Post $item The current item
121
+ */
122
+ public function single_row( $item ) {
123
+ echo '<tr class="' . esc_attr( $item->post_status ) . '">';
124
+ $this->single_row_columns( $item );
125
+ echo '</tr>';
126
+ }
127
+
128
+ /**
129
+ * Prepares the list of items for displaying.
130
+ *
131
+ * @since 5.2.0
132
+ */
133
+ public function prepare_items() {
134
+ $post_id = tribe_get_request_var( 'post_id', 0 );
135
+ $post_id = tribe_get_request_var( 'event_id', $post_id );
136
+
137
+ $this->post_id = $post_id;
138
+ $product_ids = tribe_get_request_var( 'product_ids' );
139
+ $product_ids = ! empty( $product_ids ) ? explode( ',', $product_ids ) : null;
140
+
141
+ $search = tribe_get_request_var( 's' );
142
+ $page = absint( tribe_get_request_var( 'paged', 0 ) );
143
+ $arguments = [
144
+ 'status' => 'any',
145
+ 'paged' => $page,
146
+ 'posts_per_page' => $this->per_page_option,
147
+ ];
148
+
149
+ if ( $search ) {
150
+ $arguments['search'] = $search;
151
+ }
152
+
153
+ if ( ! empty( $post_id ) ) {
154
+ $arguments['events'] = $post_id;
155
+ }
156
+ if ( ! empty( $product_ids ) ) {
157
+ $arguments['tickets'] = $product_ids;
158
+ }
159
+
160
+ $orders_repository = tec_tc_orders()->by_args( $arguments );
161
+
162
+ $total_items = $orders_repository->found();
163
+
164
+ $this->items = $orders_repository->all();
165
+
166
+ $this->set_pagination_args( [
167
+ 'total_items' => $total_items,
168
+ 'per_page' => $this->per_page_option,
169
+ ] );
170
+ }
171
+
172
+ /**
173
+ * Message to be displayed when there are no items
174
+ *
175
+ * @since 5.2.0
176
+ */
177
+ public function no_items() {
178
+ _e( 'No matching orders found.', 'event-tickets' );
179
+ }
180
+
181
+ /**
182
+ * Handler for the columns that don't have a specific column_{name} handler function.
183
+ *
184
+ * @since 5.2.0
185
+ *
186
+ * @param WP_Post $item
187
+ * @param $column
188
+ *
189
+ * @return string
190
+ */
191
+ public function column_default( $item, $column ) {
192
+ return empty( $item->$column ) ? '??' : $item->$column;
193
+ }
194
+
195
+ /**
196
+ * Returns the customer name.
197
+ *
198
+ * @since 5.2.0
199
+ *
200
+ * @param WP_Post $item The current item.
201
+ *
202
+ * @return string
203
+ */
204
+ public function column_purchaser( $item ) {
205
+ return esc_html( $item->purchaser['full_name'] );
206
+ }
207
+
208
+ /**
209
+ * Returns the customer email.
210
+ *
211
+ * @since 5.2.0
212
+ *
213
+ * @param WP_Post $item The current item.
214
+ *
215
+ * @return string
216
+ */
217
+ public function column_email( $item ) {
218
+ return esc_html( $item->purchaser['email'] );
219
+ }
220
+
221
+ /**
222
+ * Returns the order status.
223
+ *
224
+ * @since 5.2.0
225
+ *
226
+ * @param WP_Post $item
227
+ *
228
+ * @return string
229
+ */
230
+ public function column_status( $item ) {
231
+ $status = tribe( Status_Handler::class )->get_by_wp_slug( $item->post_status );
232
+
233
+ return esc_html( $status->get_name() );
234
+ }
235
+
236
+ /**
237
+ * Handler for the date column
238
+ *
239
+ * @since 5.2.0
240
+ *
241
+ * @param WP_Post $item
242
+ *
243
+ * @return string
244
+ */
245
+ public function column_date( $item ) {
246
+ return esc_html( \Tribe__Date_Utils::reformat( $item->post_modified, \Tribe__Date_Utils::DATEONLYFORMAT ) );
247
+ }
248
+
249
+ /**
250
+ * Handler for the purchased column
251
+ *
252
+ * @since 5.2.0
253
+ *
254
+ * @param WP_Post $item
255
+ *
256
+ * @return string
257
+ */
258
+ public function column_purchased( $item ) {
259
+ $output = '';
260
+
261
+ foreach ( $item->items as $cart_item ) {
262
+ $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $cart_item['ticket_id'] );
263
+ $name = esc_html( $ticket->name );
264
+ $quantity = esc_html( (int) $cart_item['quantity'] );
265
+ $output .= "<div class='tribe-line-item'>{$quantity} - {$name}</div>";
266
+ }
267
+
268
+ return $output;
269
+ }
270
+
271
+ /**
272
+ * Handler for the order column
273
+ *
274
+ * @since 5.2.0
275
+ *
276
+ * @param WP_Post $item
277
+ *
278
+ * @return string
279
+ */
280
+ public function column_order( $item ) {
281
+ $output = sprintf( esc_html__( '%1$s', 'event-tickets' ), $item->ID );
282
+ $status = tribe( Status_Handler::class )->get_by_wp_slug( $item->post_status );
283
+
284
+ switch ( $status->get_slug() ) {
285
+ default:
286
+ $output .= '<div class="order-status order-status-' . esc_attr( $status->get_slug() ) . '">';
287
+ $output .= esc_html( ucwords( $status->get_name() ) );
288
+ $output .= '</div>';
289
+ break;
290
+ }
291
+
292
+ return $output;
293
+ }
294
+
295
+ /**
296
+ * Handler for the total column
297
+ *
298
+ * @since 5.2.0
299
+ *
300
+ * @param WP_Post $item
301
+ *
302
+ * @return string
303
+ */
304
+ public function column_total( $item ) {
305
+ return tribe_format_currency( $item->total_value, $this->post_id );
306
+ }
307
+
308
+ /**
309
+ * Handler for gateway order id.
310
+ *
311
+ * @since 5.2.0
312
+ *
313
+ * @param WP_Post $item
314
+ *
315
+ * @return string
316
+ */
317
+ public function column_gateway_order_id( $item ) {
318
+ return $item->gateway_order_id;
319
+ }
320
+
321
+ /**
322
+ * Handler for gateway column
323
+ *
324
+ * @since 5.2.0
325
+ *
326
+ * @param WP_Post $item
327
+ *
328
+ * @return string
329
+ */
330
+ public function column_gateway( $item ) {
331
+ $gateway = tribe( Manager::class )->get_gateway_by_key( $item->gateway );
332
+ if ( ! $gateway ) {
333
+ return $item->gateway;
334
+ }
335
+ return $gateway::get_label();
336
+ }
337
+ }
src/Tickets/Commerce/Assets.php CHANGED
@@ -45,6 +45,7 @@ class Assets extends tad_DI52_ServiceProvider {
45
  [
46
  'tribe-common-skeleton-style',
47
  'tribe-common-full-style',
 
48
  ],
49
  null,
50
  [
@@ -52,6 +53,7 @@ class Assets extends tad_DI52_ServiceProvider {
52
  'tribe-tickets-commerce',
53
  'tribe-tickets-commerce-checkout',
54
  ],
 
55
  ]
56
  );
57
 
@@ -62,6 +64,7 @@ class Assets extends tad_DI52_ServiceProvider {
62
  [
63
  'jquery',
64
  'tribe-common',
 
65
  'tribe-tickets-loader',
66
  ],
67
  null,
@@ -72,5 +75,16 @@ class Assets extends tad_DI52_ServiceProvider {
72
  ],
73
  ]
74
  );
 
 
 
 
 
 
 
 
 
 
 
75
  }
76
  }
45
  [
46
  'tribe-common-skeleton-style',
47
  'tribe-common-full-style',
48
+ 'tribe-common-responsive',
49
  ],
50
  null,
51
  [
53
  'tribe-tickets-commerce',
54
  'tribe-tickets-commerce-checkout',
55
  ],
56
+ 'print' => true,
57
  ]
58
  );
59
 
64
  [
65
  'jquery',
66
  'tribe-common',
67
+ 'tribe-tickets-provider',
68
  'tribe-tickets-loader',
69
  ],
70
  null,
75
  ],
76
  ]
77
  );
78
+
79
+ tribe_asset(
80
+ $tickets_main,
81
+ 'tribe-tickets-commerce-notice-js',
82
+ 'commerce/notice.js',
83
+ [
84
+ 'jquery',
85
+ 'tribe-common',
86
+ ],
87
+ null
88
+ );
89
  }
90
  }
src/Tickets/Commerce/Attendee.php CHANGED
@@ -3,9 +3,11 @@
3
  namespace TEC\Tickets\Commerce;
4
 
5
  use TEC\Tickets\Commerce;
 
6
  use TEC\Tickets\Commerce\Status\Status_Handler;
7
  use \Tribe__Tickets__Ticket_Object as Ticket_Object;
8
  use Tribe__Utils__Array as Arr;
 
9
 
10
  /**
11
  * Class Attendee
@@ -15,6 +17,7 @@ use Tribe__Utils__Array as Arr;
15
  * @package TEC\Tickets\Commerce
16
  */
17
  class Attendee {
 
18
  /**
19
  * Tickets Commerce Attendee Post Type slug.
20
  *
@@ -148,16 +151,7 @@ class Attendee {
148
  *
149
  * @var string
150
  */
151
- public static $first_name_meta_key = '_tec_tickets_commerce_first_name';
152
-
153
- /**
154
- * Meta key holding the last name for the attendee. (not purchaser)
155
- *
156
- * @since 5.1.9
157
- *
158
- * @var string
159
- */
160
- public static $last_name_meta_key = '_tec_tickets_commerce_last_name';
161
 
162
  /**
163
  * Meta key holding the email for the attendee. (not purchaser)
@@ -186,6 +180,21 @@ class Attendee {
186
  */
187
  public static $currency_meta_key = '_tec_tickets_commerce_currency';
188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
  /**
191
  * Register this Class post type into WP.
@@ -236,11 +245,42 @@ class Attendee {
236
  'ticket_id' => $ticket->ID,
237
  'event_id' => $ticket->get_event_id(),
238
  'security_code' => Arr::get( $args, 'security_code' ),
239
- 'opt_out' => Arr::get( $args, 'optout' ),
240
- 'price_paid' => Arr::get( $args, 'price' ),
241
  'currency' => Arr::get( $args, 'currency' ),
242
  ];
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  /**
245
  * Allow the filtering of the create arguments for attendee.
246
  *
@@ -299,7 +339,7 @@ class Attendee {
299
  *
300
  * @since 5.1.9
301
  *
302
- * @param int $post_id WP_Post ID
303
  */
304
  public function maybe_redirect_to_attendees_report( $post_id ) {
305
  $post = get_post( $post_id );
@@ -308,11 +348,11 @@ class Attendee {
308
  return;
309
  }
310
 
311
- $args = array(
312
  'post_type' => 'tribe_events',
313
  'page' => \Tribe__Tickets__Tickets_Handler::$attendees_slug,
314
  'event_id' => get_post_meta( $post_id, static::$event_relation_meta_key, true ),
315
- );
316
 
317
  $url = add_query_arg( $args, admin_url( 'edit.php' ) );
318
  $url = esc_url_raw( $url );
@@ -344,7 +384,7 @@ class Attendee {
344
 
345
  $user_id = get_current_user_id();
346
 
347
- $ticket_attendees = $this->tickets_view->get_post_ticket_attendees( $post_id, $user_id );
348
  $ticket_attendee_ids = wp_list_pluck( $ticket_attendees, 'attendee_id' );
349
 
350
  // This makes sure we don't save attendees for attendees that are not from this current user and event.
@@ -393,10 +433,10 @@ class Attendee {
393
  *
394
  * @since 5.1.9
395
  *
396
- * @param int $event_id
397
  */
398
  public function maybe_send_tickets_after_status_change( $event_id ) {
399
- $transaction_ids = array();
400
 
401
  foreach ( tribe( Module::class )->get_event_attendees( $event_id ) as $attendee ) {
402
  $transaction = get_post_meta( $attendee['attendee_id'], static::$order_relation_meta_key, true );
@@ -409,16 +449,16 @@ class Attendee {
409
  foreach ( $transaction_ids as $transaction ) {
410
  // This method takes care of intelligently sending out emails only when
411
  // required, for attendees that have not yet received their tickets
412
- tribe( Module::class )->send_tickets_email( $transaction, $event_id );
413
  }
414
  }
415
 
416
  /**
417
  * Add our class to the list of classes for the attendee registration form
418
  *
419
- * @since TBd
420
  *
421
- * @param array $classes existing array of classes
422
  *
423
  * @return array $classes with our class added
424
  */
@@ -467,35 +507,329 @@ class Attendee {
467
  *
468
  * @since 5.1.9
469
  *
470
- * @param array $attendee
471
  *
472
  * @return bool
473
  */
474
  public function decreases_inventory( $attendee ) {
475
  $attendee = tec_tc_get_attendee( $attendee['ID'] );
476
  $order = tec_tc_get_order( $attendee->post_parent );
477
- $statuses = array_unique( [ tribe( Status_Handler::class )->get_inventory_decrease_status()->get_wp_slug(), tribe( Commerce\Status\Pending::class )->get_wp_slug() ] );
 
 
 
 
 
478
 
479
- return in_array( $order->post_status, $statuses, true );
480
  }
481
 
482
  /**
483
- * Get attendee data for attendee.
484
  *
485
- * @since 5.1.9
 
 
 
 
 
 
486
  */
487
- public function get_attendee() {
488
- /**
489
- * @todo Determine if this meta piece can be moved into the ET+ codebase.
490
- */
491
- $meta = '';
492
- if ( class_exists( 'Tribe__Tickets_Plus__Meta', false ) ) {
493
- $meta = get_post_meta( $attendee->ID, \Tribe__Tickets_Plus__Meta::META_KEY, true );
494
 
495
- // Process Meta to include value, slug, and label
496
- if ( ! empty( $meta ) ) {
497
- $meta = tribe( Module::class )->process_attendee_meta( $attendee['product_id'], $meta );
 
 
 
 
498
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
  }
501
  }
3
  namespace TEC\Tickets\Commerce;
4
 
5
  use TEC\Tickets\Commerce;
6
+ use TEC\Tickets\Commerce\Communications\Email;
7
  use TEC\Tickets\Commerce\Status\Status_Handler;
8
  use \Tribe__Tickets__Ticket_Object as Ticket_Object;
9
  use Tribe__Utils__Array as Arr;
10
+ use Tribe__Date_Utils;
11
 
12
  /**
13
  * Class Attendee
17
  * @package TEC\Tickets\Commerce
18
  */
19
  class Attendee {
20
+
21
  /**
22
  * Tickets Commerce Attendee Post Type slug.
23
  *
151
  *
152
  * @var string
153
  */
154
+ public static $full_name_meta_key = '_tec_tickets_commerce_full_name';
 
 
 
 
 
 
 
 
 
155
 
156
  /**
157
  * Meta key holding the email for the attendee. (not purchaser)
180
  */
181
  public static $currency_meta_key = '_tec_tickets_commerce_currency';
182
 
183
+ /**
184
+ * Meta key holding the attendee's unique id
185
+ *
186
+ * @since 5.2.0
187
+ *
188
+ * @var string
189
+ */
190
+ public static $unique_id_meta_key = '_unique_id';
191
+
192
+ /**
193
+ * Constructor
194
+ */
195
+ public function __construct() {
196
+ $this->legacy_rsvp_repo = tribe( 'tickets.rsvp' );
197
+ }
198
 
199
  /**
200
  * Register this Class post type into WP.
245
  'ticket_id' => $ticket->ID,
246
  'event_id' => $ticket->get_event_id(),
247
  'security_code' => Arr::get( $args, 'security_code' ),
248
+ 'opt_out' => Arr::get( $args, 'opt_out' ),
249
+ 'price_paid' => Arr::get( $args, 'price_paid' ),
250
  'currency' => Arr::get( $args, 'currency' ),
251
  ];
252
 
253
+ if ( ! empty( $order->purchaser['user_id'] ) ) {
254
+ $create_args['user_id'] = $order->purchaser['user_id'];
255
+ }
256
+
257
+ if ( ! empty( $args['email'] ) ) {
258
+ $create_args['email'] = $args['email'];
259
+ }
260
+
261
+ if (
262
+ empty( $args['email'] )
263
+ && ! empty( $order->purchaser['email'] )
264
+ ) {
265
+ $create_args['email'] = $order->purchaser['email'];
266
+ }
267
+
268
+ if ( ! empty( $args['full_name'] ) ) {
269
+ $create_args['full_name'] = $args['full_name'];
270
+ }
271
+
272
+ if (
273
+ empty( $args['full_name'] )
274
+ && ! empty( $order->purchaser['full_name'] )
275
+ ) {
276
+ $create_args['full_name'] = $order->purchaser['full_name'];
277
+ }
278
+
279
+ $fields = Arr::get( $args, 'fields', [] );
280
+ if ( ! empty( $fields ) ) {
281
+ $create_args['fields'] = $fields;
282
+ }
283
+
284
  /**
285
  * Allow the filtering of the create arguments for attendee.
286
  *
339
  *
340
  * @since 5.1.9
341
  *
342
+ * @param int $post_id WP_Post ID.
343
  */
344
  public function maybe_redirect_to_attendees_report( $post_id ) {
345
  $post = get_post( $post_id );
348
  return;
349
  }
350
 
351
+ $args = [
352
  'post_type' => 'tribe_events',
353
  'page' => \Tribe__Tickets__Tickets_Handler::$attendees_slug,
354
  'event_id' => get_post_meta( $post_id, static::$event_relation_meta_key, true ),
355
+ ];
356
 
357
  $url = add_query_arg( $args, admin_url( 'edit.php' ) );
358
  $url = esc_url_raw( $url );
384
 
385
  $user_id = get_current_user_id();
386
 
387
+ $ticket_attendees = tribe( Module::class )->get_attendees_by_user_id( $user_id, $post_id );
388
  $ticket_attendee_ids = wp_list_pluck( $ticket_attendees, 'attendee_id' );
389
 
390
  // This makes sure we don't save attendees for attendees that are not from this current user and event.
433
  *
434
  * @since 5.1.9
435
  *
436
+ * @param int $event_id the event id.
437
  */
438
  public function maybe_send_tickets_after_status_change( $event_id ) {
439
+ $transaction_ids = [];
440
 
441
  foreach ( tribe( Module::class )->get_event_attendees( $event_id ) as $attendee ) {
442
  $transaction = get_post_meta( $attendee['attendee_id'], static::$order_relation_meta_key, true );
449
  foreach ( $transaction_ids as $transaction ) {
450
  // This method takes care of intelligently sending out emails only when
451
  // required, for attendees that have not yet received their tickets
452
+ tribe( Email::class )->send_tickets_email( $transaction, $event_id );
453
  }
454
  }
455
 
456
  /**
457
  * Add our class to the list of classes for the attendee registration form
458
  *
459
+ * @since 5.2.0
460
  *
461
+ * @param array $classes existing array of classes.
462
  *
463
  * @return array $classes with our class added
464
  */
507
  *
508
  * @since 5.1.9
509
  *
510
+ * @param array $attendee array of attendee information.
511
  *
512
  * @return bool
513
  */
514
  public function decreases_inventory( $attendee ) {
515
  $attendee = tec_tc_get_attendee( $attendee['ID'] );
516
  $order = tec_tc_get_order( $attendee->post_parent );
517
+ $statuses = array_unique(
518
+ [
519
+ tribe( Status_Handler::class )->get_inventory_decrease_status()->get_wp_slug(),
520
+ tribe( Commerce\Status\Completed::class )->get_wp_slug(),
521
+ ]
522
+ );
523
 
524
+ return in_array( $order->post_status, $statuses, true );
525
  }
526
 
527
  /**
528
+ * Hydrate attendee object with ticket data
529
  *
530
+ * @todo We should not be using this particular piece of the code until it's using `tec_tc_get_attendee`.
531
+ *
532
+ * @since 5.2.0
533
+ *
534
+ * @param \WP_Post $attendee the attendee object.
535
+ *
536
+ * @return \WP_Post
537
  */
538
+ public function get_attendee( \WP_Post $attendee ) {
 
 
 
 
 
 
539
 
540
+ if ( static::POSTTYPE !== $attendee->post_type ) {
541
+ $attendee->is_legacy_attendee = true;
542
+ $legacy_provider = tribe_tickets_get_ticket_provider( $attendee->ID );
543
+ $attendee_data = (array) $legacy_provider->get_attendee( $attendee );
544
+
545
+ foreach ( $attendee_data as $key => $value ) {
546
+ $attendee->{$key} = $value;
547
  }
548
+ } else {
549
+ $attendee = $this->load_attendee_data( $attendee );
550
+ }
551
+
552
+ return $attendee;
553
+ }
554
+
555
+ /**
556
+ * Loads event, ticket, order and other data into an attendee object
557
+ *
558
+ * @todo We should not be using this particular piece of the code until it's using `tec_tc_get_attendee`.
559
+ *
560
+ * @since 5.2.0
561
+ *
562
+ * @param \WP_Post $attendee the attendee object.
563
+ *
564
+ * @return \WP_Post
565
+ */
566
+ public function load_attendee_data( \WP_Post $attendee ) {
567
+ $attendee->attendee_id = $attendee->ID;
568
+ $attendee->attendee_meta = null;
569
+ $attendee->check_in = $this->get_check_in_status( $attendee );
570
+ $attendee->event_id = $this->get_event_id( $attendee );
571
+ $attendee->holder_email = $this->get_holder_email( $attendee );
572
+ $attendee->holder_name = $this->get_holder_name( $attendee );
573
+ $attendee->is_legacy_attendee = false;
574
+ $attendee->is_purchaser = true;
575
+ $attendee->is_subscribed = null;
576
+ $attendee->optout = null;
577
+ $attendee->order_id = 0;
578
+ $attendee->product = $this->get_product( $attendee );
579
+ $attendee->product_id = $this->get_product_id( $attendee );
580
+ $attendee->provider = Commerce::ABBR;
581
+ $attendee->provider_slug = Commerce::ABBR;
582
+ $attendee->purchase_time = get_post_time( Tribe__Date_Utils::DBDATETIMEFORMAT, false, $attendee->order_id );
583
+ $attendee->qr_ticket_id = null;
584
+ $attendee->security = $this->get_security_code( $attendee );
585
+ $attendee->security_code = $this->get_security_code( $attendee );
586
+ $attendee->ticket = $this->get_product_title( $attendee );
587
+ $attendee->ticket_id = $this->get_unique_id( $attendee );
588
+ $attendee->ticket_name = $this->get_product_title( $attendee );
589
+ $attendee->ticket_sent = null;
590
+ $attendee->user_id = null;
591
+
592
+ $order = $this->get_order( $attendee );
593
+
594
+ if ( $order ) {
595
+ $attendee->order_id = $order->ID;
596
+ $attendee->order_status = $order->post_status;
597
+ $attendee->order_status_label = tribe( Tickets_View::class )->get_rsvp_options( $attendee->order_status );
598
+ $attendee->purchaser_name = get_post_meta( $order->ID, Order::$purchaser_full_name_meta_key, true );
599
+ $attendee->purchaser_email = get_post_meta( $order->ID, Order::$purchaser_email_meta_key, true );
600
+ }
601
+
602
+ if ( empty( $attendee->ticket_id ) ) {
603
+ $attendee->ticket_id = $attendee->ID;
604
+ }
605
+
606
+ return $attendee;
607
+ }
608
+
609
+ /**
610
+ * Returns the product object related to an attendee
611
+ *
612
+ * @since 5.2.0
613
+ *
614
+ * @param \WP_Post $attendee the attendee object.
615
+ *
616
+ * @return \WP_Post|\stdClass
617
+ */
618
+ public function get_product( \WP_Post $attendee ) {
619
+ $product = get_post_meta( $attendee->ID, Module::ATTENDEE_PRODUCT_KEY, true );
620
+
621
+ if ( $product ) {
622
+ return get_post( $product );
623
+ }
624
+
625
+ return (object) [];
626
+ }
627
+
628
+ /**
629
+ * Returns the product id related to an attendee
630
+ *
631
+ * @since 5.2.0
632
+ *
633
+ * @param \WP_Post $attendee the attendee object.
634
+ *
635
+ * @return string
636
+ */
637
+ public function get_product_id( \WP_Post $attendee ) {
638
+ if ( empty( $attendee->product->ID ) ) {
639
+ return '';
640
+ }
641
+
642
+ return (string) $attendee->product->ID;
643
+ }
644
+
645
+ /**
646
+ * Returns the product title related to an attendee
647
+ *
648
+ * @since 5.2.0
649
+ *
650
+ * @param \WP_Post $attendee the attendee object.
651
+ *
652
+ * @return string
653
+ */
654
+ public function get_product_title( \WP_Post $attendee ) {
655
+ $ticket = get_post( $attendee->ticket_id );
656
+
657
+ return ! empty( $ticket->post_title ) ?
658
+ esc_html( $this->post_title ) :
659
+ get_post_meta( $attendee->ID, static::$deleted_ticket_meta_key, true );
660
+ }
661
+
662
+ /**
663
+ * Returns the event id related to an attendee
664
+ *
665
+ * @since 5.2.0
666
+ *
667
+ * @param \WP_Post $attendee the attendee object.
668
+ *
669
+ * @return string
670
+ */
671
+ public function get_event_id( \WP_Post $attendee ) {
672
+ return get_post_meta( $attendee->ID, static::$event_relation_meta_key, true );
673
+ }
674
+
675
+ /**
676
+ * Returns the ticket unique id related to an attendee
677
+ *
678
+ * @since 5.2.0
679
+ *
680
+ * @param \WP_Post $attendee the attendee object.
681
+ *
682
+ * @return string
683
+ */
684
+ public function get_unique_id( \WP_Post $attendee ) {
685
+ $id = ! empty( $attendee->attendee_id ) ? $attendee->attendee_id : $attendee->ID;
686
+
687
+ return get_post_meta( $id, static::$unique_id_meta_key, true );
688
+ }
689
+
690
+ /**
691
+ * Returns the ticket id related to an attendee
692
+ *
693
+ * @since 5.2.0
694
+ *
695
+ * @param \WP_Post $attendee the attendee object.
696
+ *
697
+ * @return string
698
+ */
699
+ public function get_ticket_id( \WP_Post $attendee ) {
700
+ if ( $attendee->is_legacy_attendee ) {
701
+ return $attendee->product_id;
702
+ }
703
+
704
+ return get_post_meta( $attendee->ID, static::$ticket_relation_meta_key, true );
705
+ }
706
+
707
+ /**
708
+ * Returns the security code for an attendee
709
+ *
710
+ * @since 5.2.0
711
+ *
712
+ * @param \WP_Post $attendee the attendee object.
713
+ *
714
+ * @return string
715
+ */
716
+ public function get_security_code( \WP_Post $attendee ) {
717
+ if ( $attendee->is_legacy_attendee ) {
718
+ return $attendee->security_code;
719
+ }
720
+
721
+ return get_post_meta( $attendee->ID, static::$security_code_meta_key, true );
722
+ }
723
+
724
+ /**
725
+ * Returns the check in status of an attendee
726
+ *
727
+ * @since 5.2.0
728
+ *
729
+ * @param \WP_Post $attendee the attendee object.
730
+ *
731
+ * @return string
732
+ */
733
+ public function get_check_in_status( \WP_Post $attendee ) {
734
+ if ( $attendee->is_legacy_attendee ) {
735
+ return $attendee->check_in;
736
+ }
737
+
738
+ return get_post_meta( $attendee->ID, static::$checked_in_meta_key, true );
739
+ }
740
+
741
+ /**
742
+ * Returns the status label used in the Status column
743
+ *
744
+ * @since 5.2.0
745
+ *
746
+ * @param \WP_Post $attendee the attendee object.
747
+ *
748
+ * @return string
749
+ */
750
+ public function get_status_label( \WP_Post $attendee ) {
751
+ if ( $attendee->is_legacy_attendee ) {
752
+ return $attendee->order_status_label;
753
  }
754
+
755
+ $checked_in = $this->get_check_in_status( $attendee );
756
+
757
+ if ( empty( $checked_in ) ) {
758
+ return '';
759
+ }
760
+
761
+ return tribe( Tickets_View::class )->get_rsvp_options( '1' === $checked_in ? 'yes' : 'no' );
762
+ }
763
+
764
+ /**
765
+ * Returns the order object related to an attendee
766
+ *
767
+ * @since 5.2.0
768
+ *
769
+ * @param \WP_Post $attendee the attendee object.
770
+ *
771
+ * @return array|WP_Post|null The Order post object or array, `null` if not found.
772
+ */
773
+ public function get_order( \WP_Post $attendee ) {
774
+ return tec_tc_get_order(
775
+ get_post_meta( $attendee->ID, static::$order_relation_meta_key, true )
776
+ );
777
+ }
778
+
779
+ /**
780
+ * Returns the purchaser name if available
781
+ *
782
+ * @since 5.2.0
783
+ *
784
+ * @param \WP_Post $attendee the attendee object.
785
+ *
786
+ * @return string
787
+ */
788
+ public function get_holder_name( \WP_Post $attendee ) {
789
+ $name = get_post_meta( $attendee->ID, static::$purchaser_name_meta_key, true );
790
+
791
+ if ( $name ) {
792
+ return esc_html( $name );
793
+ }
794
+
795
+ return esc_html__( 'Name not available', 'event-tickets' );
796
+ }
797
+
798
+ /**
799
+ * Returns the purchaser email if available
800
+ *
801
+ * @since 5.2.0
802
+ *
803
+ * @param \WP_Post $attendee the attendee object.
804
+ *
805
+ * @return string
806
+ */
807
+ public function get_holder_email( \WP_Post $attendee ) {
808
+ $email = get_post_meta( $attendee->ID, static::$purchaser_email_meta_key, true );
809
+
810
+ if ( $email ) {
811
+ return esc_html( $email );
812
+ }
813
+
814
+ return esc_html__( 'Email not available', 'event-tickets' );
815
+ }
816
+
817
+ /**
818
+ * Check if the attendee is of valid type.
819
+ *
820
+ * @since 5.2.0
821
+ *
822
+ * @param int|\WP_Post $attendee The attendee object to check.
823
+ *
824
+ * @return bool
825
+ */
826
+ public static function is_valid( $attendee ) {
827
+ $attendee = get_post( $attendee );
828
+
829
+ if ( ! $attendee ) {
830
+ return false;
831
+ }
832
+
833
+ return static::POSTTYPE === $attendee->post_type;
834
  }
835
  }
src/Tickets/Commerce/Cart.php CHANGED
@@ -64,13 +64,26 @@ class Cart {
64
  public static $cart_hash_cookie_name = 'tec-tickets-commerce-cart';
65
 
66
  /**
67
- * Which invoice number we are using here.
 
 
68
  *
69
  * @since 5.1.9
70
  *
71
- * @var string
72
  */
73
- protected $cart_hash;
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  /**
76
  * From the current active cart repository we fetch it's mode.
@@ -105,7 +118,6 @@ class Cart {
105
  */
106
  public function is_available_mode( $mode ) {
107
  return in_array( $mode, $this->get_available_modes(), true );
108
-
109
  }
110
 
111
  /**
@@ -143,29 +155,20 @@ class Cart {
143
  return Commerce::ABBR . '-cart-' . md5( $id );
144
  }
145
 
146
- /**
147
- * Returns the name of the transient used by the cart for invoice numbers
148
- *
149
- * @since 5.1.9
150
- *
151
- * @param string $id
152
- *
153
- * @return string
154
- */
155
- public static function get_invoice_transient_name( $id ) {
156
- return Commerce::ABBR . '-invoice-' . md5( $id );
157
- }
158
-
159
  /**
160
  * Determine the Current cart Transient Key based on invoice number.
161
  *
162
  * @since 5.1.9
163
  *
164
- * @return string
165
  */
166
  public function get_current_cart_transient() {
167
  $cart_hash = $this->get_cart_hash();
168
 
 
 
 
 
169
  return static::get_transient_name( $cart_hash );
170
  }
171
 
@@ -196,12 +199,12 @@ class Cart {
196
  *
197
  * @since 5.1.9
198
  *
199
- * @return string|bool The cart hash or `false` if not found.
200
  */
201
  public function get_cart_hash( $generate = false ) {
202
  $cart_hash_length = 12;
203
 
204
- $cart_hash = $this->cart_hash;
205
 
206
  if (
207
  ! empty( $_COOKIE[ static::$cart_hash_cookie_name ] )
@@ -212,24 +215,43 @@ class Cart {
212
  $cart_hash_transient = get_transient( static::get_transient_name( $cart_hash ) );
213
 
214
  if ( empty( $cart_hash_transient ) ) {
215
- $cart_hash = false;
216
  }
217
  }
218
 
219
  if ( empty( $cart_hash ) && $generate ) {
220
- $cart_hash = wp_generate_password( $cart_hash_length, false );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  }
222
 
223
- /**
224
- * Filters the cart hash used for the Cart.
225
- *
226
- * @since 5.1.9
227
- *
228
- * @param string $cart_hash Invoice number.
229
- */
230
- $this->cart_hash = apply_filters( 'tec_tickets_commerce_cart_hash', $cart_hash );
231
 
232
- return $this->cart_hash;
 
 
 
 
 
 
 
 
 
233
  }
234
 
235
  /**
@@ -237,20 +259,15 @@ class Cart {
237
  *
238
  * @since 5.1.9
239
  *
240
- * @return false
241
  */
242
  public function clear_cart() {
243
- $is_empty = empty( $_COOKIE[ static::$cart_hash_cookie_name ] );
244
  $this->set_cart_hash_cookie( null );
 
245
 
246
- if ( $is_empty ) {
247
- return false;
248
- }
249
-
250
- $cart_hash = $_COOKIE[ static::$cart_hash_cookie_name ];
251
  unset( $_COOKIE[ static::$cart_hash_cookie_name ] );
252
 
253
- return delete_transient( static::get_transient_name( $cart_hash ) );
254
  }
255
 
256
  /**
@@ -296,26 +313,6 @@ class Cart {
296
  return $is_cookie_set;
297
  }
298
 
299
- /**
300
- * Gets the current instance of cart handling that we are using.
301
- *
302
- * @since 5.1.9
303
- *
304
- * @return Commerce\Cart\Cart_Interface
305
- */
306
- public function get_repository() {
307
- $default_cart = tribe( Cart\Unmanaged_Cart::class );
308
-
309
- /**
310
- * Filters the cart repository, by default we use Unmanaged Cart.
311
- *
312
- * @since 5.1.9
313
- *
314
- * @param Cart\Cart_Interface $cart Instance of the cart repository managing the cart.
315
- */
316
- return apply_filters( 'tec_tickets_commerce_cart_repository', $default_cart );
317
- }
318
-
319
  /**
320
  * Get the tickets currently in the cart for a given provider.
321
  *
@@ -326,8 +323,7 @@ class Cart {
326
  * @return array List of items.
327
  */
328
  public function get_items_in_cart( $full_item_params = false ) {
329
- $cart = $this->get_repository();
330
-
331
  $items = $cart->get_items();
332
 
333
  // When Items is empty in any capacity return an empty array.
@@ -338,6 +334,11 @@ class Cart {
338
  if ( $full_item_params ) {
339
  $items = array_map( static function ( $item ) {
340
  $item['obj'] = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
 
 
 
 
 
341
  $item['event_id'] = $item['obj']->get_event_id();
342
  $item['sub_total'] = Price::sub_total( $item['obj']->price, $item['quantity'] );
343
 
@@ -345,7 +346,7 @@ class Cart {
345
  }, $items );
346
  }
347
 
348
- return $items;
349
  }
350
 
351
  /**
@@ -407,7 +408,7 @@ class Cart {
407
  $transient_key = $this->get_current_cart_transient();
408
 
409
  // Bail if we have no data key.
410
- if ( false === $transient_key ) {
411
  return;
412
  }
413
 
@@ -542,7 +543,6 @@ class Cart {
542
  * @param array $data The cart data after processing.
543
  */
544
  return apply_filters( 'tec_tickets_commerce_cart_prepare_data', $this->get_repository()->prepare_data( $data ) );
545
-
546
  }
547
 
548
  /**
@@ -585,6 +585,16 @@ class Cart {
585
  if ( static::REDIRECT_MODE === $this->get_mode() ) {
586
  $redirect_url = tribe( Checkout::class )->get_url();
587
 
 
 
 
 
 
 
 
 
 
 
588
  if (
589
  ! isset( $_COOKIE[ $this->get_cart_hash() ] )
590
  || ! $_COOKIE[ $this->get_cart_hash() ]
64
  public static $cart_hash_cookie_name = 'tec-tickets-commerce-cart';
65
 
66
  /**
67
+ * Gets the current instance of cart handling that we are using.
68
+ * Most of the pieces should be handled in the Repository for the cart, only piece fully handled by the
69
+ * parent class is the cookie handling.
70
  *
71
  * @since 5.1.9
72
  *
73
+ * @return Commerce\Cart\Cart_Interface
74
  */
75
+ public function get_repository() {
76
+ $default_cart = tribe( Cart\Unmanaged_Cart::class );
77
+
78
+ /**
79
+ * Filters the cart repository, by default we use Unmanaged Cart.
80
+ *
81
+ * @since 5.1.9
82
+ *
83
+ * @param Cart\Cart_Interface $cart Instance of the cart repository managing the cart.
84
+ */
85
+ return apply_filters( 'tec_tickets_commerce_cart_repository', $default_cart );
86
+ }
87
 
88
  /**
89
  * From the current active cart repository we fetch it's mode.
118
  */
119
  public function is_available_mode( $mode ) {
120
  return in_array( $mode, $this->get_available_modes(), true );
 
121
  }
122
 
123
  /**
155
  return Commerce::ABBR . '-cart-' . md5( $id );
156
  }
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  /**
159
  * Determine the Current cart Transient Key based on invoice number.
160
  *
161
  * @since 5.1.9
162
  *
163
+ * @return string|null
164
  */
165
  public function get_current_cart_transient() {
166
  $cart_hash = $this->get_cart_hash();
167
 
168
+ if ( empty( $cart_hash ) ) {
169
+ return null;
170
+ }
171
+
172
  return static::get_transient_name( $cart_hash );
173
  }
174
 
199
  *
200
  * @since 5.1.9
201
  *
202
+ * @return string|null The cart hash or `null` if not found.
203
  */
204
  public function get_cart_hash( $generate = false ) {
205
  $cart_hash_length = 12;
206
 
207
+ $cart_hash = $this->get_repository()->get_hash();
208
 
209
  if (
210
  ! empty( $_COOKIE[ static::$cart_hash_cookie_name ] )
215
  $cart_hash_transient = get_transient( static::get_transient_name( $cart_hash ) );
216
 
217
  if ( empty( $cart_hash_transient ) ) {
218
+ $cart_hash = null;
219
  }
220
  }
221
 
222
  if ( empty( $cart_hash ) && $generate ) {
223
+ $tries = 1;
224
+ $max_tries = 20;
225
+
226
+ $this->clear_cart();
227
+ // While we dont find an empty transient to store this cart we loop, but avoid more than 20 tries.
228
+ while (
229
+ ( ! empty( $cart_hash_transient ) || empty( $cart_hash ) )
230
+ && $max_tries >= $tries
231
+ ) {
232
+ $cart_hash = wp_generate_password( $cart_hash_length, false );
233
+ $cart_hash_transient = get_transient( static::get_transient_name( $cart_hash ) );
234
+
235
+ // Make sure we increment.
236
+ $tries ++;
237
+ }
238
  }
239
 
240
+ $this->set_cart_hash( $cart_hash );
241
+
242
+ return $this->get_repository()->get_hash();
243
+ }
 
 
 
 
244
 
245
+ /**
246
+ * Configures the Cart hash on the class object
247
+ *
248
+ * @since 5.2.0
249
+ *
250
+ * @param string $cart_hash Cart hash value.
251
+ *
252
+ */
253
+ public function set_cart_hash( $cart_hash ) {
254
+ $this->get_repository()->set_hash( $cart_hash );
255
  }
256
 
257
  /**
259
  *
260
  * @since 5.1.9
261
  *
262
+ * @return bool
263
  */
264
  public function clear_cart() {
 
265
  $this->set_cart_hash_cookie( null );
266
+ $this->get_repository()->clear();
267
 
 
 
 
 
 
268
  unset( $_COOKIE[ static::$cart_hash_cookie_name ] );
269
 
270
+ return delete_transient( static::get_current_cart_transient() );
271
  }
272
 
273
  /**
313
  return $is_cookie_set;
314
  }
315
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  /**
317
  * Get the tickets currently in the cart for a given provider.
318
  *
323
  * @return array List of items.
324
  */
325
  public function get_items_in_cart( $full_item_params = false ) {
326
+ $cart = $this->get_repository();
 
327
  $items = $cart->get_items();
328
 
329
  // When Items is empty in any capacity return an empty array.
334
  if ( $full_item_params ) {
335
  $items = array_map( static function ( $item ) {
336
  $item['obj'] = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
337
+ // If it's an invalid ticket we just remove it.
338
+ if ( ! $item['obj'] instanceof \Tribe__Tickets__Ticket_Object ) {
339
+ return null;
340
+ }
341
+
342
  $item['event_id'] = $item['obj']->get_event_id();
343
  $item['sub_total'] = Price::sub_total( $item['obj']->price, $item['quantity'] );
344
 
346
  }, $items );
347
  }
348
 
349
+ return array_filter( $items );
350
  }
351
 
352
  /**
408
  $transient_key = $this->get_current_cart_transient();
409
 
410
  // Bail if we have no data key.
411
+ if ( empty( $transient_key ) ) {
412
  return;
413
  }
414
 
543
  * @param array $data The cart data after processing.
544
  */
545
  return apply_filters( 'tec_tickets_commerce_cart_prepare_data', $this->get_repository()->prepare_data( $data ) );
 
546
  }
547
 
548
  /**
585
  if ( static::REDIRECT_MODE === $this->get_mode() ) {
586
  $redirect_url = tribe( Checkout::class )->get_url();
587
 
588
+ /**
589
+ * Filter the base redirect URL for cart to checkout.
590
+ *
591
+ * @since 5.2.0
592
+ *
593
+ * @param string $redirect_url Redirect URL.
594
+ * @param array $data Data that we just processed on the cart.
595
+ */
596
+ $redirect_url = apply_filters( 'tec_tickets_commerce_cart_to_checkout_redirect_url_base', $redirect_url, $data );
597
+
598
  if (
599
  ! isset( $_COOKIE[ $this->get_cart_hash() ] )
600
  || ! $_COOKIE[ $this->get_cart_hash() ]
src/Tickets/Commerce/Cart/Cart_Interface.php CHANGED
@@ -12,13 +12,23 @@ namespace TEC\Tickets\Commerce\Cart;
12
  interface Cart_Interface {
13
 
14
  /**
15
- * Sets the cart id.
16
  *
17
  * @since 5.1.9
 
18
  *
19
- * @param string $id
20
  */
21
- public function set_id( $id );
 
 
 
 
 
 
 
 
 
22
 
23
  /**
24
  * Gets the Cart mode based.
12
  interface Cart_Interface {
13
 
14
  /**
15
+ * Sets the cart hash.
16
  *
17
  * @since 5.1.9
18
+ * @since 5.2.0 Renamed to set_hash instead of set_id
19
  *
20
+ * @param string $hash
21
  */
22
+ public function set_hash( $hash );
23
+
24
+ /**
25
+ * Gets the cart hash.
26
+ *
27
+ * @since 5.2.0
28
+ *
29
+ * @return string
30
+ */
31
+ public function get_hash();
32
 
33
  /**
34
  * Gets the Cart mode based.
src/Tickets/Commerce/Cart/Unmanaged_Cart.php CHANGED
@@ -41,8 +41,31 @@ class Unmanaged_Cart implements Cart_Interface {
41
  /**
42
  * {@inheritdoc}
43
  */
44
- public function set_id( $id ) {
45
- $this->cart_hash = $id;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
 
48
  /**
@@ -55,10 +78,11 @@ class Unmanaged_Cart implements Cart_Interface {
55
  return false;
56
  }
57
 
 
 
58
  if ( ! $this->has_items() ) {
59
  $this->clear();
60
-
61
- return;
62
  }
63
 
64
  set_transient( Commerce\Cart::get_transient_name( $cart_hash ), $this->items, DAY_IN_SECONDS );
@@ -74,10 +98,10 @@ class Unmanaged_Cart implements Cart_Interface {
74
  }
75
 
76
  if ( ! $this->exists() ) {
77
- return false;
78
  }
79
 
80
- $cart_hash = tribe( Commerce\Cart::class )->get_cart_hash();
81
 
82
  $items = get_transient( Commerce\Cart::get_transient_name( $cart_hash ) );
83
 
@@ -98,6 +122,7 @@ class Unmanaged_Cart implements Cart_Interface {
98
  return false;
99
  }
100
 
 
101
  delete_transient( Commerce\Cart::get_transient_name( $cart_hash ) );
102
  tribe( Commerce\Cart::class )->set_cart_hash_cookie( $cart_hash );
103
  }
@@ -130,7 +155,7 @@ class Unmanaged_Cart implements Cart_Interface {
130
  public function has_item( $item_id ) {
131
  $items = $this->get_items();
132
 
133
- return ! empty( $items[ $item_id ] ) ? (int) $items[ $item_id ]['quantity'] : false;
134
  }
135
 
136
  /**
@@ -149,7 +174,7 @@ class Unmanaged_Cart implements Cart_Interface {
149
 
150
  if ( 0 < $new_quantity ) {
151
  $item['ticket_id'] = $item_id;
152
- $item['quantity'] = $new_quantity;
153
 
154
  $item['extra'] = $extra_data;
155
 
41
  /**
42
  * {@inheritdoc}
43
  */
44
+ public function set_hash( $hash ) {
45
+ /**
46
+ * Filters the cart setting of a hash used for the Cart.
47
+ *
48
+ * @since 5.2.0
49
+ *
50
+ * @param string $cart_hash Cart hash value.
51
+ * @param Cart_Interface $cart Which cart object we are using here.
52
+ */
53
+ $this->cart_hash = apply_filters( 'tec_tickets_commerce_cart_set_hash', $hash, $this );
54
+ }
55
+
56
+ /**
57
+ * {@inheritdoc}
58
+ */
59
+ public function get_hash() {
60
+ /**
61
+ * Filters the cart hash used for the Cart.
62
+ *
63
+ * @since 5.2.0
64
+ *
65
+ * @param string $cart_hash Cart hash value.
66
+ * @param Cart_Interface $cart Which cart object we are using here.
67
+ */
68
+ return apply_filters( 'tec_tickets_commerce_cart_get_hash', $this->cart_hash, $this );
69
  }
70
 
71
  /**
78
  return false;
79
  }
80
 
81
+ $this->set_hash( $cart_hash );
82
+
83
  if ( ! $this->has_items() ) {
84
  $this->clear();
85
+ return false;
 
86
  }
87
 
88
  set_transient( Commerce\Cart::get_transient_name( $cart_hash ), $this->items, DAY_IN_SECONDS );
98
  }
99
 
100
  if ( ! $this->exists() ) {
101
+ return [];
102
  }
103
 
104
+ $cart_hash = $this->get_hash();
105
 
106
  $items = get_transient( Commerce\Cart::get_transient_name( $cart_hash ) );
107
 
122
  return false;
123
  }
124
 
125
+ $this->set_hash( null );
126
  delete_transient( Commerce\Cart::get_transient_name( $cart_hash ) );
127
  tribe( Commerce\Cart::class )->set_cart_hash_cookie( $cart_hash );
128
  }
155
  public function has_item( $item_id ) {
156
  $items = $this->get_items();
157
 
158
+ return ! empty( $items[ $item_id ]['quantity'] ) ? (int) $items[ $item_id ]['quantity'] : false;
159
  }
160
 
161
  /**
174
 
175
  if ( 0 < $new_quantity ) {
176
  $item['ticket_id'] = $item_id;
177
+ $item['quantity'] = $new_quantity;
178
 
179
  $item['extra'] = $extra_data;
180
 
src/Tickets/Commerce/Checkout.php CHANGED
@@ -10,6 +10,15 @@ namespace TEC\Tickets\Commerce;
10
  * @package TEC\Tickets\Commerce
11
  */
12
  class Checkout {
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Get the Checkout page ID.
15
  *
@@ -178,4 +187,38 @@ class Checkout {
178
 
179
  return $post_states;
180
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  }
10
  * @package TEC\Tickets\Commerce
11
  */
12
  class Checkout {
13
+ /**
14
+ * Which URL param we use to identify a given page as the checkout.
15
+ *
16
+ * @since 5.2.0
17
+ *
18
+ * @var string
19
+ */
20
+ public static $url_query_arg = 'tec-tc-checkout';
21
+
22
  /**
23
  * Get the Checkout page ID.
24
  *
187
 
188
  return $post_states;
189
  }
190
+
191
+ /**
192
+ * Determines whether or not the success page option is set.
193
+ *
194
+ * @since 5.2.0
195
+ *
196
+ * @return bool
197
+ */
198
+ public function is_option_set() {
199
+ $page = $this->get_page_id();
200
+ return ! empty( $page );
201
+ }
202
+
203
+ /**
204
+ * Determines whether or not the success page has the appropriate shortcode in the content.
205
+ *
206
+ * @since 5.2.0
207
+ *
208
+ * @return bool
209
+ */
210
+ public function page_has_shortcode() {
211
+ if ( ! $this->is_option_set() ) {
212
+ return false;
213
+ }
214
+
215
+ $page = get_post( $this->get_page_id() );
216
+
217
+ if ( ! $page instanceof \WP_Post ) {
218
+ return false;
219
+ }
220
+
221
+ $shortcode = Shortcodes\Checkout_Shortcode::get_wp_slug();
222
+ return has_shortcode( $page->post_content, $shortcode );
223
+ }
224
  }
src/Tickets/Commerce/Communication/Email.php CHANGED
@@ -1,25 +1,27 @@
1
  <?php
2
 
3
- namespace TEC\Tickets\Commerce\Communications;
 
 
4
 
5
  /**
6
  * Class Email
7
  *
8
  * @since 5.1.9
9
  *
10
- * @package TEC\Tickets\Commerce\Communications
11
  */
12
  class Email {
13
  /**
14
  * Sends ticket email
15
  *
16
- * @since 4.7.6 added $post_id parameter
17
  *
18
  * @param string $order_id Order post ID
19
  * @param int $post_id Parent post ID (optional)
20
  */
21
  public function send_tickets_email( $order_id, $post_id = null ) {
22
- $all_attendees = $this->get_attendees_by_order_id( $order_id );
23
 
24
  $to_send = array();
25
 
@@ -42,8 +44,7 @@ class Email {
42
  /**
43
  * Controls the list of tickets which will be emailed out.
44
  *
45
- * @since 4.7
46
- * @since 4.7.6 added new parameter $post_id
47
  *
48
  * @param array $to_send list of tickets to be sent out by email
49
  * @param array $all_attendees list of all attendees/tickets, including those already sent out
@@ -51,7 +52,7 @@ class Email {
51
  * @param string $order_id
52
  *
53
  */
54
- $to_send = (array) apply_filters( 'tribe_tickets_tpp_tickets_to_send', $to_send, $all_attendees, $post_id, $order_id );
55
 
56
  if ( empty( $to_send ) ) {
57
  return;
@@ -64,6 +65,6 @@ class Email {
64
  ];
65
 
66
  // Send the emails.
67
- $this->send_tickets_email_for_attendees( $to_send, $send_args );
68
  }
69
  }
1
  <?php
2
 
3
+ namespace TEC\Tickets\Commerce\Communication;
4
+
5
+ use TEC\Tickets\Commerce\Module;
6
 
7
  /**
8
  * Class Email
9
  *
10
  * @since 5.1.9
11
  *
12
+ * @package TEC\Tickets\Commerce\Communication
13
  */
14
  class Email {
15
  /**
16
  * Sends ticket email
17
  *
18
+ * @since 5.2.0
19
  *
20
  * @param string $order_id Order post ID
21
  * @param int $post_id Parent post ID (optional)
22
  */
23
  public function send_tickets_email( $order_id, $post_id = null ) {
24
+ $all_attendees = tribe( Module::class )->get_attendees_by_order_id( $order_id );
25
 
26
  $to_send = array();
27
 
44
  /**
45
  * Controls the list of tickets which will be emailed out.
46
  *
47
+ * @since 5.2.0
 
48
  *
49
  * @param array $to_send list of tickets to be sent out by email
50
  * @param array $all_attendees list of all attendees/tickets, including those already sent out
52
  * @param string $order_id
53
  *
54
  */
55
+ $to_send = (array) apply_filters( 'tec_tickets_commerce_legacy_email_tickets_to_send', $to_send, $all_attendees, $post_id, $order_id );
56
 
57
  if ( empty( $to_send ) ) {
58
  return;
65
  ];
66
 
67
  // Send the emails.
68
+ tribe( Module::class )->send_tickets_email_for_attendees( $to_send, $send_args );
69
  }
70
  }
src/Tickets/Commerce/Compatibility/Events.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles Tickets Commerce compatibility with The Events Calendar.
4
+ *
5
+ * @since 5.2.0
6
+ *
7
+ * @package TEC\Tickets\Commerce\Compatibility
8
+ */
9
+
10
+ namespace TEC\Tickets\Commerce\Compatibility;
11
+
12
+ use TEC\Tickets\Commerce\Checkout;
13
+
14
+ /**
15
+ * Class Events.
16
+ *
17
+ * @since 5.2.0
18
+ *
19
+ * @package TEC\Tickets\Commerce\Compatibility
20
+ */
21
+ class Events {
22
+
23
+ /**
24
+ * In cases where Event Tickets is running alongside The Events Calendar and the home page is set to be the Events page, this
25
+ * redirect will trigger a hook in The Events Calendar that was designed to prevent funky page loads out of context.
26
+ * We don't need those checks to run when redirecting to the Cart page in Tickets Commerce so we
27
+ * short-circuit the context.
28
+ *
29
+ * @since 5.2.0
30
+ *
31
+ * @param string $location the URL we're redirecting to.
32
+ * @param int $status The redirect status code.
33
+ *
34
+ * @return string
35
+ */
36
+ public function prevent_filter_redirect_canonical( $location, $status ) {
37
+
38
+ if ( 302 !== $status || false === strpos( $location, 'tec-tc-cookie=' ) ) {
39
+ return $location;
40
+ }
41
+
42
+ // The complete checkout url must be the first thing in the $location string
43
+ if ( 0 !== strpos( $location, tribe( Checkout::class )->get_url() ) ) {
44
+ return $location;
45
+ }
46
+
47
+ add_filter( 'tribe_context_view_request', '__return_false' );
48
+
49
+ return $location;
50
+ }
51
+ }
src/Tickets/Commerce/Editor/Metabox.php CHANGED
@@ -9,7 +9,7 @@ use Tribe__Tickets__Main as Tickets_Plugin;
9
  /**
10
  * Class Metabox.
11
  *
12
- * @since 5.1.9
13
  *
14
  * @package TEC\Tickets\Commerce\Editor
15
  */
@@ -31,7 +31,7 @@ class Metabox {
31
 
32
  /** @var \Tribe__Tickets__Tickets_Handler $tickets_handler */
33
  $tickets_handler = tribe( 'tickets.handler' );
34
- $provider_obj = tribe( Module::class );
35
 
36
  $is_correct_provider = $tickets_handler->is_correct_provider( $post_id, $provider_obj );
37
 
@@ -67,7 +67,7 @@ class Metabox {
67
  public function include_metabox_advanced_options( $post_id, $ticket_id ) {
68
  $provider = __CLASS__;
69
 
70
- echo '<div id="' . sanitize_html_class( $provider ) . '_advanced" class="tribe-dependent" data-depends="#' . sanitize_html_class( $provider ) . '_radio" data-condition-is-checked>';
71
 
72
  if ( ! tribe_is_frontend() ) {
73
  $this->do_metabox_sku_options( $post_id, $ticket_id );
@@ -93,7 +93,7 @@ class Metabox {
93
  * Using the method, providers can add as many fields as
94
  * they want, specific to their implementation.
95
  *
96
- * @since 4.7
97
  *
98
  * @param int $post_id
99
  * @param int $ticket_id
@@ -103,7 +103,7 @@ class Metabox {
103
  public function do_metabox_capacity_options( $post_id, $ticket_id ) {
104
  /** @var \Tribe__Tickets__Tickets_Handler $tickets_handler */
105
  $tickets_handler = tribe( 'tickets.handler' );
106
- $provider = tribe( Module::class );
107
 
108
  $is_correct_provider = $tickets_handler->is_correct_provider( $post_id, $provider );
109
 
@@ -142,13 +142,13 @@ class Metabox {
142
  /**
143
  * Filters the absolute path to the file containing the metabox capacity HTML.
144
  *
145
- * @since 4.7
146
  *
147
  * @param string $file The absolute path to the file containing the metabox capacity HTML
148
  * @param int|string $ticket_capacity
149
  * @param int|string $post_capacity
150
  */
151
- $file = apply_filters( 'tribe_tickets_tc_metabox_capacity_file', $file, $ticket_capacity, $post_capacity );
152
 
153
  if ( file_exists( $file ) ) {
154
  include $file;
9
  /**
10
  * Class Metabox.
11
  *
12
+ * @since 5.1.9
13
  *
14
  * @package TEC\Tickets\Commerce\Editor
15
  */
31
 
32
  /** @var \Tribe__Tickets__Tickets_Handler $tickets_handler */
33
  $tickets_handler = tribe( 'tickets.handler' );
34
+ $provider_obj = tribe( Module::class );
35
 
36
  $is_correct_provider = $tickets_handler->is_correct_provider( $post_id, $provider_obj );
37
 
67
  public function include_metabox_advanced_options( $post_id, $ticket_id ) {
68
  $provider = __CLASS__;
69
 
70
+ echo '<div id="' . sanitize_html_class( $provider ) . '_advanced" class="tribe-dependent" data-depends="#provider_TEC_Tickets_Commerce_Module_radio" data-condition-is-checked>';
71
 
72
  if ( ! tribe_is_frontend() ) {
73
  $this->do_metabox_sku_options( $post_id, $ticket_id );
93
  * Using the method, providers can add as many fields as
94
  * they want, specific to their implementation.
95
  *
96
+ * @since 5.2.0
97
  *
98
  * @param int $post_id
99
  * @param int $ticket_id
103
  public function do_metabox_capacity_options( $post_id, $ticket_id ) {
104
  /** @var \Tribe__Tickets__Tickets_Handler $tickets_handler */
105
  $tickets_handler = tribe( 'tickets.handler' );
106
+ $provider = tribe( Module::class );
107
 
108
  $is_correct_provider = $tickets_handler->is_correct_provider( $post_id, $provider );
109
 
142
  /**
143
  * Filters the absolute path to the file containing the metabox capacity HTML.
144
  *
145
+ * @since 5.2.0
146
  *
147
  * @param string $file The absolute path to the file containing the metabox capacity HTML
148
  * @param int|string $ticket_capacity
149
  * @param int|string $post_capacity
150
  */
151
+ $file = apply_filters( 'tec_tickets_commerce_metabox_capacity_file', $file, $ticket_capacity, $post_capacity );
152
 
153
  if ( file_exists( $file ) ) {
154
  include $file;
src/Tickets/Commerce/Flag_Actions/Archive_Attendees.php CHANGED
@@ -41,11 +41,11 @@ class Archive_Attendees extends Flag_Action_Abstract {
41
  */
42
  public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
43
  // @todo we need an error handling piece here.
44
- if ( empty( $post->cart_items ) ) {
45
  return;
46
  }
47
 
48
- foreach ( $post->cart_items as $ticket_id => $item ) {
49
  $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
50
  if ( null === $ticket ) {
51
  continue;
41
  */
42
  public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
43
  // @todo we need an error handling piece here.
44
+ if ( empty( $post->items ) ) {
45
  return;
46
  }
47
 
48
+ foreach ( $post->items as $ticket_id => $item ) {
49
  $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
50
  if ( null === $ticket ) {
51
  continue;
src/Tickets/Commerce/Flag_Actions/Backfill_Purchaser.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Flag_Actions;
4
+
5
+ use TEC\Tickets\Commerce\Attendee;
6
+ use TEC\Tickets\Commerce\Gateways\PayPal\Gateway as PayPal_Gateway;
7
+ use TEC\Tickets\Commerce\Module;
8
+ use TEC\Tickets\Commerce\Order;
9
+ use TEC\Tickets\Commerce\Status\Completed;
10
+ use TEC\Tickets\Commerce\Status\Status_Interface;
11
+
12
+ /**
13
+ * Class Increase_Stock, normally triggered when refunding on orders get set to not-completed.
14
+ *
15
+ * @since 5.1.9
16
+ *
17
+ * @package TEC\Tickets\Commerce\Flag_Actions
18
+ */
19
+ class Backfill_Purchaser extends Flag_Action_Abstract {
20
+ /**
21
+ * {@inheritDoc}
22
+ */
23
+ protected $flags = [
24
+ 'backfill_purchaser',
25
+ ];
26
+
27
+ /**
28
+ * {@inheritDoc}
29
+ */
30
+ protected $post_types = [
31
+ Order::POSTTYPE
32
+ ];
33
+
34
+ /**
35
+ * {@inheritDoc}
36
+ */
37
+ public function handle( Status_Interface $new_status, $old_status, \WP_Post $order ) {
38
+ if ( empty( $order->gateway_payload[ Completed::SLUG ] ) ) {
39
+ return;
40
+ }
41
+
42
+ if ( ! empty( $order->purchaser_email ) ) {
43
+ return;
44
+ }
45
+
46
+ // @todo move this piece out the flag action since it's PayPal gateway specific.
47
+ if (
48
+ empty( $order->gateway )
49
+ || PayPal_Gateway::get_key() !== $order->gateway
50
+ ) {
51
+ return;
52
+ }
53
+
54
+ $payload = end( $order->gateway_payload[ Completed::SLUG ] );
55
+
56
+ if ( empty( $payload['payer']['email_address'] ) ) {
57
+ return;
58
+ }
59
+
60
+ if ( ! filter_var( $payload['payer']['email_address'], FILTER_VALIDATE_EMAIL ) ) {
61
+ return;
62
+ }
63
+
64
+ $email = trim( $payload['payer']['email_address'] );
65
+ $first_name = null;
66
+ $last_name = null;
67
+ $full_name = null;
68
+
69
+ if ( ! empty( $payload['payer']['name']['given_name'] ) ) {
70
+ $first_name = trim( $payload['payer']['name']['given_name'] );
71
+ }
72
+
73
+ if ( ! empty( $payload['payer']['name']['surname'] ) ) {
74
+ $last_name = trim( $payload['payer']['name']['surname'] );
75
+ }
76
+
77
+ $full_name = trim( $first_name . ' ' . $last_name );
78
+
79
+ update_post_meta( $order->ID, Order::$purchaser_email_meta_key, $email );
80
+ update_post_meta( $order->ID, Order::$purchaser_first_name_meta_key, $first_name );
81
+ update_post_meta( $order->ID, Order::$purchaser_last_name_meta_key, $last_name );
82
+ update_post_meta( $order->ID, Order::$purchaser_full_name_meta_key, $full_name );
83
+
84
+ $attendees = tribe( Module::class )->get_attendees_by_order_id( $order->ID );
85
+
86
+ if ( empty( $attendees ) ) {
87
+ return;
88
+ }
89
+
90
+ foreach ( $attendees as $attendee ) {
91
+ if ( empty( $attendee['holder_email'] ) ) {
92
+ update_post_meta( $attendee['ID'], Attendee::$email_meta_key, $email );
93
+ }
94
+
95
+ if ( empty( $attendee['holder_name'] ) || Order::$placeholder_name === $attendee['holder_name'] ) {
96
+ update_post_meta( $attendee['ID'], Attendee::$full_name_meta_key, $full_name );
97
+ }
98
+ }
99
+ }
100
+ }
src/Tickets/Commerce/Flag_Actions/Decrease_Sales.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Flag_Actions;
4
+
5
+ use TEC\Tickets\Commerce\Order;
6
+ use TEC\Tickets\Commerce\Status\Denied;
7
+ use TEC\Tickets\Commerce\Status\Pending;
8
+ use TEC\Tickets\Commerce\Status\Status_Interface;
9
+ use TEC\Tickets\Commerce\Ticket;
10
+ use Tribe__Utils__Array as Arr;
11
+
12
+ /**
13
+ * Class Increase_Sales, normally triggered when refunding on orders get set to not-completed.
14
+ *
15
+ * @since 5.2.0
16
+ *
17
+ * @package TEC\Tickets\Commerce\Flag_Actions
18
+ */
19
+ class Decrease_Sales extends Flag_Action_Abstract {
20
+
21
+ /**
22
+ * {@inheritDoc}
23
+ *
24
+ * @since 5.2.0
25
+ */
26
+ protected $flags = [
27
+ 'decrease_sales',
28
+ ];
29
+
30
+ /**
31
+ * {@inheritDoc}
32
+ *
33
+ * @since 5.2.0
34
+ */
35
+ protected $post_types = [
36
+ Order::POSTTYPE,
37
+ ];
38
+
39
+ /**
40
+ * {@inheritDoc}
41
+ *
42
+ * @since 5.2.0
43
+ */
44
+ public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
45
+ if ( empty( $post->items ) ) {
46
+ return;
47
+ }
48
+
49
+ foreach ( $post->items as $ticket_id => $item ) {
50
+ $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
51
+ if ( null === $ticket ) {
52
+ continue;
53
+ }
54
+
55
+ $quantity = Arr::get( $item, 'quantity' );
56
+
57
+ if ( ! $quantity ) {
58
+ continue;
59
+ }
60
+
61
+ // Skip generating for zero-ed items.
62
+ if ( 0 >= $quantity ) {
63
+ continue;
64
+ }
65
+
66
+ $global_stock = new \Tribe__Tickets__Global_Stock( $ticket->get_event_id() );
67
+
68
+ tribe( Ticket::class )->decrease_ticket_sales_by( $ticket->ID, $quantity, $ticket->global_stock_mode(), $global_stock );
69
+ }
70
+ }
71
+
72
+ }
src/Tickets/Commerce/Flag_Actions/Decrease_Stock.php CHANGED
@@ -84,11 +84,11 @@ class Decrease_Stock extends Flag_Action_Abstract {
84
  * {@inheritDoc}
85
  */
86
  public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
87
- if ( empty( $post->cart_items ) ) {
88
  return;
89
  }
90
 
91
- foreach ( $post->cart_items as $ticket_id => $item ) {
92
  $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
93
  if ( null === $ticket ) {
94
  continue;
84
  * {@inheritDoc}
85
  */
86
  public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
87
+ if ( empty( $post->items ) ) {
88
  return;
89
  }
90
 
91
+ foreach ( $post->items as $ticket_id => $item ) {
92
  $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
93
  if ( null === $ticket ) {
94
  continue;
src/Tickets/Commerce/Flag_Actions/End_Duplicated_Pending_Orders.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Flag_Actions;
4
+
5
+ use TEC\Tickets\Commerce\Order;
6
+ use TEC\Tickets\Commerce\Status\Not_Completed;
7
+ use TEC\Tickets\Commerce\Status\Pending;
8
+ use TEC\Tickets\Commerce\Status\Status_Interface;
9
+ use Tribe__Utils__Array as Arr;
10
+
11
+ /**
12
+ * Class End_Duplicated_Pending_Orders, normally triggered when a given order is completed it will modify the status of all the
13
+ * other orders created with the same Hash cart key, which prevents leaving pending orders open when one was completed.
14
+ *
15
+ * @since 5.2.0
16
+ *
17
+ * @package TEC\Tickets\Commerce\Flag_Actions
18
+ */
19
+ class End_Duplicated_Pending_Orders extends Flag_Action_Abstract {
20
+
21
+ /**
22
+ * {@inheritDoc}
23
+ *
24
+ * @since 5.2.0
25
+ */
26
+ protected $flags = [
27
+ 'end_duplicated_pending_orders',
28
+ ];
29
+
30
+ /**
31
+ * {@inheritDoc}
32
+ *
33
+ * @since 5.2.0
34
+ */
35
+ protected $post_types = [
36
+ Order::POSTTYPE,
37
+ ];
38
+
39
+ /**
40
+ * {@inheritDoc}
41
+ *
42
+ * @since 5.2.0
43
+ */
44
+ public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
45
+ if ( empty( $post->hash ) ) {
46
+ return;
47
+ }
48
+
49
+ $orders_query = tec_tc_orders()->by_args( [
50
+ 'status' => tribe( Pending::class )->get_wp_slug(),
51
+ 'hash' => $post->hash,
52
+ 'per_page' => - 1,
53
+ ] );
54
+
55
+ if ( ! $orders_query->found() ) {
56
+ return;
57
+ }
58
+
59
+ $duplicated_orders = $orders_query->all();
60
+ foreach ( $duplicated_orders as $order ) {
61
+ tribe( Order::class )->modify_status( $order->ID, Not_Completed::SLUG );
62
+ }
63
+ }
64
+ }
src/Tickets/Commerce/Flag_Actions/Flag_Action_Handler.php CHANGED
@@ -31,6 +31,11 @@ class Flag_Action_Handler extends \tad_DI52_ServiceProvider {
31
  Increase_Stock::class,
32
  Decrease_Stock::class,
33
  Archive_Attendees::class,
 
 
 
 
 
34
  ];
35
 
36
  /**
31
  Increase_Stock::class,
32
  Decrease_Stock::class,
33
  Archive_Attendees::class,
34
+ Backfill_Purchaser::class,
35
+ Send_Email::class,
36
+ Increase_Sales::class,
37
+ Decrease_Sales::class,
38
+ End_Duplicated_Pending_Orders::class,
39
  ];
40
 
41
  /**
src/Tickets/Commerce/Flag_Actions/Generate_Attendees.php CHANGED
@@ -6,12 +6,9 @@ use TEC\Tickets\Commerce\Attendee;
6
  use TEC\Tickets\Commerce\Module;
7
  use TEC\Tickets\Commerce\Order;
8
  use TEC\Tickets\Commerce\Settings;
9
- use TEC\Tickets\Commerce\Status\Completed;
10
- use TEC\Tickets\Commerce\Status\Pending;
11
  use TEC\Tickets\Commerce\Status\Status_Abstract;
12
  use TEC\Tickets\Commerce\Status\Status_Handler;
13
  use TEC\Tickets\Commerce\Status\Status_Interface;
14
- use TEC\Tickets\Commerce\Ticket;
15
  use Tribe__Utils__Array as Arr;
16
 
17
  /**
@@ -79,15 +76,15 @@ class Generate_Attendees extends Flag_Action_Abstract {
79
  /**
80
  * {@inheritDoc}
81
  */
82
- public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
83
  // @todo we need an error handling piece here.
84
- if ( empty( $post->cart_items ) ) {
85
  return;
86
  }
87
 
88
  $default_currency = tribe_get_option( Settings::$option_currency_code, 'USD' );
89
 
90
- foreach ( $post->cart_items as $ticket_id => $item ) {
91
  $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
92
  if ( null === $ticket ) {
93
  continue;
@@ -101,16 +98,63 @@ class Generate_Attendees extends Flag_Action_Abstract {
101
  continue;
102
  }
103
 
 
 
104
  for ( $i = 0; $i < $quantity; $i ++ ) {
105
  $args = [
106
  'opt_out' => Arr::get( $extra, 'optout' ),
107
  'price_paid' => Arr::get( $item, 'price' ),
108
  'currency' => Arr::get( $item, 'currency', $default_currency ),
109
- 'security_code' => tribe( Module::class )->generate_security_code( time() . '-' . $i )
110
  ];
111
 
112
- $attendee = tribe( Attendee::class )->create( $post, $ticket, $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  }
115
  }
116
  }
6
  use TEC\Tickets\Commerce\Module;
7
  use TEC\Tickets\Commerce\Order;
8
  use TEC\Tickets\Commerce\Settings;
 
 
9
  use TEC\Tickets\Commerce\Status\Status_Abstract;
10
  use TEC\Tickets\Commerce\Status\Status_Handler;
11
  use TEC\Tickets\Commerce\Status\Status_Interface;
 
12
  use Tribe__Utils__Array as Arr;
13
 
14
  /**
76
  /**
77
  * {@inheritDoc}
78
  */
79
+ public function handle( Status_Interface $new_status, $old_status, \WP_Post $order ) {
80
  // @todo we need an error handling piece here.
81
+ if ( empty( $order->items ) ) {
82
  return;
83
  }
84
 
85
  $default_currency = tribe_get_option( Settings::$option_currency_code, 'USD' );
86
 
87
+ foreach ( $order->items as $ticket_id => $item ) {
88
  $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
89
  if ( null === $ticket ) {
90
  continue;
98
  continue;
99
  }
100
 
101
+ $attendees = [];
102
+
103
  for ( $i = 0; $i < $quantity; $i ++ ) {
104
  $args = [
105
  'opt_out' => Arr::get( $extra, 'optout' ),
106
  'price_paid' => Arr::get( $item, 'price' ),
107
  'currency' => Arr::get( $item, 'currency', $default_currency ),
108
+ 'security_code' => tribe( Module::class )->generate_security_code( time() . '-' . $i ),
109
  ];
110
 
111
+ /**
112
+ * Filters the attendee data before it is saved.
113
+ *
114
+ * @since 5.2.0
115
+ *
116
+ * @param array<mixed> $args The attendee creation args.
117
+ * @param \Tribe__Tickets__Tickets $ticket The ticket the attendee is generated for.
118
+ * @param \WP_Post $order The order the attendee is generated for.
119
+ * @param Status_Interface $new_status New post status.
120
+ * @param Status_Interface|null $old_status Old post status.
121
+ * @param array $item Which cart item this args are for.
122
+ * @param int $i Which Attendee index we are generating.
123
+ */
124
+ $args = apply_filters( 'tec_tickets_commerce_flag_action_generate_attendee_args', $args, $ticket, $order, $new_status, $old_status, $item, $i );
125
+
126
+ $attendee = tribe( Attendee::class )->create( $order, $ticket, $args );
127
+
128
+ /**
129
+ * Fires after an attendee is generated for an order.
130
+ *
131
+ * @since 5.2.0
132
+ *
133
+ * @param Attendee $attendee The generated attendee.
134
+ * @param \Tribe__Tickets__Tickets $ticket The ticket the attendee is generated for.
135
+ * @param \WP_Post $order The order the attendee is generated for.
136
+ * @param Status_Interface $new_status New post status.
137
+ * @param Status_Interface|null $old_status Old post status.
138
+ * @param array $item Which cart item this was generated for.
139
+ * @param int $i Which Attendee index we are generating.
140
+ */
141
+ do_action( 'tec_tickets_commerce_flag_action_generated_attendee', $attendee, $ticket, $order, $new_status, $old_status, $item, $i );
142
+
143
+ $attendees[] = $attendee;
144
  }
145
+
146
+ /**
147
+ * Fires after all attendees are generated for an order.
148
+ *
149
+ * @since 5.2.0
150
+ *
151
+ * @param array<Attendee> $attendees The generated attendees.
152
+ * @param \Tribe__Tickets__Tickets $ticket The ticket the attendee is generated for.
153
+ * @param \WP_Post $order The order the attendee is generated for.
154
+ * @param Status_Interface $new_status New post status.
155
+ * @param Status_Interface|null $old_status Old post status.
156
+ */
157
+ do_action( 'tec_tickets_commerce_flag_action_generated_attendees', $attendees, $ticket, $order, $new_status, $old_status );
158
  }
159
  }
160
  }
src/Tickets/Commerce/Flag_Actions/Increase_Sales.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Flag_Actions;
4
+
5
+ use TEC\Tickets\Commerce\Order;
6
+ use TEC\Tickets\Commerce\Status\Denied;
7
+ use TEC\Tickets\Commerce\Status\Pending;
8
+ use TEC\Tickets\Commerce\Status\Status_Interface;
9
+ use TEC\Tickets\Commerce\Ticket;
10
+ use Tribe__Utils__Array as Arr;
11
+
12
+ /**
13
+ * Class Increase_Sales, normally triggered when refunding on orders get set to not-completed.
14
+ *
15
+ * @since 5.2.0
16
+ *
17
+ * @package TEC\Tickets\Commerce\Flag_Actions
18
+ */
19
+ class Increase_Sales extends Flag_Action_Abstract {
20
+
21
+ /**
22
+ * {@inheritDoc}
23
+ *
24
+ * @since 5.2.0
25
+ */
26
+ protected $flags = [
27
+ 'increase_sales',
28
+ ];
29
+
30
+ /**
31
+ * {@inheritDoc}
32
+ *
33
+ * @since 5.2.0
34
+ */
35
+ protected $post_types = [
36
+ Order::POSTTYPE,
37
+ ];
38
+
39
+ /**
40
+ * {@inheritDoc}
41
+ *
42
+ * @since 5.2.0
43
+ */
44
+ public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
45
+ if ( empty( $post->items ) ) {
46
+ return;
47
+ }
48
+
49
+ foreach ( $post->items as $ticket_id => $item ) {
50
+ $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
51
+ if ( null === $ticket ) {
52
+ continue;
53
+ }
54
+
55
+ $quantity = Arr::get( $item, 'quantity' );
56
+
57
+ if ( ! $quantity ) {
58
+ continue;
59
+ }
60
+
61
+ // Skip generating for zero-ed items.
62
+ if ( 0 >= $quantity ) {
63
+ continue;
64
+ }
65
+
66
+ $global_stock = new \Tribe__Tickets__Global_Stock( $ticket->get_event_id() );
67
+
68
+ tribe( Ticket::class )->increase_ticket_sales_by( $ticket->ID, $quantity, $ticket->global_stock_mode(), $global_stock );
69
+ }
70
+ }
71
+ }
src/Tickets/Commerce/Flag_Actions/Increase_Stock.php CHANGED
@@ -33,11 +33,11 @@ class Increase_Stock extends Flag_Action_Abstract {
33
  * {@inheritDoc}
34
  */
35
  public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
36
- if ( empty( $post->cart_items ) ) {
37
  return;
38
  }
39
 
40
- foreach ( $post->cart_items as $ticket_id => $item ) {
41
  $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
42
  if ( null === $ticket ) {
43
  continue;
33
  * {@inheritDoc}
34
  */
35
  public function handle( Status_Interface $new_status, $old_status, \WP_Post $post ) {
36
+ if ( empty( $post->items ) ) {
37
  return;
38
  }
39
 
40
+ foreach ( $post->items as $ticket_id => $item ) {
41
  $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
42
  if ( null === $ticket ) {
43
  continue;
src/Tickets/Commerce/Flag_Actions/Send_Email.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Flag_Actions;
4
+
5
+ use TEC\Tickets\Commerce\Communication\Email;
6
+ use TEC\Tickets\Commerce\Order;
7
+ use TEC\Tickets\Commerce\Status\Status_Interface;
8
+ use TEC\Tickets\Commerce\Ticket;
9
+ use Tribe__Utils__Array as Arr;
10
+
11
+ /**
12
+ * Class Increase_Stock, normally triggered when refunding on orders get set to not-completed.
13
+ *
14
+ * @since 5.1.9
15
+ *
16
+ * @package TEC\Tickets\Commerce\Flag_Actions
17
+ */
18
+ class Send_Email extends Flag_Action_Abstract {
19
+ /**
20
+ * {@inheritDoc}
21
+ */
22
+ protected $flags = [
23
+ 'send_email',
24
+ ];
25
+
26
+ /**
27
+ * {@inheritDoc}
28
+ */
29
+ protected $post_types = [
30
+ Order::POSTTYPE
31
+ ];
32
+
33
+ /**
34
+ * {@inheritDoc}
35
+ */
36
+ public function handle( Status_Interface $new_status, $old_status, \WP_Post $order ) {
37
+
38
+ // temporary fix for manual attendees first email
39
+ // @todo backend review this logic
40
+ if ( ! empty( $order->gateway ) && 'manual' === $order->gateway && empty( $order->events_in_order ) ) {
41
+ $order->events_in_order[] = $order;
42
+ }
43
+
44
+
45
+ if ( empty( $order->events_in_order ) || ! is_array( $order->events_in_order ) ) {
46
+ return;
47
+ }
48
+
49
+ foreach ( $order->events_in_order as $event_id ) {
50
+ $event = get_post( $event_id );
51
+ if ( ! $event instanceof \WP_Post ) {
52
+ continue;
53
+ }
54
+
55
+ /**
56
+ * If this request is being generated via ajax in the Attendees View admin page, we need to
57
+ * make sure the email only goes out after all the work to register the order and attendees is
58
+ * finished, so we hook it to the same hook used to process everything, but make sure it's the last
59
+ * function to run.
60
+ *
61
+ * @todo TribeLegacyCommerce
62
+ */
63
+ if ( doing_action( 'wp_ajax_tribe_tickets_admin_manager' ) ) {
64
+ add_filter( 'tribe_tickets_admin_manager_request', static function( $response ) use ( $order, $event ) {
65
+ tribe( Email::class )->send_tickets_email( $order->ID, $event->ID );
66
+ return $response;
67
+ }, 9999 );
68
+ return;
69
+ }
70
+
71
+ tribe( Email::class )->send_tickets_email( $order->ID, $event->ID );
72
+ }
73
+ }
74
+ }
src/Tickets/Commerce/Gateways/Abstract_Gateway.php CHANGED
@@ -49,6 +49,13 @@ abstract class Abstract_Gateway implements Interface_Gateway {
49
  return $gateways;
50
  }
51
 
 
 
 
 
 
 
 
52
  /**
53
  * @inheritDoc
54
  */
49
  return $gateways;
50
  }
51
 
52
+ /**
53
+ * @inheritDoc
54
+ */
55
+ public static function is_connected() {
56
+ return false;
57
+ }
58
+
59
  /**
60
  * @inheritDoc
61
  */
src/Tickets/Commerce/Gateways/Interface_Gateway.php CHANGED
@@ -42,10 +42,19 @@ interface Interface_Gateway {
42
  *
43
  * @since 5.1.6
44
  *
45
- * @return bool Whether the provider is active.
46
  */
47
  public static function is_active();
48
 
 
 
 
 
 
 
 
 
 
49
  /**
50
  * Determine whether the gateway should be shown as an available gateway.
51
  *
42
  *
43
  * @since 5.1.6
44
  *
45
+ * @return bool Whether the gateway is active.
46
  */
47
  public static function is_active();
48
 
49
+ /**
50
+ * Determine whether the gateway is connected.
51
+ *
52
+ * @since 5.2.0
53
+ *
54
+ * @return bool Whether the gateway is connected.
55
+ */
56
+ public static function is_connected();
57
+
58
  /**
59
  * Determine whether the gateway should be shown as an available gateway.
60
  *
src/Tickets/Commerce/Gateways/Manager.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  namespace TEC\Tickets\Commerce\Gateways;
4
 
5
- use TEC\Tickets\Commerce\Settings;
6
 
7
  /**
8
  * Class Gateways Manager.
@@ -21,24 +21,6 @@ class Manager {
21
  */
22
  public static $option_gateway = '_tickets_commerce_gateway';
23
 
24
- /**
25
- * Determine whether PayPal Legacy should be shown as an available gateway.
26
- *
27
- * @since 5.1.6
28
- *
29
- * @return bool Whether PayPal Legacy should be shown as an available gateway.
30
- */
31
- public function should_show_legacy() {
32
- /**
33
- * Determine whether PayPal Legacy should be shown as an available gateway.
34
- *
35
- * @since 5.1.6
36
- *
37
- * @param bool $should_show Whether PayPal Legacy should be shown as an available gateway.
38
- */
39
- return (bool) apply_filters( 'tec_tickets_commerce_display_legacy', ! tec_tickets_commerce_is_enabled() );
40
- }
41
-
42
  /**
43
  * Get the list of registered Tickets Commerce gateways.
44
  *
@@ -51,7 +33,6 @@ class Manager {
51
  * Allow filtering the list of registered Tickets Commerce gateways.
52
  *
53
  * PayPal Commerce filters at priority 10.
54
- * PayPal Legacy filters at priority 15.
55
  *
56
  * @since 5.1.6
57
  *
@@ -68,11 +49,7 @@ class Manager {
68
  * @return string The current Tickets Commerce gateway.
69
  */
70
  public function get_current_gateway() {
71
- $default = null;
72
-
73
- if ( ! $this->should_show_legacy() ) {
74
- $default = PayPal\Gateway::get_key();
75
- }
76
 
77
  return (string) tribe_get_option( static::$option_gateway, $default );
78
  }
@@ -103,20 +80,24 @@ class Manager {
103
  continue;
104
  }
105
 
106
- $heading = [
107
- 'tickets-commerce-' . $gateway_key => [
108
- 'type' => 'html',
109
- 'html' => '<h3 class="event-tickets__admin-settings-subheading" class="tribe-dependent" data-depends="#' . Settings::$option_enable . '-input" data-condition-is-checked>' . $gateway::get_label() . '</h3>',
110
- 'validation_type' => 'html',
111
- ],
112
- ];
113
-
114
- // Add the gateway label to the start of settings.
115
- $gateway_setting_groups[] = $heading;
116
-
117
  $gateway_setting_groups[] = $gateway_settings;
118
  }
119
 
120
  return array_merge( ...$gateway_setting_groups );
121
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  }
2
 
3
  namespace TEC\Tickets\Commerce\Gateways;
4
 
5
+ use TEC\Tickets\Settings;
6
 
7
  /**
8
  * Class Gateways Manager.
21
  */
22
  public static $option_gateway = '_tickets_commerce_gateway';
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  /**
25
  * Get the list of registered Tickets Commerce gateways.
26
  *
33
  * Allow filtering the list of registered Tickets Commerce gateways.
34
  *
35
  * PayPal Commerce filters at priority 10.
 
36
  *
37
  * @since 5.1.6
38
  *
49
  * @return string The current Tickets Commerce gateway.
50
  */
51
  public function get_current_gateway() {
52
+ $default = PayPal\Gateway::get_key();
 
 
 
 
53
 
54
  return (string) tribe_get_option( static::$option_gateway, $default );
55
  }
80
  continue;
81
  }
82
 
 
 
 
 
 
 
 
 
 
 
 
83
  $gateway_setting_groups[] = $gateway_settings;
84
  }
85
 
86
  return array_merge( ...$gateway_setting_groups );
87
  }
88
+
89
+ /**
90
+ * Get gateway by key.
91
+ *
92
+ * @since 5.2.0
93
+ *
94
+ * @param string $key Key for expected gateway.
95
+ *
96
+ * @return Abstract_Gateway
97
+ */
98
+ public function get_gateway_by_key( $key ) {
99
+ $gateways = $this->get_gateways();
100
+
101
+ return isset( $gateways[ $key ] ) ? $gateways[ $key ] : null;
102
+ }
103
  }
src/Tickets/Commerce/Gateways/Manual/Assets.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles registering and setup for assets on Ticket Commerce Manual Gateway.
4
+ *
5
+ * @since 5.2.0
6
+ *
7
+ * @package TEC\Tickets\Commerce\Gateways\Manual
8
+ */
9
+
10
+ namespace TEC\Tickets\Commerce\Gateways\Manual;
11
+
12
+
13
+ /**
14
+ * Class Assets.
15
+ *
16
+ * @since 5.2.0
17
+ *
18
+ * @package TEC\Tickets\Commerce\Gateways\Manual
19
+ */
20
+ class Assets extends \tad_DI52_ServiceProvider {
21
+
22
+ /**
23
+ * Binds and sets up implementations.
24
+ *
25
+ * @since 5.2.0
26
+ */
27
+ public function register() {
28
+ $plugin = \Tribe__Tickets__Main::instance();
29
+
30
+ }
31
+
32
+ }
src/Tickets/Commerce/Gateways/Manual/Gateway.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Gateways\Manual;
4
+
5
+ use TEC\Tickets\Commerce\Gateways\Abstract_Gateway;
6
+
7
+ /**
8
+ * Class Manual Gateway.
9
+ *
10
+ * @since 5.2.0
11
+ * @package TEC\Tickets\Commerce\Gateways\Manual
12
+ */
13
+ class Gateway extends Abstract_Gateway {
14
+ /**
15
+ * @inheritDoc
16
+ *
17
+ * @since 5.2.0
18
+ */
19
+ protected static $key = 'manual';
20
+
21
+ /**
22
+ * @inheritDoc
23
+ *
24
+ * @since 5.2.0
25
+ */
26
+ public static function get_label() {
27
+ return __( 'Manually Generated', 'event-tickets' );
28
+ }
29
+
30
+ /**
31
+ * @inheritDoc
32
+ *
33
+ * @since 5.2.0
34
+ */
35
+ public static function is_connected() {
36
+ return true;
37
+ }
38
+
39
+ /**
40
+ * @inheritDoc
41
+ *
42
+ * @since 5.2.0
43
+ */
44
+ public static function is_active() {
45
+ return true;
46
+ }
47
+
48
+ /**
49
+ * @inheritDoc
50
+ *
51
+ * @since 5.2.0
52
+ */
53
+ public static function should_show() {
54
+ return false;
55
+ }
56
+ }
src/Tickets/Commerce/Gateways/Manual/Hooks.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles hooking all the actions and filters used by the module.
4
+ *
5
+ * To remove a filter:
6
+ * remove_filter( 'some_filter', [ tribe( TEC\Tickets\Commerce\Gateways\Manual\Hooks::class ), 'some_filtering_method' ] );
7
+ * remove_filter( 'some_filter', [ tribe( 'tickets.commerce.gateways.manual.hooks' ), 'some_filtering_method' ] );
8
+ *
9
+ * To remove an action:
10
+ * remove_action( 'some_action', [ tribe( TEC\Tickets\Commerce\Gateways\Manual\Hooks::class ), 'some_method' ] );
11
+ * remove_action( 'some_action', [ tribe( 'tickets.commerce.gateways.manual.hooks' ), 'some_method' ] );
12
+ *
13
+ * @since 5.2.0
14
+ *
15
+ * @package TEC\Tickets\Commerce\Gateways\Manual
16
+ */
17
+
18
+ namespace TEC\Tickets\Commerce\Gateways\Manual;
19
+
20
+ use TEC\Tickets\Commerce\Gateways\Manual\Gateway;
21
+
22
+ use Tribe__Utils__Array as Arr;
23
+
24
+
25
+ /**
26
+ * Class Hooks.
27
+ *
28
+ * @since 5.2.0
29
+ *
30
+ * @package TEC\Tickets\Commerce\Gateways\Manual
31
+ */
32
+ class Hooks extends \tad_DI52_ServiceProvider {
33
+
34
+ /**
35
+ * Binds and sets up implementations.
36
+ *
37
+ * @since 5.2.0
38
+ */
39
+ public function register() {
40
+ $this->add_actions();
41
+ $this->add_filters();
42
+ }
43
+
44
+ /**
45
+ * Adds the actions required by each Tickets Commerce component.
46
+ *
47
+ * @since 5.2.0
48
+ */
49
+ protected function add_actions() {
50
+
51
+ }
52
+
53
+ /**
54
+ * Adds the filters required by each Tickets Commerce component.
55
+ *
56
+ * @since 5.2.0
57
+ */
58
+ protected function add_filters() {
59
+ add_filter( 'tec_tickets_commerce_gateways', [ $this, 'filter_add_gateway' ], 10, 2 );
60
+ }
61
+
62
+ /**
63
+ * Add this gateway to the list of available.
64
+ *
65
+ * @since 5.2.0
66
+ *
67
+ * @param array $gateways List of available gateways.
68
+ *
69
+ * @return array
70
+ */
71
+ public function filter_add_gateway( array $gateways = [] ) {
72
+ return $this->container->make( Gateway::class )->register_gateway( $gateways );
73
+ }
74
+ }
src/Tickets/Commerce/Gateways/Manual/Order.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Gateways\Manual;
4
+
5
+ use TEC\Tickets\Commerce\Utils\Price;
6
+ use TEC\Tickets\Commerce\Order as Commerce_Order;
7
+ use Tribe__Utils__Array as Arr;
8
+
9
+ /**
10
+ * Class Order
11
+ *
12
+ * @since 5.2.0
13
+ *
14
+ * @package TEC\Tickets\Commerce\Gateways\Manual
15
+ */
16
+ class Order {
17
+ /**
18
+ * Creates a manual Order based on set of items and a purchaser.
19
+ *
20
+ * @since 5.2.0
21
+ *
22
+ * @throws \Tribe__Repository__Usage_Error
23
+ *
24
+ * @param array $items
25
+ * @param array $purchaser
26
+ *
27
+ * @return false|\WP_Post
28
+ */
29
+ public function create( $items, $purchaser = [] ) {
30
+ $order = tribe( Commerce_Order::class );
31
+ $gateway = tribe( Gateway::class );
32
+
33
+ $items = array_map(
34
+ static function ( $item ) {
35
+ $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
36
+ if ( null === $ticket ) {
37
+ return null;
38
+ }
39
+
40
+ $item['sub_total'] = Price::sub_total( $ticket->price, $item['quantity'] );
41
+ $item['price'] = $ticket->price;
42
+
43
+ return $item;
44
+ },
45
+ $items
46
+ );
47
+ $items = array_filter( $items );
48
+ $sub_totals = array_filter( wp_list_pluck( $items, 'sub_total' ) );
49
+ $total = Price::total( $sub_totals );
50
+ $hash = wp_generate_password( 12, false );
51
+
52
+ $order_args = [
53
+ 'title' => $order->generate_order_title( $items, [ 'M', $hash ] ),
54
+ 'total_value' => $total,
55
+ 'items' => $items,
56
+ 'gateway' => $gateway::get_key(),
57
+ ];
58
+
59
+ // When purchaser data-set is not passed we pull from the current user.
60
+ if ( empty( $purchaser ) && is_user_logged_in() && $user = wp_get_current_user() ) {
61
+ $order_args['purchaser_user_id'] = $user->ID;
62
+ $order_args['purchaser_full_name'] = $user->first_name . ' ' . $user->last_name;
63
+ $order_args['purchaser_first_name'] = $user->first_name;
64
+ $order_args['purchaser_last_name'] = $user->last_name;
65
+ $order_args['purchaser_email'] = $user->user_email;
66
+ } elseif ( empty( $purchaser ) ) {
67
+ $order_args['purchaser_user_id'] = 0;
68
+ $order_args['purchaser_full_name'] = Commerce_Order::$placeholder_name;
69
+ $order_args['purchaser_first_name'] = Commerce_Order::$placeholder_name;
70
+ $order_args['purchaser_last_name'] = Commerce_Order::$placeholder_name;
71
+ $order_args['purchaser_email'] = '';
72
+ } else {
73
+ $order_args['purchaser_user_id'] = Arr::get( $purchaser, 'user_id', 0 );
74
+ if ( ! empty( $purchaser['full_name'] ) ) {
75
+ $order_args['purchaser_full_name'] = Arr::get( $purchaser, 'full_name' );
76
+ }
77
+ if ( ! empty( $purchaser['first_name'] ) ) {
78
+ $order_args['purchaser_first_name'] = Arr::get( $purchaser, 'first_name' );
79
+ }
80
+ if ( ! empty( $purchaser['last_name'] ) ) {
81
+ $order_args['purchaser_last_name'] = Arr::get( $purchaser, 'last_name' );
82
+ }
83
+ if ( ! empty( $purchaser['email'] ) ) {
84
+ $order_args['purchaser_email'] = Arr::get( $purchaser, 'email' );
85
+ }
86
+ }
87
+
88
+ return $order->create( $gateway, $order_args );
89
+ }
90
+ }
src/Tickets/Commerce/Gateways/Manual/Provider.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Gateways\Manual;
4
+
5
+ /**
6
+ * Service provider for the Tickets Commerce: Manual Gateway.
7
+ *
8
+ * @since 5.2.0
9
+ * @package TEC\Tickets\Commerce\Gateways\Manual
10
+ */
11
+ class Provider extends \tad_DI52_ServiceProvider {
12
+
13
+ /**
14
+ * Register the provider singletons.
15
+ *
16
+ * @since 5.2.0
17
+ */
18
+ public function register() {
19
+ $this->container->singleton( Gateway::class );
20
+ $this->container->singleton( Order::class );
21
+
22
+ $this->register_hooks();
23
+ $this->register_assets();
24
+ }
25
+
26
+ /**
27
+ * Registers the provider handling all the 1st level filters and actions for this Service Provider
28
+ *
29
+ * @since 5.2.0
30
+ */
31
+ protected function register_assets() {
32
+ $assets = new Assets( $this->container );
33
+ $assets->register();
34
+
35
+ $this->container->singleton( Assets::class, $assets );
36
+ }
37
+
38
+ /**
39
+ * Registers the provider handling all the 1st level filters and actions for this Service Provider.
40
+ *
41
+ * @since 5.2.0
42
+ */
43
+ protected function register_hooks() {
44
+ $hooks = new Hooks( $this->container );
45
+ $hooks->register();
46
+
47
+ // Allow Hooks to be removed, by having the them registered to the container
48
+ $this->container->singleton( Hooks::class, $hooks );
49
+ }
50
+ }
src/Tickets/Commerce/Gateways/PayPal/Assets.php CHANGED
@@ -9,6 +9,7 @@
9
 
10
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
11
 
 
12
  use TEC\Tickets\Commerce\Gateways\PayPal\REST\Order_Endpoint;
13
 
14
  /**
@@ -58,7 +59,7 @@ class Assets extends \tad_DI52_ServiceProvider {
58
  esc_html__( 'Implement an SSL certificate to keep your payments secure.', 'event-tickets' ),
59
  esc_html__( 'Keep plugins up to date to ensure latest security fixes are present.', 'event-tickets' ),
60
  ],
61
- 'liveWarning' => tribe_tickets_commerce_is_test_mode()
62
  ? esc_html__( 'You have connected your account for test mode. You will need to connect again once you are in live mode.', 'event-tickets' )
63
  : '',
64
  ],
@@ -68,6 +69,17 @@ class Assets extends \tad_DI52_ServiceProvider {
68
  ]
69
  );
70
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  tribe_asset(
73
  $plugin,
@@ -76,7 +88,9 @@ class Assets extends \tad_DI52_ServiceProvider {
76
  [
77
  'jquery',
78
  'tribe-common',
 
79
  'tribe-tickets-commerce-js',
 
80
  ],
81
  null,
82
  [
@@ -89,12 +103,64 @@ class Assets extends \tad_DI52_ServiceProvider {
89
  'data' => static function () {
90
  return [
91
  'orderEndpoint' => tribe( Order_Endpoint::class )->get_route_url(),
 
 
 
 
 
 
 
 
92
  ];
93
  },
94
  ],
95
  ]
96
  );
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  }
99
 
100
  /**
@@ -123,4 +189,15 @@ class Assets extends \tad_DI52_ServiceProvider {
123
  public function should_enqueue_assets() {
124
  return tribe( Gateway::class )->is_active();
125
  }
 
 
 
 
 
 
 
 
 
 
 
126
  }
9
 
10
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
11
 
12
+ use TEC\Tickets\Commerce\Gateways\PayPal\REST\On_Boarding_Endpoint;
13
  use TEC\Tickets\Commerce\Gateways\PayPal\REST\Order_Endpoint;
14
 
15
  /**
59
  esc_html__( 'Implement an SSL certificate to keep your payments secure.', 'event-tickets' ),
60
  esc_html__( 'Keep plugins up to date to ensure latest security fixes are present.', 'event-tickets' ),
61
  ],
62
+ 'liveWarning' => tec_tickets_commerce_is_sandbox_mode()
63
  ? esc_html__( 'You have connected your account for test mode. You will need to connect again once you are in live mode.', 'event-tickets' )
64
  : '',
65
  ],
69
  ]
70
  );
71
 
72
+ /**
73
+ * This file is intentionally enqueued on every page of the administration.
74
+ */
75
+ tribe_asset(
76
+ $plugin,
77
+ 'tec-tickets-commerce-gateway-paypal-global-admin-styles',
78
+ 'tickets-commerce/gateway/paypal/admin-global.css',
79
+ [],
80
+ 'admin_enqueue_scripts',
81
+ []
82
+ );
83
 
84
  tribe_asset(
85
  $plugin,
88
  [
89
  'jquery',
90
  'tribe-common',
91
+ 'tribe-tickets-loader',
92
  'tribe-tickets-commerce-js',
93
+ 'tribe-tickets-commerce-notice-js',
94
  ],
95
  null,
96
  [
103
  'data' => static function () {
104
  return [
105
  'orderEndpoint' => tribe( Order_Endpoint::class )->get_route_url(),
106
+ 'advancedPayments' => [
107
+ 'fieldPlaceholders' => [
108
+ 'cvv' => esc_html__( 'E.g.: 123', 'event-tickets' ),
109
+ 'expirationDate' => esc_html__( 'E.g.: 03/26', 'event-tickets' ),
110
+ 'number' => esc_html__( 'E.g.: 4111 1111 1111 1111', 'event-tickets' ),
111
+ 'zipCode' => esc_html__( 'E.g.: 01020', 'event-tickets' ),
112
+ ]
113
+ ],
114
  ];
115
  },
116
  ],
117
  ]
118
  );
119
 
120
+ tribe_asset(
121
+ $plugin,
122
+ 'tec-tickets-commerce-gateway-paypal-signup',
123
+ 'commerce/gateway/paypal/signup.js',
124
+ [
125
+ 'jquery',
126
+ 'tribe-common',
127
+ 'tribe-tickets-commerce-js',
128
+ ],
129
+ 'admin_enqueue_scripts',
130
+ [
131
+ 'conditionals' => [ $this, 'should_enqueue_assets_payments_tab' ],
132
+ 'localize' => [
133
+ 'name' => 'tecTicketsCommerceGatewayPayPalSignup',
134
+ 'data' => static function () {
135
+ return [
136
+ 'onboardNonce' => wp_create_nonce( 'tec-tc-on-boarded' ),
137
+ 'refreshConnectNonce' => wp_create_nonce( 'tec-tickets-commerce-gateway-paypal-refresh-connect-url' ),
138
+ 'onboardingEndpointUrl' => tribe( On_Boarding_Endpoint::class )->get_route_url(),
139
+ ];
140
+ },
141
+ ],
142
+ ]
143
+ );
144
+
145
+ // Tickets Commerce PayPal main frontend styles.
146
+ tribe_asset(
147
+ $plugin,
148
+ 'tribe-tickets-commerce-paypal-style',
149
+ 'tickets-commerce/gateway/paypal.css',
150
+ [
151
+ 'tribe-common-skeleton-style',
152
+ 'tribe-common-full-style',
153
+ ],
154
+ null,
155
+ [
156
+ 'groups' => [
157
+ 'tribe-tickets-commerce',
158
+ 'tribe-tickets-commerce-checkout',
159
+ ],
160
+ 'print' => true,
161
+ ]
162
+ );
163
+
164
  }
165
 
166
  /**
189
  public function should_enqueue_assets() {
190
  return tribe( Gateway::class )->is_active();
191
  }
192
+
193
+ /**
194
+ * Define if the assets for `PayPal` should be enqueued or not.
195
+ *
196
+ * @since 5.1.10
197
+ *
198
+ * @return bool If the `PayPal` assets should be enqueued or not.
199
+ */
200
+ public function should_enqueue_assets_payments_tab() {
201
+ return 'payments' === tribe_get_request_var( 'tab' ) && \Tribe__Settings::instance()->adminSlug === tribe_get_request_var( 'page' );
202
+ }
203
  }
src/Tickets/Commerce/Gateways/PayPal/Buttons.php CHANGED
@@ -4,6 +4,7 @@ namespace TEC\Tickets\Commerce\Gateways\PayPal;
4
 
5
  use Tribe__Utils__Array as Arr;
6
  use TEC\Tickets\Commerce\Module;
 
7
 
8
  /**
9
  * Class Buttons
@@ -55,21 +56,82 @@ class Buttons {
55
  return;
56
  }
57
 
58
- $client = tribe( Client::class );
59
- $client_token_data = $client->get_client_token();
60
- $must_login = ! is_user_logged_in() && tribe( Module::class )->login_required();
61
- $template_vars = [
62
- 'url' => $client->get_js_sdk_url(),
63
- 'attribution_id' => Gateway::ATTRIBUTION_ID,
64
- 'client_token' => Arr::get( $client_token_data, 'client_token' ),
65
- 'client_token_expires_in' => Arr::get( $client_token_data, 'expires_in' ),
66
- 'must_login' => $must_login,
 
 
 
 
67
  ];
68
 
 
 
 
 
 
 
 
 
69
  $html = $this->get_template()->template( 'checkout-script', $template_vars, false );
70
 
71
  tribe_asset_enqueue( 'tec-tickets-commerce-gateway-paypal-checkout' );
72
 
73
  return $html;
74
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  }
4
 
5
  use Tribe__Utils__Array as Arr;
6
  use TEC\Tickets\Commerce\Module;
7
+ use TEC\Tickets\Commerce\Cart;
8
 
9
  /**
10
  * Class Buttons
56
  return;
57
  }
58
 
59
+ $items = tribe( Cart::class )->get_items_in_cart( true );
60
+
61
+ // Bail if there are no tickets in cart.
62
+ if ( empty( $items ) ) {
63
+ return;
64
+ }
65
+
66
+ $client = tribe( Client::class );
67
+ $must_login = ! is_user_logged_in() && tribe( Module::class )->login_required();
68
+ $template_vars = [
69
+ 'url' => $client->get_js_sdk_url(),
70
+ 'attribution_id' => Gateway::ATTRIBUTION_ID,
71
+ 'must_login' => $must_login,
72
  ];
73
 
74
+ $client_token_data = $client->get_client_token();
75
+ $client_token = Arr::get( $client_token_data, 'client_token' );
76
+ $client_token_expires_in = Arr::get( $client_token_data, 'expires_in' );
77
+ if ( ! empty( $client_token ) && ! empty( $client_token_expires_in ) ) {
78
+ $template_vars['client_token'] = $client_token;
79
+ $template_vars['client_token_expires_in'] = $client_token_expires_in - 60;
80
+ }
81
+
82
  $html = $this->get_template()->template( 'checkout-script', $template_vars, false );
83
 
84
  tribe_asset_enqueue( 'tec-tickets-commerce-gateway-paypal-checkout' );
85
 
86
  return $html;
87
  }
88
+
89
+
90
+ /**
91
+ * Include the payment buttons from PayPal into the Checkout page.
92
+ *
93
+ * @since 5.2.0
94
+ *
95
+ * @param string $file Which file we are loading.
96
+ * @param string $name Name of file file
97
+ * @param \Tribe__Template $template Which Template object is being used.
98
+ *
99
+ */
100
+ public function include_payment_buttons( $file, $name, $template ) {
101
+ $must_login = ! is_user_logged_in() && tribe( Module::class )->login_required();
102
+
103
+ $template->template( 'gateway/paypal/buttons', [ 'must_login' => $must_login ] );
104
+ }
105
+
106
+
107
+ /**
108
+ * Include the advanced payment fields from PayPal into the Checkout page.
109
+ *
110
+ * @since 5.2.0
111
+ *
112
+ * @param string $file Which file we are loading.
113
+ * @param string $name Name of file file
114
+ * @param \Tribe__Template $template Which Template object is being used.
115
+ *
116
+ */
117
+ public function include_advanced_payments( $file, $name, $template ) {
118
+ $items = tribe( Cart::class )->get_items_in_cart( true );
119
+
120
+ // Bail if there are no tickets in cart.
121
+ if ( empty( $items ) ) {
122
+ return;
123
+ }
124
+
125
+ $must_login = ! is_user_logged_in() && tribe( Module::class )->login_required();
126
+ $merchant = tribe( Merchant::class );
127
+
128
+ $template->template(
129
+ 'gateway/paypal/advanced-payments',
130
+ [
131
+ 'supports_custom_payments' => $merchant->get_supports_custom_payments(),
132
+ 'active_custom_payments' => $merchant->get_active_custom_payments(),
133
+ 'must_login' => $must_login,
134
+ ]
135
+ );
136
+ }
137
  }
src/Tickets/Commerce/Gateways/PayPal/Client.php CHANGED
@@ -14,6 +14,15 @@ use Tribe__Utils__Array as Arr;
14
  *
15
  */
16
  class Client {
 
 
 
 
 
 
 
 
 
17
  /**
18
  * Get environment base URL.
19
  *
@@ -64,6 +73,8 @@ class Client {
64
  *
65
  * We use something like: https://www.paypal.com/sdk/js?client-id=sb&locale=en_US&components=buttons
66
  *
 
 
67
  * @since 5.1.9
68
  *
69
  * @param array $query_args Which query args will be added.
@@ -74,11 +85,13 @@ class Client {
74
  $url = 'https://www.paypal.com/sdk/js';
75
  $merchant = tribe( Merchant::class );
76
  $query_args = array_merge( [
77
- 'client-id' => $merchant->is_sandbox() ? 'sb' : $merchant->get_client_id(),
78
- 'merchant-id' => $merchant->get_merchant_id_in_paypal(),
79
- 'components' => 'buttons,hosted-fields',
80
- 'intent' => 'capture',
81
- 'currency' => tribe_get_option( \TEC\Tickets\Commerce\Settings::$option_currency_code, 'USD' ),
 
 
82
  ], $query_args );
83
  $url = add_query_arg( $query_args, $url );
84
 
@@ -109,24 +122,49 @@ class Client {
109
  );
110
  }
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  /**
113
  * Send a given method request to a given URL in the PayPal API.
114
  *
115
  * @since 5.1.10
 
116
  *
117
  * @param string $method
118
  * @param string $url
119
  * @param array $query_args
120
  * @param array $request_arguments
121
  * @param bool $raw
 
122
  *
123
  * @return array|\WP_Error
124
  */
125
- public function request( $method, $url, array $query_args = [], array $request_arguments = [], $raw = false ) {
126
  $method = strtoupper( $method );
127
 
128
  // If the endpoint passed is a full URL don't try to append anything.
129
- $url = 0 !== strpos( 'https://', $url )
130
  ? $this->get_api_url( $url, $query_args )
131
  : add_query_arg( $query_args, $url );
132
 
@@ -189,15 +227,42 @@ class Client {
189
 
190
  $response_code = wp_remote_retrieve_response_code( $response );
191
 
192
- // When we receive an error code we return the whole response.
193
- if ( ! in_array( $response_code, [ 200, 201, 202, 204 ], true ) ) {
194
- return $response;
 
195
  }
196
 
197
- $response = wp_remote_retrieve_body( $response );
198
- $response = @json_decode( $response, true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
- if ( ! is_array( $response ) ) {
201
  tribe( 'logger' )->log_error( sprintf( '[%s] Unexpected PayPal %s response', $url, $method ), 'tickets-commerce-paypal' );
202
 
203
  return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-client-unexpected', null, [
@@ -209,7 +274,7 @@ class Client {
209
  ] );
210
  }
211
 
212
- return $response;
213
  }
214
 
215
  /**
@@ -345,12 +410,7 @@ class Client {
345
  public function get_client_token() {
346
  $query_args = [];
347
  $args = [
348
- 'headers' => [
349
- 'Accept' => 'application/json',
350
- 'Accept-Language' => 'en_US',
351
- 'Authorization' => sprintf( 'Bearer %1$s', $this->get_access_token() ),
352
- 'Content-Type' => 'application/json',
353
- ],
354
  'body' => [],
355
  ];
356
 
@@ -422,18 +482,21 @@ class Client {
422
  'surname' => Arr::get( $unit, 'last_name' ),
423
  ],
424
  'email_address' => Arr::get( $unit, 'email' ),
425
-
426
  ],
427
  'payment_instruction' => [
428
  'disbursement_mode' => Arr::get( $unit, 'disbursement_mode', 'INSTANT' ),
429
  ],
430
  ];
431
 
432
- /**
433
- * @todo Need to figure out how to get this email address still.
434
- */
435
- if ( ! $merchant->is_sandbox() ) {
436
- $purchase_unit['payee']['email_address'] = Arr::get( $unit, 'merchant_id', $merchant->get_merchant_id() );
 
 
 
 
437
  }
438
 
439
  if ( ! empty( $unit['tax_id'] ) ) {
@@ -484,7 +547,13 @@ class Client {
484
  $body['payerID'] = $payer_id;
485
  }
486
 
487
- $args = [
 
 
 
 
 
 
488
  'headers' => [
489
  'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
490
  'Prefer' => 'return=representation',
@@ -720,20 +789,22 @@ class Client {
720
  if ( ! $response || empty( $response['id'] ) ) {
721
  $error = @json_decode( $response['body'], true );
722
  if ( empty( $error['name'] ) ) {
723
- tribe( 'logger' )->log_error( __( 'Unexpected PayPal response when creating webhook', 'event-tickets' ), 'tickets-commerce-gateway-paypal' );
 
724
 
725
- return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-unexpected', null, $response );
726
  }
727
 
728
  if ( 'WEBHOOK_URL_ALREADY_EXISTS' === $error['name'] ) {
729
- return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-url-already-exists', null, $response );
730
  }
731
 
732
  if ( 'WEBHOOK_NUMBER_LIMIT_EXCEEDED' === $error['name'] ) {
 
733
  // Limit has been reached, we cannot just delete all webhooks without permission.
734
- tribe( 'logger' )->log_error( __( 'PayPal webhook limit has been reached, you need to go into your developer.paypal.com account and remove webhooks from the associated account', 'event-tickets' ), 'tickets-commerce-gateway-paypal' );
735
 
736
- return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-limit-exceeded', null, $response );
737
  }
738
  }
739
 
@@ -788,13 +859,14 @@ class Client {
788
  if ( ! $response || empty( $response['id'] ) ) {
789
  $error = @json_decode( $response['body'], true );
790
  if ( empty( $error['name'] ) ) {
791
- tribe( 'logger' )->log_error( __( 'Unexpected PayPal response when updating webhook', 'event-tickets' ), 'tickets-commerce-gateway-paypal' );
 
792
 
793
- return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-update-unexpected' );
794
  }
795
 
796
  if ( 'INVALID_RESOURCE_ID' === $error['name'] ) {
797
- return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-update-invalid-id' );
798
  }
799
  }
800
 
14
  *
15
  */
16
  class Client {
17
+ /**
18
+ * Debug ID from PayPal.
19
+ *
20
+ * @since 5.2.0
21
+ *
22
+ * @var string
23
+ */
24
+ protected $debug_header;
25
+
26
  /**
27
  * Get environment base URL.
28
  *
73
  *
74
  * We use something like: https://www.paypal.com/sdk/js?client-id=sb&locale=en_US&components=buttons
75
  *
76
+ * @link https://developer.paypal.com/docs/checkout/reference/customize-sdk/#query-parameters
77
+ *
78
  * @since 5.1.9
79
  *
80
  * @param array $query_args Which query args will be added.
85
  $url = 'https://www.paypal.com/sdk/js';
86
  $merchant = tribe( Merchant::class );
87
  $query_args = array_merge( [
88
+ 'client-id' => $merchant->get_client_id(),
89
+ 'merchant-id' => $merchant->get_merchant_id_in_paypal(),
90
+ 'components' => 'hosted-fields,buttons',
91
+ 'intent' => 'capture',
92
+ 'locale' => $merchant->get_locale(),
93
+ 'disable-funding' => 'credit',
94
+ 'currency' => tribe_get_option( \TEC\Tickets\Commerce\Settings::$option_currency_code, 'USD' ),
95
  ], $query_args );
96
  $url = add_query_arg( $query_args, $url );
97
 
122
  );
123
  }
124
 
125
+ /**
126
+ * Stores the debug header from a given PayPal request, which allows for us to store it with the gateway payload.
127
+ *
128
+ * @since 5.2.0
129
+ *
130
+ * @param string $id Which ID we are storing.
131
+ *
132
+ */
133
+ protected function set_debug_header( $id ) {
134
+ $this->debug_header = $id;
135
+ }
136
+
137
+ /**
138
+ * Fetches the last stored debug id from PayPal.
139
+ *
140
+ * @since 5.2.0
141
+ *
142
+ * @return string|null
143
+ */
144
+ public function get_debug_header() {
145
+ return $this->debug_header;
146
+ }
147
+
148
  /**
149
  * Send a given method request to a given URL in the PayPal API.
150
  *
151
  * @since 5.1.10
152
+ * @since 5.2.0 Included $retries param.
153
  *
154
  * @param string $method
155
  * @param string $url
156
  * @param array $query_args
157
  * @param array $request_arguments
158
  * @param bool $raw
159
+ * @param int $retries Param used to determine the amount of time this particular request was retried.
160
  *
161
  * @return array|\WP_Error
162
  */
163
+ public function request( $method, $url, array $query_args = [], array $request_arguments = [], $raw = false, $retries = 0 ) {
164
  $method = strtoupper( $method );
165
 
166
  // If the endpoint passed is a full URL don't try to append anything.
167
+ $url = 0 !== strpos( $url, 'https://' )
168
  ? $this->get_api_url( $url, $query_args )
169
  : add_query_arg( $query_args, $url );
170
 
227
 
228
  $response_code = wp_remote_retrieve_response_code( $response );
229
 
230
+ // If the debug header was set we pass it or reset it.
231
+ $this->set_debug_header( null );
232
+ if ( ! empty( $response['headers']['Paypal-Debug-Id'] ) ) {
233
+ $this->set_debug_header( $response['headers']['Paypal-Debug-Id'] );
234
  }
235
 
236
+ // When we get specifically a 401 and we are not trying to generate a token we try once more.
237
+ if (
238
+ 401 === $response_code
239
+ && 2 >= $retries
240
+ && false === strpos( $url, 'v1/oauth2/token' )
241
+ ) {
242
+ $merchant = tribe( Merchant::class );
243
+ $token_data = $this->get_access_token_from_client_credentials( $merchant->get_client_id(), $merchant->get_client_secret() );
244
+ $saved = $merchant->save_access_token_data( $token_data );
245
+
246
+ // If we properly saved, just re-try the request.
247
+ if ( $saved ) {
248
+ $arguments = func_get_args();
249
+ array_pop( $arguments );
250
+ $arguments[] = $retries + 1;
251
+
252
+ return call_user_func_array( [ $this, 'request' ], $arguments );
253
+ }
254
+ }
255
+
256
+ /**
257
+ * @todo we need to log and be more verbose about the responses. Specially around failed JSON strings.
258
+ */
259
+ $response_body = wp_remote_retrieve_body( $response );
260
+ $response_body = @json_decode( $response_body, true );
261
+ if ( empty( $response_body ) ) {
262
+ return $response;
263
+ }
264
 
265
+ if ( ! is_array( $response_body ) ) {
266
  tribe( 'logger' )->log_error( sprintf( '[%s] Unexpected PayPal %s response', $url, $method ), 'tickets-commerce-paypal' );
267
 
268
  return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-client-unexpected', null, [
274
  ] );
275
  }
276
 
277
+ return $response_body;
278
  }
279
 
280
  /**
410
  public function get_client_token() {
411
  $query_args = [];
412
  $args = [
413
+ 'headers' => [],
 
 
 
 
 
414
  'body' => [],
415
  ];
416
 
482
  'surname' => Arr::get( $unit, 'last_name' ),
483
  ],
484
  'email_address' => Arr::get( $unit, 'email' ),
 
485
  ],
486
  'payment_instruction' => [
487
  'disbursement_mode' => Arr::get( $unit, 'disbursement_mode', 'INSTANT' ),
488
  ],
489
  ];
490
 
491
+ $items = Arr::get( $unit, 'items' );
492
+ if ( ! empty( $items ) ) {
493
+ $purchase_unit['items'] = $items;
494
+ $purchase_unit['amount']['breakdown'] = [
495
+ 'item_total' => [
496
+ 'value' => Arr::get( $unit, 'value' ),
497
+ 'currency_code' => Arr::get( $unit, 'currency' ),
498
+ ],
499
+ ];
500
  }
501
 
502
  if ( ! empty( $unit['tax_id'] ) ) {
547
  $body['payerID'] = $payer_id;
548
  }
549
 
550
+ /**
551
+ * If we need to handle failures.
552
+ *
553
+ * @link https://developer.paypal.com/docs/platforms/checkout/add-capabilities/handle-funding-failures/
554
+ * 'PayPal-Mock-Response' => '{"mock_application_codes" : "INSTRUMENT_DECLINED"}',
555
+ */
556
+ $args = [
557
  'headers' => [
558
  'PayPal-Partner-Attribution-Id' => Gateway::ATTRIBUTION_ID,
559
  'Prefer' => 'return=representation',
789
  if ( ! $response || empty( $response['id'] ) ) {
790
  $error = @json_decode( $response['body'], true );
791
  if ( empty( $error['name'] ) ) {
792
+ $message = __( 'Unexpected PayPal response when creating webhook', 'event-tickets' );
793
+ tribe( 'logger' )->log_error( $message, 'tickets-commerce-gateway-paypal' );
794
 
795
+ return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-unexpected', $message, $response );
796
  }
797
 
798
  if ( 'WEBHOOK_URL_ALREADY_EXISTS' === $error['name'] ) {
799
+ return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-url-already-exists', $error['message'], $response );
800
  }
801
 
802
  if ( 'WEBHOOK_NUMBER_LIMIT_EXCEEDED' === $error['name'] ) {
803
+ $message = __( 'PayPal webhook limit has been reached, you need to go into your developer.paypal.com account and remove webhooks from the associated account', 'event-tickets' );
804
  // Limit has been reached, we cannot just delete all webhooks without permission.
805
+ tribe( 'logger' )->log_error( $message, 'tickets-commerce-gateway-paypal' );
806
 
807
+ return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-limit-exceeded', $message, $response );
808
  }
809
  }
810
 
859
  if ( ! $response || empty( $response['id'] ) ) {
860
  $error = @json_decode( $response['body'], true );
861
  if ( empty( $error['name'] ) ) {
862
+ $message = __( 'Unexpected PayPal response when updating webhook', 'event-tickets' );
863
+ tribe( 'logger' )->log_error( $message, 'tickets-commerce-gateway-paypal' );
864
 
865
+ return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-update-unexpected', $message );
866
  }
867
 
868
  if ( 'INVALID_RESOURCE_ID' === $error['name'] ) {
869
+ return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-update-invalid-id', $error['message'] );
870
  }
871
  }
872
 
src/Tickets/Commerce/Gateways/PayPal/Gateway.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
4
 
5
  use TEC\Tickets\Commerce\Gateways\Abstract_Gateway;
 
6
 
7
  /**
8
  * Class Gateway
@@ -40,7 +41,19 @@ class Gateway extends Abstract_Gateway {
40
  * @inheritDoc
41
  */
42
  public static function get_label() {
43
- return __( 'PayPal Commerce', 'event-tickets' );
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
 
46
  /**
@@ -76,4 +89,94 @@ class Gateway extends Abstract_Gateway {
76
  public static function is_test_mode() {
77
  return tribe_is_truthy( tribe_get_option( \TEC\Tickets\Commerce\Settings::$option_sandbox ) );
78
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
3
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
4
 
5
  use TEC\Tickets\Commerce\Gateways\Abstract_Gateway;
6
+ use TEC\Tickets\Commerce\Notice_Handler;
7
 
8
  /**
9
  * Class Gateway
41
  * @inheritDoc
42
  */
43
  public static function get_label() {
44
+ return __( 'PayPal', 'event-tickets' );
45
+ }
46
+
47
+ /**
48
+ * @inheritDoc
49
+ */
50
+ public static function is_connected() {
51
+ // If this gateway shouldn't be shown, then don't change the active status.
52
+ if ( ! static::should_show() ) {
53
+ return false;
54
+ }
55
+
56
+ return tribe( Merchant::class )->is_connected();
57
  }
58
 
59
  /**
89
  public static function is_test_mode() {
90
  return tribe_is_truthy( tribe_get_option( \TEC\Tickets\Commerce\Settings::$option_sandbox ) );
91
  }
92
+
93
+ /**
94
+ * Get all the admin notices.
95
+ *
96
+ * @since 5.2.0.
97
+ *
98
+ * @return array
99
+ */
100
+ public function get_admin_notices() {
101
+ $notices = [
102
+ [
103
+ 'slug' => 'tc-paypal-signup-complete',
104
+ 'content' => __( 'PayPal is now connected.', 'event-tickets' ),
105
+ 'type' => 'info',
106
+ ],
107
+ [
108
+ 'slug' => 'tc-paypal-disconnect-failed',
109
+ 'content' => __( 'Failed to disconnect PayPal account.', 'event-tickets' ),
110
+ 'type' => 'error',
111
+ ],
112
+ [
113
+ 'slug' => 'tc-paypal-disconnected',
114
+ 'content' => __( 'Disconnected PayPal account.', 'event-tickets' ),
115
+ 'type' => 'info',
116
+ ],
117
+ [
118
+ 'slug' => 'tc-paypal-refresh-token-failed',
119
+ 'content' => __( 'Failed to refresh PayPal access token.', 'event-tickets' ),
120
+ 'type' => 'error',
121
+ ],
122
+ [
123
+ 'slug' => 'tc-paypal-refresh-token',
124
+ 'content' => __( 'PayPal access token was refreshed successfully.', 'event-tickets' ),
125
+ 'type' => 'info',
126
+ ],
127
+ [
128
+ 'slug' => 'tc-paypal-refresh-user-info-failed',
129
+ 'content' => __( 'Failed to refresh PayPal user info.', 'event-tickets' ),
130
+ 'type' => 'error',
131
+ ],
132
+ [
133
+ 'slug' => 'tc-paypal-refresh-user-info',
134
+ 'content' => __( 'PayPal user info was refreshed successfully.', 'event-tickets' ),
135
+ 'type' => 'info',
136
+ ],
137
+ [
138
+ 'slug' => 'tc-paypal-refresh-webhook-failed',
139
+ 'content' => __( 'Failed to refresh PayPal webhooks.', 'event-tickets' ),
140
+ 'type' => 'error',
141
+ ],
142
+ [
143
+ 'slug' => 'tc-paypal-refresh-webhook-success',
144
+ 'content' => __( 'PayPal webhooks refreshed successfully.', 'event-tickets' ),
145
+ 'type' => 'info',
146
+ ],
147
+ [
148
+ 'slug' => 'tc-paypal-ssl-not-available',
149
+ 'content' => __( 'A valid SSL certificate is required to set up your PayPal account and accept payments', 'event-tickets' ),
150
+ 'type' => 'error',
151
+ ],
152
+ ];
153
+
154
+ return $notices;
155
+ }
156
+
157
+ /**
158
+ * Displays error notice for invalid API responses, with error message from API response data.
159
+ *
160
+ * @since 5.2.0
161
+ *
162
+ * @param array $response Raw Response data.
163
+ * @param string $message Additional message to show with error message.
164
+ * @param string $slug Slug for notice container.
165
+ */
166
+ public function handle_invalid_response( $response, $message, $slug = 'error' ) {
167
+
168
+ $notices = tribe( Notice_Handler::class );
169
+ $body = (array) json_decode( wp_remote_retrieve_body( $response ) );
170
+
171
+ $error = isset( $body['error'] ) ? $body['error'] : __( 'Something went wrong!' , 'event-tickets' );
172
+ $error_message = isset( $body['error_description'] ) ? $body['error_description'] : __( 'Unexpected response recieved.' , 'event-tickets' );
173
+
174
+ $notices->trigger_admin(
175
+ $slug,
176
+ [
177
+ 'content' => sprintf( 'Error - %s : %s - %s', $error, $error_message, $message ),
178
+ 'type' => 'error',
179
+ ]
180
+ );
181
+ }
182
  }
src/Tickets/Commerce/Gateways/PayPal/Hooks.php CHANGED
@@ -18,7 +18,14 @@
18
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
19
 
20
  use TEC\Tickets\Commerce\Module;
 
 
21
  use TEC\Tickets\Commerce\Shortcodes\Shortcode_Abstract;
 
 
 
 
 
22
 
23
  /**
24
  * Class Hooks.
@@ -51,12 +58,18 @@ class Hooks extends \tad_DI52_ServiceProvider {
51
  add_action( 'tec_tickets_commerce_admin_process_action:paypal-refresh-access-token', [ $this, 'handle_action_refresh_token' ] );
52
  add_action( 'tec_tickets_commerce_admin_process_action:paypal-refresh-user-info', [ $this, 'handle_action_refresh_user_info' ] );
53
  add_action( 'tec_tickets_commerce_admin_process_action:paypal-refresh-webhook', [ $this, 'handle_action_refresh_webhook' ] );
 
54
 
55
- add_action( 'tribe_template_before_include:tickets/v2/commerce/checkout/header', [ $this, 'include_client_js_sdk_script' ], 15, 3 );
56
  add_action( 'tribe_template_after_include:tickets/v2/commerce/checkout/footer', [ $this, 'include_payment_buttons' ], 15, 3 );
 
 
 
 
 
 
57
  }
58
 
59
- /**1
60
  * Adds the filters required by each Tickets Commerce component.
61
  *
62
  * @since 5.1.6
@@ -65,6 +78,20 @@ class Hooks extends \tad_DI52_ServiceProvider {
65
  add_filter( 'tec_tickets_commerce_gateways', [ $this, 'filter_add_gateway' ], 10, 2 );
66
  add_filter( 'tec_tickets_commerce_success_shortcode_checkout_page_paypal_template_vars', [ $this, 'include_checkout_page_vars' ], 10, 2 );
67
  add_filter( 'tec_tickets_commerce_success_shortcode_success_page_paypal_template_vars', [ $this, 'include_success_page_vars' ], 10, 2 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  }
69
 
70
  /**
@@ -114,69 +141,141 @@ class Hooks extends \tad_DI52_ServiceProvider {
114
  }
115
 
116
  /**
117
- * Include the Client JS SDK script into checkout.
118
  *
119
  * @since 5.1.9
120
  *
121
  * @param string $file Which file we are loading.
122
  * @param string $name Name of file file
123
  * @param \Tribe__Template $template Which Template object is being used.
124
- *
125
  */
126
  public function include_payment_buttons( $file, $name, $template ) {
127
- $must_login = ! is_user_logged_in() && tribe( Module::class )->login_required();
 
128
 
129
- $template->template( 'gateway/paypal/buttons', [ 'must_login' => $must_login ] );
 
 
 
 
 
 
 
 
 
 
130
  }
131
 
132
  /**
133
  * Handles the disconnecting of the merchant.
134
  *
135
- * @todo Display some message when disconnecting.
136
  * @since 5.1.9
137
  *
 
138
  */
139
  public function handle_action_disconnect() {
140
- $this->container->make( Merchant::class )->disconnect();
 
 
 
 
 
 
 
 
 
141
  }
142
 
143
  /**
144
  * Handles the refreshing of the token from PayPal for this merchant.
145
  *
146
- * @todo Display some message when refreshing token.
147
  * @since 5.1.9
148
- *
149
  */
150
  public function handle_action_refresh_token() {
151
  $merchant = $this->container->make( Merchant::class );
152
  $token_data = $this->container->make( Client::class )->get_access_token_from_client_credentials( $merchant->get_client_id(), $merchant->get_client_secret() );
 
 
 
 
 
 
 
 
 
153
 
154
  $saved = $merchant->save_access_token_data( $token_data );
 
 
 
 
 
 
 
 
155
  }
156
 
157
  /**
158
  * Handles the refreshing of the user info from PayPal for this merchant.
159
  *
160
- * @todo Display some message when refreshing user info.
161
  * @since 5.1.9
162
  *
163
  */
164
  public function handle_action_refresh_user_info() {
165
  $merchant = $this->container->make( Merchant::class );
166
  $user_info = $this->container->make( Client::class )->get_user_info();
 
167
 
168
- $saved = $merchant->save_user_info( $user_info );
 
 
 
 
 
 
 
 
 
 
169
  }
170
 
171
  /**
172
  * Handles the refreshing of the webhook on PayPal for this site/merchant.
173
  *
174
- * @todo Display some message when refreshing user info.
175
  * @since 5.1.10
176
  *
 
177
  */
178
  public function handle_action_refresh_webhook() {
179
  $updated = $this->container->make( Webhooks::class )->create_or_update_existing();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  }
181
 
182
  /**
@@ -200,4 +299,74 @@ class Hooks extends \tad_DI52_ServiceProvider {
200
  public function filter_add_gateway( array $gateways = [] ) {
201
  return $this->container->make( Gateway::class )->register_gateway( $gateways );
202
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  }
18
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
19
 
20
  use TEC\Tickets\Commerce\Module;
21
+ use TEC\Tickets\Commerce\Notice_Handler;
22
+ use TEC\Tickets\Commerce\Settings;
23
  use TEC\Tickets\Commerce\Shortcodes\Shortcode_Abstract;
24
+ use TEC\Tickets\Commerce\Gateways\PayPal\Gateway;
25
+ use TEC\Tickets\Commerce\Status\Completed;
26
+
27
+ use Tribe__Utils__Array as Arr;
28
+
29
 
30
  /**
31
  * Class Hooks.
58
  add_action( 'tec_tickets_commerce_admin_process_action:paypal-refresh-access-token', [ $this, 'handle_action_refresh_token' ] );
59
  add_action( 'tec_tickets_commerce_admin_process_action:paypal-refresh-user-info', [ $this, 'handle_action_refresh_user_info' ] );
60
  add_action( 'tec_tickets_commerce_admin_process_action:paypal-refresh-webhook', [ $this, 'handle_action_refresh_webhook' ] );
61
+ add_action( 'tec_tickets_commerce_admin_process_action:paypal-resync-connection', [ $this, 'handle_action_refresh_connection' ] );
62
 
 
63
  add_action( 'tribe_template_after_include:tickets/v2/commerce/checkout/footer', [ $this, 'include_payment_buttons' ], 15, 3 );
64
+ add_action( 'tribe_template_after_include:tickets/v2/commerce/checkout/footer', [ $this, 'include_advanced_payments' ], 20, 3 );
65
+ add_action( 'tribe_template_after_include:tickets/v2/commerce/checkout/footer', [ $this, 'include_client_js_sdk_script' ], 30, 3 );
66
+ add_action( 'wp_ajax_tec_tickets_commerce_gateway_paypal_refresh_connect_url', [ $this, 'ajax_refresh_connect_url' ] );
67
+ add_action( 'admin_init', [ $this, 'render_ssl_notice' ] );
68
+
69
+ add_action( 'tribe_template_after_include:tickets/v2/commerce/order/details/order-number', [ $this, 'include_capture_id_success_page' ], 10, 3 );
70
  }
71
 
72
+ /**
73
  * Adds the filters required by each Tickets Commerce component.
74
  *
75
  * @since 5.1.6
78
  add_filter( 'tec_tickets_commerce_gateways', [ $this, 'filter_add_gateway' ], 10, 2 );
79
  add_filter( 'tec_tickets_commerce_success_shortcode_checkout_page_paypal_template_vars', [ $this, 'include_checkout_page_vars' ], 10, 2 );
80
  add_filter( 'tec_tickets_commerce_success_shortcode_success_page_paypal_template_vars', [ $this, 'include_success_page_vars' ], 10, 2 );
81
+ add_filter( 'tec_tickets_commerce_notice_messages', [ $this, 'include_admin_notices' ] );
82
+ add_filter( 'tribe-events-save-options', [ $this, 'flush_transients_when_toggling_sandbox_mode' ] );
83
+ }
84
+
85
+ /**
86
+ * Resolve the refresh of the URL when the coutry changes.
87
+ *
88
+ * @since 5.2.0
89
+ *
90
+ *
91
+ * @return false|string
92
+ */
93
+ public function ajax_refresh_connect_url() {
94
+ return $this->container->make( Signup::class )->ajax_refresh_connect_url();
95
  }
96
 
97
  /**
141
  }
142
 
143
  /**
144
+ * Include the payment buttons from PayPal into the Checkout page.
145
  *
146
  * @since 5.1.9
147
  *
148
  * @param string $file Which file we are loading.
149
  * @param string $name Name of file file
150
  * @param \Tribe__Template $template Which Template object is being used.
 
151
  */
152
  public function include_payment_buttons( $file, $name, $template ) {
153
+ $this->container->make( Buttons::class )->include_payment_buttons( $file, $name, $template );
154
+ }
155
 
156
+ /**
157
+ * Include the advanced payment fields from PayPal in the Checkout page.
158
+ *
159
+ * @since 5.2.0
160
+ *
161
+ * @param string $file Which file we are loading.
162
+ * @param string $name Name of file file
163
+ * @param \Tribe__Template $template Which Template object is being used.
164
+ */
165
+ public function include_advanced_payments( $file, $name, $template ) {
166
+ $this->container->make( Buttons::class )->include_advanced_payments( $file, $name, $template );
167
  }
168
 
169
  /**
170
  * Handles the disconnecting of the merchant.
171
  *
 
172
  * @since 5.1.9
173
  *
174
+ * @since 5.2.0 Display info on disconnect.
175
  */
176
  public function handle_action_disconnect() {
177
+ $disconnected = $this->container->make( Merchant::class )->disconnect();
178
+ $notices = $this->container->make( Notice_Handler::class );
179
+
180
+ if ( ! $disconnected ) {
181
+ $notices->trigger_admin( 'tc-paypal-disconnect-failed' );
182
+
183
+ return;
184
+ }
185
+
186
+ $notices->trigger_admin( 'tc-paypal-disconnected' );
187
  }
188
 
189
  /**
190
  * Handles the refreshing of the token from PayPal for this merchant.
191
  *
 
192
  * @since 5.1.9
 
193
  */
194
  public function handle_action_refresh_token() {
195
  $merchant = $this->container->make( Merchant::class );
196
  $token_data = $this->container->make( Client::class )->get_access_token_from_client_credentials( $merchant->get_client_id(), $merchant->get_client_secret() );
197
+ $notices = $this->container->make( Notice_Handler::class );
198
+
199
+ // Check if API response is valid for token data.
200
+ if ( ! is_array( $token_data ) || ! isset( $token_data['access_token'] ) ) {
201
+ $message = $notices->get_message_data( 'tc-paypal-refresh-token-failed' );
202
+ $this->container->make( Gateway::class )->handle_invalid_response( $token_data, $message['content'] );
203
+
204
+ return;
205
+ }
206
 
207
  $saved = $merchant->save_access_token_data( $token_data );
208
+
209
+ if ( ! $saved ) {
210
+ $notices->trigger_admin( 'tc-paypal-refresh-token-failed' );
211
+
212
+ return;
213
+ }
214
+
215
+ $notices->trigger_admin( 'tc-paypal-refresh-token' );
216
  }
217
 
218
  /**
219
  * Handles the refreshing of the user info from PayPal for this merchant.
220
  *
 
221
  * @since 5.1.9
222
  *
223
  */
224
  public function handle_action_refresh_user_info() {
225
  $merchant = $this->container->make( Merchant::class );
226
  $user_info = $this->container->make( Client::class )->get_user_info();
227
+ $notices = $this->container->make( Notice_Handler::class );
228
 
229
+ // Check if API response is valid for user info.
230
+ if ( ! isset( $user_info['user_id'] ) ) {
231
+ $message = $notices->get_message_data( 'tc-paypal-refresh-user-info-failed' );
232
+ $this->container->make( Gateway::class )->handle_invalid_response( $user_info, $message['content'], 'tc-invalid-user-info-response' );
233
+
234
+ return;
235
+ }
236
+
237
+ $merchant->save_user_info( $user_info );
238
+
239
+ $notices->trigger_admin( 'tc-paypal-refresh-user-info' );
240
  }
241
 
242
  /**
243
  * Handles the refreshing of the webhook on PayPal for this site/merchant.
244
  *
 
245
  * @since 5.1.10
246
  *
247
+ * @since 5.2.0 Display error|success messages.
248
  */
249
  public function handle_action_refresh_webhook() {
250
  $updated = $this->container->make( Webhooks::class )->create_or_update_existing();
251
+ $notices = $this->container->make( Notice_Handler::class );
252
+
253
+ if ( is_wp_error( $updated ) ) {
254
+ $content = empty( $updated->get_error_message() ) ? $updated->get_error_code() : $updated->get_error_message();
255
+ $notices->trigger_admin( 'tc-paypal-refresh-webhook-api-error', [ 'content' => $content ] );
256
+ $notices->trigger_admin( 'tc-paypal-refresh-webhook-failed' );
257
+
258
+ return;
259
+ }
260
+
261
+ if ( ! $updated ) {
262
+ $notices->trigger_admin( 'tc-paypal-refresh-webhook-failed' );
263
+
264
+ return;
265
+ }
266
+
267
+ $notices->trigger_admin( 'tc-paypal-refresh-webhook-success' );
268
+ }
269
+
270
+ /**
271
+ * Handles the refreshing the entire connection with PayPal.
272
+ *
273
+ * @since 5.2.0
274
+ */
275
+ public function handle_action_refresh_connection() {
276
+ $this->handle_action_refresh_token();
277
+ $this->handle_action_refresh_user_info();
278
+ $this->handle_action_refresh_webhook();
279
  }
280
 
281
  /**
299
  public function filter_add_gateway( array $gateways = [] ) {
300
  return $this->container->make( Gateway::class )->register_gateway( $gateways );
301
  }
302
+
303
+ /**
304
+ * Render SSL requirement notice.
305
+ *
306
+ * @since 5.2.0
307
+ */
308
+ public function render_ssl_notice() {
309
+ $page = tribe_get_request_var( 'page' );
310
+ $tab = tribe_get_request_var( 'tab' );
311
+
312
+ if ( \Tribe__Settings::instance()->adminSlug !== $page || 'payments' !== $tab || is_ssl() ) {
313
+ return;
314
+ }
315
+
316
+ $this->container->make( Notice_Handler::class )->trigger_admin( 'tc-paypal-ssl-not-available' );
317
+ }
318
+
319
+ /**
320
+ * Include PayPal admin notices for Ticket Commerce.
321
+ *
322
+ * @since 5.2.0
323
+ *
324
+ * @param array $messages Array of messages.
325
+ *
326
+ * @return array
327
+ */
328
+ public function include_admin_notices( $messages ) {
329
+ return array_merge( $messages, $this->container->make( Gateway::class )->get_admin_notices() );
330
+ }
331
+
332
+ /**
333
+ * Includes the Capture ID in the success page of the PayPal Gateway orders.
334
+ *
335
+ * @since 5.2.0
336
+ *
337
+ * @param string $file Which file we are loading.
338
+ * @param string $name The name of the file.
339
+ * @param \Tribe__Template $template Which Template object is being used.
340
+ */
341
+ public function include_capture_id_success_page( $file, $name, $template ) {
342
+ $order = $template->get( 'order' );
343
+
344
+ // Bail if the order is not set to complete.
345
+ if ( empty( $order->gateway_payload[ Completed::SLUG ] ) ) {
346
+ return;
347
+ }
348
+
349
+ $capture_payload = end( $order->gateway_payload[ Completed::SLUG ] );
350
+ $capture_id = Arr::get( $capture_payload, [ 'purchase_units', 0, 'payments', 'captures', 0, 'id' ] );
351
+
352
+ // Couldn't find a valid Capture ID.
353
+ if ( ! $capture_id ) {
354
+ return;
355
+ }
356
+
357
+ $template->template( 'gateway/paypal/order/details/capture-id', [ 'capture_id' => $capture_id ] );
358
+ }
359
+
360
+ /**
361
+ * Checks if the transient data needs to be flushed when saving options and deletes it if appropriate
362
+ *
363
+ * @since 5.2.0
364
+ *
365
+ * @param array $options the list of plugin options set for saving
366
+ *
367
+ * @return array
368
+ */
369
+ public function flush_transients_when_toggling_sandbox_mode( $options ) {
370
+ return $this->container->make( Signup::class )->maybe_delete_transient_data( $options );
371
+ }
372
  }
src/Tickets/Commerce/Gateways/PayPal/Location/Country.php ADDED
@@ -0,0 +1,851 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles all the Country handling for PayPal Gateway.
4
+ *
5
+ * @since 5.2.0
6
+ *
7
+ * @package TEC\Tickets\Commerce\Gateways\PayPal
8
+ */
9
+
10
+ namespace TEC\Tickets\Commerce\Gateways\PayPal\Location;
11
+
12
+ /**
13
+ * Class Country
14
+ *
15
+ * @since 5.2.0
16
+ *
17
+ */
18
+ class Country {
19
+
20
+ public static $country_option_key = 'tickets-commerce-gateway-paypal-merchant-country';
21
+
22
+ /**
23
+ * Default two char string for the default country code.
24
+ *
25
+ * @since 5.2.0
26
+ *
27
+ * @var string
28
+ */
29
+ const DEFAULT_COUNTRY_CODE = 'US';
30
+
31
+ /**
32
+ * Get PayPal base country.
33
+ *
34
+ * @since 5.2.0
35
+ *
36
+ * @return string $country The two letter country code for the site's base country
37
+ */
38
+ public function get_setting() {
39
+ $country = tribe_get_option( static::$country_option_key );
40
+
41
+ /**
42
+ * Fetches the country associated with the PayPal setting.
43
+ *
44
+ * @since 5.2.0
45
+ *
46
+ * @param string $country Two letter country code in the settings.
47
+ */
48
+ $country = apply_filters( 'tec_tickets_commerce_gateway_paypal_country', $country );
49
+
50
+ // Makes sure this value is always valid.
51
+ if ( ! $this->is_valid( $country ) ) {
52
+ return static::DEFAULT_COUNTRY_CODE;
53
+ }
54
+
55
+ return $country;
56
+ }
57
+
58
+ /**
59
+ * Saves the paypal base country to the Options array.
60
+ *
61
+ * @since 5.2.0
62
+ *
63
+ * @return boolean
64
+ */
65
+ public function save_setting( $value ) {
66
+ return tribe_update_option( static::$country_option_key, $value );
67
+ }
68
+
69
+ /**
70
+ * Determines based on a country code if it's valid.
71
+ *
72
+ * @since 5.2.0
73
+ *
74
+ * @param string $country
75
+ *
76
+ * @return bool
77
+ */
78
+ public function is_valid( $country ) {
79
+ if ( empty( $country ) ) {
80
+ return false;
81
+ }
82
+
83
+ $countries = $this->get_list();
84
+ if ( empty( $countries[ $country ] ) ) {
85
+ return false;
86
+ }
87
+
88
+ return true;
89
+ }
90
+
91
+ public function get_list() {
92
+ $us = static::DEFAULT_COUNTRY_CODE;
93
+ $countries = [
94
+ '' => '',
95
+ $us => esc_html__( 'United States', 'event-tickets' ),
96
+ 'CA' => esc_html__( 'Canada', 'event-tickets' ),
97
+ 'GB' => esc_html__( 'United Kingdom', 'event-tickets' ),
98
+ 'AF' => esc_html__( 'Afghanistan', 'event-tickets' ),
99
+ 'AL' => esc_html__( 'Albania', 'event-tickets' ),
100
+ 'DZ' => esc_html__( 'Algeria', 'event-tickets' ),
101
+ 'AS' => esc_html__( 'American Samoa', 'event-tickets' ),
102
+ 'AD' => esc_html__( 'Andorra', 'event-tickets' ),
103
+ 'AO' => esc_html__( 'Angola', 'event-tickets' ),
104
+ 'AI' => esc_html__( 'Anguilla', 'event-tickets' ),
105
+ 'AQ' => esc_html__( 'Antarctica', 'event-tickets' ),
106
+ 'AG' => esc_html__( 'Antigua and Barbuda', 'event-tickets' ),
107
+ 'AR' => esc_html__( 'Argentina', 'event-tickets' ),
108
+ 'AM' => esc_html__( 'Armenia', 'event-tickets' ),
109
+ 'AW' => esc_html__( 'Aruba', 'event-tickets' ),
110
+ 'AU' => esc_html__( 'Australia', 'event-tickets' ),
111
+ 'AT' => esc_html__( 'Austria', 'event-tickets' ),
112
+ 'AZ' => esc_html__( 'Azerbaijan', 'event-tickets' ),
113
+ 'BS' => esc_html__( 'Bahamas', 'event-tickets' ),
114
+ 'BH' => esc_html__( 'Bahrain', 'event-tickets' ),
115
+ 'BD' => esc_html__( 'Bangladesh', 'event-tickets' ),
116
+ 'BB' => esc_html__( 'Barbados', 'event-tickets' ),
117
+ 'BY' => esc_html__( 'Belarus', 'event-tickets' ),
118
+ 'BE' => esc_html__( 'Belgium', 'event-tickets' ),
119
+ 'BZ' => esc_html__( 'Belize', 'event-tickets' ),
120
+ 'BJ' => esc_html__( 'Benin', 'event-tickets' ),
121
+ 'BM' => esc_html__( 'Bermuda', 'event-tickets' ),
122
+ 'BT' => esc_html__( 'Bhutan', 'event-tickets' ),
123
+ 'BO' => esc_html__( 'Bolivia', 'event-tickets' ),
124
+ 'BA' => esc_html__( 'Bosnia and Herzegovina', 'event-tickets' ),
125
+ 'BW' => esc_html__( 'Botswana', 'event-tickets' ),
126
+ 'BV' => esc_html__( 'Bouvet Island', 'event-tickets' ),
127
+ 'BR' => esc_html__( 'Brazil', 'event-tickets' ),
128
+ 'IO' => esc_html__( 'British Indian Ocean Territory', 'event-tickets' ),
129
+ 'BN' => esc_html__( 'Brunei Darrussalam', 'event-tickets' ),
130
+ 'BG' => esc_html__( 'Bulgaria', 'event-tickets' ),
131
+ 'BF' => esc_html__( 'Burkina Faso', 'event-tickets' ),
132
+ 'BI' => esc_html__( 'Burundi', 'event-tickets' ),
133
+ 'KH' => esc_html__( 'Cambodia', 'event-tickets' ),
134
+ 'CM' => esc_html__( 'Cameroon', 'event-tickets' ),
135
+ 'CV' => esc_html__( 'Cape Verde', 'event-tickets' ),
136
+ 'KY' => esc_html__( 'Cayman Islands', 'event-tickets' ),
137
+ 'CF' => esc_html__( 'Central African Republic', 'event-tickets' ),
138
+ 'TD' => esc_html__( 'Chad', 'event-tickets' ),
139
+ 'CL' => esc_html__( 'Chile', 'event-tickets' ),
140
+ 'CN' => esc_html__( 'China', 'event-tickets' ),
141
+ 'CX' => esc_html__( 'Christmas Island', 'event-tickets' ),
142
+ 'CC' => esc_html__( 'Cocos Islands', 'event-tickets' ),
143
+ 'CO' => esc_html__( 'Colombia', 'event-tickets' ),
144
+ 'KM' => esc_html__( 'Comoros', 'event-tickets' ),
145
+ 'CD' => esc_html__( 'Congo, Democratic People\'s Republic', 'event-tickets' ),
146
+ 'CG' => esc_html__( 'Congo, Republic of', 'event-tickets' ),
147
+ 'CK' => esc_html__( 'Cook Islands', 'event-tickets' ),
148
+ 'CR' => esc_html__( 'Costa Rica', 'event-tickets' ),
149
+ 'CI' => esc_html__( 'Cote d\'Ivoire', 'event-tickets' ),
150
+ 'HR' => esc_html__( 'Croatia/Hrvatska', 'event-tickets' ),
151
+ 'CU' => esc_html__( 'Cuba', 'event-tickets' ),
152
+ 'CY' => esc_html__( 'Cyprus Island', 'event-tickets' ),
153
+ 'CZ' => esc_html__( 'Czech Republic', 'event-tickets' ),
154
+ 'DK' => esc_html__( 'Denmark', 'event-tickets' ),
155
+ 'DJ' => esc_html__( 'Djibouti', 'event-tickets' ),
156
+ 'DM' => esc_html__( 'Dominica', 'event-tickets' ),
157
+ 'DO' => esc_html__( 'Dominican Republic', 'event-tickets' ),
158
+ 'TP' => esc_html__( 'East Timor', 'event-tickets' ),
159
+ 'EC' => esc_html__( 'Ecuador', 'event-tickets' ),
160
+ 'EG' => esc_html__( 'Egypt', 'event-tickets' ),
161
+ 'GQ' => esc_html__( 'Equatorial Guinea', 'event-tickets' ),
162
+ 'SV' => esc_html__( 'El Salvador', 'event-tickets' ),
163
+ 'ER' => esc_html__( 'Eritrea', 'event-tickets' ),
164
+ 'EE' => esc_html__( 'Estonia', 'event-tickets' ),
165
+ 'ET' => esc_html__( 'Ethiopia', 'event-tickets' ),
166
+ 'FK' => esc_html__( 'Falkland Islands', 'event-tickets' ),
167
+ 'FO' => esc_html__( 'Faroe Islands', 'event-tickets' ),
168
+ 'FJ' => esc_html__( 'Fiji', 'event-tickets' ),
169
+ 'FI' => esc_html__( 'Finland', 'event-tickets' ),
170
+ 'FR' => esc_html__( 'France', 'event-tickets' ),
171
+ 'GF' => esc_html__( 'French Guiana', 'event-tickets' ),
172
+ 'PF' => esc_html__( 'French Polynesia', 'event-tickets' ),
173
+ 'TF' => esc_html__( 'French Southern Territories', 'event-tickets' ),
174
+ 'GA' => esc_html__( 'Gabon', 'event-tickets' ),
175
+ 'GM' => esc_html__( 'Gambia', 'event-tickets' ),
176
+ 'GE' => esc_html__( 'Georgia', 'event-tickets' ),
177
+ 'DE' => esc_html__( 'Germany', 'event-tickets' ),
178
+ 'GR' => esc_html__( 'Greece', 'event-tickets' ),
179
+ 'GH' => esc_html__( 'Ghana', 'event-tickets' ),
180
+ 'GI' => esc_html__( 'Gibraltar', 'event-tickets' ),
181
+ 'GL' => esc_html__( 'Greenland', 'event-tickets' ),
182
+ 'GD' => esc_html__( 'Grenada', 'event-tickets' ),
183
+ 'GP' => esc_html__( 'Guadeloupe', 'event-tickets' ),
184
+ 'GU' => esc_html__( 'Guam', 'event-tickets' ),
185
+ 'GT' => esc_html__( 'Guatemala', 'event-tickets' ),
186
+ 'GG' => esc_html__( 'Guernsey', 'event-tickets' ),
187
+ 'GN' => esc_html__( 'Guinea', 'event-tickets' ),
188
+ 'GW' => esc_html__( 'Guinea-Bissau', 'event-tickets' ),
189
+ 'GY' => esc_html__( 'Guyana', 'event-tickets' ),
190
+ 'HT' => esc_html__( 'Haiti', 'event-tickets' ),
191
+ 'HM' => esc_html__( 'Heard and McDonald Islands', 'event-tickets' ),
192
+ 'VA' => esc_html__( 'Holy See (City Vatican State)', 'event-tickets' ),
193
+ 'HN' => esc_html__( 'Honduras', 'event-tickets' ),
194
+ 'HK' => esc_html__( 'Hong Kong', 'event-tickets' ),
195
+ 'HU' => esc_html__( 'Hungary', 'event-tickets' ),
196
+ 'IS' => esc_html__( 'Iceland', 'event-tickets' ),
197
+ 'IN' => esc_html__( 'India', 'event-tickets' ),
198
+ 'ID' => esc_html__( 'Indonesia', 'event-tickets' ),
199
+ 'IR' => esc_html__( 'Iran', 'event-tickets' ),
200
+ 'IQ' => esc_html__( 'Iraq', 'event-tickets' ),
201
+ 'IE' => esc_html__( 'Ireland', 'event-tickets' ),
202
+ 'IM' => esc_html__( 'Isle of Man', 'event-tickets' ),
203
+ 'IL' => esc_html__( 'Israel', 'event-tickets' ),
204
+ 'IT' => esc_html__( 'Italy', 'event-tickets' ),
205
+ 'JM' => esc_html__( 'Jamaica', 'event-tickets' ),
206
+ 'JP' => esc_html__( 'Japan', 'event-tickets' ),
207
+ 'JE' => esc_html__( 'Jersey', 'event-tickets' ),
208
+ 'JO' => esc_html__( 'Jordan', 'event-tickets' ),
209
+ 'KZ' => esc_html__( 'Kazakhstan', 'event-tickets' ),
210
+ 'KE' => esc_html__( 'Kenya', 'event-tickets' ),
211
+ 'KI' => esc_html__( 'Kiribati', 'event-tickets' ),
212
+ 'KW' => esc_html__( 'Kuwait', 'event-tickets' ),
213
+ 'KG' => esc_html__( 'Kyrgyzstan', 'event-tickets' ),
214
+ 'LA' => esc_html__( 'Lao People\'s Democratic Republic', 'event-tickets' ),
215
+ 'LV' => esc_html__( 'Latvia', 'event-tickets' ),
216
+ 'LB' => esc_html__( 'Lebanon', 'event-tickets' ),
217
+ 'LS' => esc_html__( 'Lesotho', 'event-tickets' ),
218
+ 'LR' => esc_html__( 'Liberia', 'event-tickets' ),
219
+ 'LY' => esc_html__( 'Libyan Arab Jamahiriya', 'event-tickets' ),
220
+ 'LI' => esc_html__( 'Liechtenstein', 'event-tickets' ),
221
+ 'LT' => esc_html__( 'Lithuania', 'event-tickets' ),
222
+ 'LU' => esc_html__( 'Luxembourg', 'event-tickets' ),
223
+ 'MO' => esc_html__( 'Macau', 'event-tickets' ),
224
+ 'MK' => esc_html__( 'Macedonia', 'event-tickets' ),
225
+ 'MG' => esc_html__( 'Madagascar', 'event-tickets' ),
226
+ 'MW' => esc_html__( 'Malawi', 'event-tickets' ),
227
+ 'MY' => esc_html__( 'Malaysia', 'event-tickets' ),
228
+ 'MV' => esc_html__( 'Maldives', 'event-tickets' ),
229
+ 'ML' => esc_html__( 'Mali', 'event-tickets' ),
230
+ 'MT' => esc_html__( 'Malta', 'event-tickets' ),
231
+ 'MH' => esc_html__( 'Marshall Islands', 'event-tickets' ),
232
+ 'MQ' => esc_html__( 'Martinique', 'event-tickets' ),
233
+ 'MR' => esc_html__( 'Mauritania', 'event-tickets' ),
234
+ 'MU' => esc_html__( 'Mauritius', 'event-tickets' ),
235
+ 'YT' => esc_html__( 'Mayotte', 'event-tickets' ),
236
+ 'MX' => esc_html__( 'Mexico', 'event-tickets' ),
237
+ 'FM' => esc_html__( 'Micronesia', 'event-tickets' ),
238
+ 'MD' => esc_html__( 'Moldova, Republic of', 'event-tickets' ),
239
+ 'MC' => esc_html__( 'Monaco', 'event-tickets' ),
240
+ 'MN' => esc_html__( 'Mongolia', 'event-tickets' ),
241
+ 'ME' => esc_html__( 'Montenegro', 'event-tickets' ),
242
+ 'MS' => esc_html__( 'Montserrat', 'event-tickets' ),
243
+ 'MA' => esc_html__( 'Morocco', 'event-tickets' ),
244
+ 'MZ' => esc_html__( 'Mozambique', 'event-tickets' ),
245
+ 'MM' => esc_html__( 'Myanmar', 'event-tickets' ),
246
+ 'NA' => esc_html__( 'Namibia', 'event-tickets' ),
247
+ 'NR' => esc_html__( 'Nauru', 'event-tickets' ),
248
+ 'NP' => esc_html__( 'Nepal', 'event-tickets' ),
249
+ 'NL' => esc_html__( 'Netherlands', 'event-tickets' ),
250
+ 'AN' => esc_html__( 'Netherlands Antilles', 'event-tickets' ),
251
+ 'NC' => esc_html__( 'New Caledonia', 'event-tickets' ),
252
+ 'NZ' => esc_html__( 'New Zealand', 'event-tickets' ),
253
+ 'NI' => esc_html__( 'Nicaragua', 'event-tickets' ),
254
+ 'NE' => esc_html__( 'Niger', 'event-tickets' ),
255
+ 'NG' => esc_html__( 'Nigeria', 'event-tickets' ),
256
+ 'NU' => esc_html__( 'Niue', 'event-tickets' ),
257
+ 'NF' => esc_html__( 'Norfolk Island', 'event-tickets' ),
258
+ 'KP' => esc_html__( 'North Korea', 'event-tickets' ),
259
+ 'MP' => esc_html__( 'Northern Mariana Islands', 'event-tickets' ),
260
+ 'NO' => esc_html__( 'Norway', 'event-tickets' ),
261
+ 'OM' => esc_html__( 'Oman', 'event-tickets' ),
262
+ 'PK' => esc_html__( 'Pakistan', 'event-tickets' ),
263
+ 'PW' => esc_html__( 'Palau', 'event-tickets' ),
264
+ 'PS' => esc_html__( 'Palestinian Territories', 'event-tickets' ),
265
+ 'PA' => esc_html__( 'Panama', 'event-tickets' ),
266
+ 'PG' => esc_html__( 'Papua New Guinea', 'event-tickets' ),
267
+ 'PY' => esc_html__( 'Paraguay', 'event-tickets' ),
268
+ 'PE' => esc_html__( 'Peru', 'event-tickets' ),
269
+ 'PH' => esc_html__( 'Philippines', 'event-tickets' ),
270
+ 'PN' => esc_html__( 'Pitcairn Island', 'event-tickets' ),
271
+ 'PL' => esc_html__( 'Poland', 'event-tickets' ),
272
+ 'PT' => esc_html__( 'Portugal', 'event-tickets' ),
273
+ 'PR' => esc_html__( 'Puerto Rico', 'event-tickets' ),
274
+ 'QA' => esc_html__( 'Qatar', 'event-tickets' ),
275
+ 'RE' => esc_html__( 'Reunion Island', 'event-tickets' ),
276
+ 'RO' => esc_html__( 'Romania', 'event-tickets' ),
277
+ 'RU' => esc_html__( 'Russian Federation', 'event-tickets' ),
278
+ 'RW' => esc_html__( 'Rwanda', 'event-tickets' ),
279
+ 'SH' => esc_html__( 'Saint Helena', 'event-tickets' ),
280
+ 'KN' => esc_html__( 'Saint Kitts and Nevis', 'event-tickets' ),
281
+ 'LC' => esc_html__( 'Saint Lucia', 'event-tickets' ),
282
+ 'PM' => esc_html__( 'Saint Pierre and Miquelon', 'event-tickets' ),
283
+ 'VC' => esc_html__( 'Saint Vincent and the Grenadines', 'event-tickets' ),
284
+ 'SM' => esc_html__( 'San Marino', 'event-tickets' ),
285
+ 'ST' => esc_html__( 'Sao Tome and Principe', 'event-tickets' ),
286
+ 'SA' => esc_html__( 'Saudi Arabia', 'event-tickets' ),
287
+ 'SN' => esc_html__( 'Senegal', 'event-tickets' ),
288
+ 'RS' => esc_html__( 'Serbia', 'event-tickets' ),
289
+ 'SC' => esc_html__( 'Seychelles', 'event-tickets' ),
290
+ 'SL' => esc_html__( 'Sierra Leone', 'event-tickets' ),
291
+ 'SG' => esc_html__( 'Singapore', 'event-tickets' ),
292
+ 'SK' => esc_html__( 'Slovak Republic', 'event-tickets' ),
293
+ 'SI' => esc_html__( 'Slovenia', 'event-tickets' ),
294
+ 'SB' => esc_html__( 'Solomon Islands', 'event-tickets' ),
295
+ 'SO' => esc_html__( 'Somalia', 'event-tickets' ),
296
+ 'ZA' => esc_html__( 'South Africa', 'event-tickets' ),
297
+ 'GS' => esc_html__( 'South Georgia', 'event-tickets' ),
298
+ 'KR' => esc_html__( 'South Korea', 'event-tickets' ),
299
+ 'ES' => esc_html__( 'Spain', 'event-tickets' ),
300
+ 'LK' => esc_html__( 'Sri Lanka', 'event-tickets' ),
301
+ 'SD' => esc_html__( 'Sudan', 'event-tickets' ),
302
+ 'SR' => esc_html__( 'Suriname', 'event-tickets' ),
303
+ 'SJ' => esc_html__( 'Svalbard and Jan Mayen Islands', 'event-tickets' ),
304
+ 'SZ' => esc_html__( 'Eswatini', 'event-tickets' ),
305
+ 'SE' => esc_html__( 'Sweden', 'event-tickets' ),
306
+ 'CH' => esc_html__( 'Switzerland', 'event-tickets' ),
307
+ 'SY' => esc_html__( 'Syrian Arab Republic', 'event-tickets' ),
308
+ 'TW' => esc_html__( 'Taiwan', 'event-tickets' ),
309
+ 'TJ' => esc_html__( 'Tajikistan', 'event-tickets' ),
310
+ 'TZ' => esc_html__( 'Tanzania', 'event-tickets' ),
311
+ 'TG' => esc_html__( 'Togo', 'event-tickets' ),
312
+ 'TK' => esc_html__( 'Tokelau', 'event-tickets' ),
313
+ 'TO' => esc_html__( 'Tonga', 'event-tickets' ),
314
+ 'TH' => esc_html__( 'Thailand', 'event-tickets' ),
315
+ 'TT' => esc_html__( 'Trinidad and Tobago', 'event-tickets' ),
316
+ 'TN' => esc_html__( 'Tunisia', 'event-tickets' ),
317
+ 'TR' => esc_html__( 'Turkey', 'event-tickets' ),
318
+ 'TM' => esc_html__( 'Turkmenistan', 'event-tickets' ),
319
+ 'TC' => esc_html__( 'Turks and Caicos Islands', 'event-tickets' ),
320
+ 'TV' => esc_html__( 'Tuvalu', 'event-tickets' ),
321
+ 'UG' => esc_html__( 'Uganda', 'event-tickets' ),
322
+ 'UA' => esc_html__( 'Ukraine', 'event-tickets' ),
323
+ 'AE' => esc_html__( 'United Arab Emirates', 'event-tickets' ),
324
+ 'UY' => esc_html__( 'Uruguay', 'event-tickets' ),
325
+ 'UM' => esc_html__( 'US Minor Outlying Islands', 'event-tickets' ),
326
+ 'UZ' => esc_html__( 'Uzbekistan', 'event-tickets' ),
327
+ 'VU' => esc_html__( 'Vanuatu', 'event-tickets' ),
328
+ 'VE' => esc_html__( 'Venezuela', 'event-tickets' ),
329
+ 'VN' => esc_html__( 'Vietnam', 'event-tickets' ),
330
+ 'VG' => esc_html__( 'Virgin Islands (British)', 'event-tickets' ),
331
+ 'VI' => esc_html__( 'Virgin Islands (USA)', 'event-tickets' ),
332
+ 'WF' => esc_html__( 'Wallis and Futuna Islands', 'event-tickets' ),
333
+ 'EH' => esc_html__( 'Western Sahara', 'event-tickets' ),
334
+ 'WS' => esc_html__( 'Western Samoa', 'event-tickets' ),
335
+ 'YE' => esc_html__( 'Yemen', 'event-tickets' ),
336
+ 'YU' => esc_html__( 'Yugoslavia', 'event-tickets' ),
337
+ 'ZM' => esc_html__( 'Zambia', 'event-tickets' ),
338
+ 'ZW' => esc_html__( 'Zimbabwe', 'event-tickets' ),
339
+ ];
340
+
341
+ /**
342
+ * Allows filtering of the available countries for PayPal gateway on Tickets Commerce.
343
+ *
344
+ * Using the two-character ISO-3166-1 code for their index.
345
+ *
346
+ * @since 5.2.0
347
+ *
348
+ * @param array $countries Which countries are available.
349
+ */
350
+ return (array) apply_filters( 'tec_tickets_commerce_gateway_paypal_countries', $countries );
351
+ }
352
+
353
+ /**
354
+ * Get Country List without postal/zip codes.
355
+ *
356
+ * @since 5.2.0
357
+ *
358
+ * @return string[] $countries A list of countries without postal/zip codes.
359
+ */
360
+ public function get_list_without_postcodes() {
361
+ $countries = [
362
+ 'AO',
363
+ 'AG',
364
+ 'AW',
365
+ 'BS',
366
+ 'BZ',
367
+ 'BJ',
368
+ 'BW',
369
+ 'BF',
370
+ 'BI',
371
+ 'CM',
372
+ 'CF',
373
+ 'KM',
374
+ 'CD',
375
+ 'CG',
376
+ 'CK',
377
+ 'CI',
378
+ 'DJ',
379
+ 'DM',
380
+ 'GQ',
381
+ 'ER',
382
+ 'FJ',
383
+ 'TF',
384
+ 'GM',
385
+ 'GH',
386
+ 'GD',
387
+ 'GN',
388
+ 'GY',
389
+ 'HK',
390
+ 'IE',
391
+ 'JM',
392
+ 'KE',
393
+ 'KI',
394
+ 'MO',
395
+ 'MW',
396
+ 'ML',
397
+ 'MR',
398
+ 'MU',
399
+ 'MS',
400
+ 'NR',
401
+ 'AN',
402
+ 'NU',
403
+ 'KP',
404
+ 'PA',
405
+ 'QA',
406
+ 'RW',
407
+ 'KN',
408
+ 'LC',
409
+ 'ST',
410
+ 'SC',
411
+ 'SL',
412
+ 'SB',
413
+ 'SO',
414
+ 'ZA',
415
+ 'SR',
416
+ 'SY',
417
+ 'TZ',
418
+ 'TK',
419
+ 'TO',
420
+ 'TT',
421
+ 'TV',
422
+ 'UG',
423
+ 'AE',
424
+ 'VU',
425
+ 'YE',
426
+ 'ZW',
427
+ ];
428
+
429
+ /**
430
+ * Filter list of countries codes that do not require postal/zip codes.
431
+ *
432
+ * @since 5.2.0
433
+ *
434
+ * @param string[] $countries List of the countries.
435
+ */
436
+ return (array) apply_filters( 'tec_tickets_commerce_gateway_paypal_countries_no_postcode', $countries );
437
+ }
438
+
439
+ /**
440
+ * Get country locale settings.
441
+ *
442
+ * @since 5.2.0
443
+ *
444
+ * @return array
445
+ */
446
+ public function get_list_locale() {
447
+ /**
448
+ * Filter list of countries locale settings, which is used to determine how certain fields are displayed.
449
+ *
450
+ * @since 5.2.0
451
+ *
452
+ * @param string[] $countries List of the countries.
453
+ */
454
+ return (array) apply_filters(
455
+ 'tec_tickets_commerce_gateway_paypal_countries_locale',
456
+ [
457
+ 'AE' => [
458
+ 'state' => [
459
+ 'required' => false,
460
+ ],
461
+ ],
462
+ 'AF' => [
463
+ 'state' => [
464
+ 'required' => false,
465
+ 'hidden' => true,
466
+ ],
467
+ ],
468
+ 'AT' => [
469
+ 'state' => [
470
+ 'required' => false,
471
+ 'hidden' => true,
472
+ ],
473
+ ],
474
+ 'AU' => [
475
+ 'state' => [
476
+ 'label' => __( 'State', 'event-tickets' ),
477
+ ],
478
+ ],
479
+ 'AX' => [
480
+ 'state' => [
481
+ 'required' => false,
482
+ ],
483
+ ],
484
+ 'BD' => [
485
+ 'state' => [
486
+ 'label' => __( 'District', 'event-tickets' ),
487
+ ],
488
+ ],
489
+ 'BE' => [
490
+ 'state' => [
491
+ 'required' => false,
492
+ 'label' => __( 'Province', 'event-tickets' ),
493
+ 'hidden' => true,
494
+ ],
495
+ ],
496
+ 'BI' => [
497
+ 'state' => [
498
+ 'required' => false,
499
+ ],
500
+ ],
501
+ 'CA' => [
502
+ 'state' => [
503
+ 'label' => __( 'Province', 'event-tickets' ),
504
+ ],
505
+ ],
506
+ 'CH' => [
507
+ 'state' => [
508
+ 'label' => __( 'Canton', 'event-tickets' ),
509
+ 'required' => false,
510
+ 'hidden' => true,
511
+ ],
512
+ ],
513
+ 'CL' => [
514
+ 'state' => [
515
+ 'label' => __( 'Region', 'event-tickets' ),
516
+ ],
517
+ ],
518
+ 'CN' => [
519
+ 'state' => [
520
+ 'label' => __( 'Province', 'event-tickets' ),
521
+ ],
522
+ ],
523
+ 'CZ' => [
524
+ 'state' => [
525
+ 'required' => false,
526
+ 'hidden' => true,
527
+ ],
528
+ ],
529
+ 'DE' => [
530
+ 'state' => [
531
+ 'required' => false,
532
+ 'hidden' => true,
533
+ ],
534
+ ],
535
+ 'DK' => [
536
+ 'state' => [
537
+ 'required' => false,
538
+ 'hidden' => true,
539
+ ],
540
+ ],
541
+ 'EE' => [
542
+ 'state' => [
543
+ 'required' => false,
544
+ 'hidden' => true,
545
+ ],
546
+ ],
547
+ 'FI' => [
548
+ 'state' => [
549
+ 'required' => false,
550
+ 'hidden' => true,
551
+ ],
552
+ ],
553
+ 'FR' => [
554
+ 'state' => [
555
+ 'required' => false,
556
+ 'hidden' => true,
557
+ ],
558
+ ],
559
+ 'GP' => [
560
+ 'state' => [
561
+ 'required' => false,
562
+ ],
563
+ ],
564
+ 'GF' => [
565
+ 'state' => [
566
+ 'required' => false,
567
+ ],
568
+ ],
569
+ 'HK' => [
570
+ 'state' => [
571
+ 'label' => __( 'Region', 'event-tickets' ),
572
+ ],
573
+ ],
574
+ 'HU' => [
575
+ 'state' => [
576
+ 'label' => __( 'County', 'event-tickets' ),
577
+ 'hidden' => true,
578
+ ],
579
+ ],
580
+ 'ID' => [
581
+ 'state' => [
582
+ 'label' => __( 'Province', 'event-tickets' ),
583
+ ],
584
+ ],
585
+ 'IE' => [
586
+ 'state' => [
587
+ 'label' => __( 'County', 'event-tickets' ),
588
+ ],
589
+ ],
590
+ 'IS' => [
591
+ 'state' => [
592
+ 'required' => false,
593
+ 'hidden' => true,
594
+ ],
595
+ ],
596
+ 'IL' => [
597
+ 'state' => [
598
+ 'required' => false,
599
+ ],
600
+ ],
601
+ 'IT' => [
602
+ 'state' => [
603
+ 'required' => true,
604
+ 'label' => __( 'Province', 'event-tickets' ),
605
+ ],
606
+ ],
607
+ 'JP' => [
608
+ 'state' => [
609
+ 'label' => __( 'Prefecture', 'event-tickets' ),
610
+ ],
611
+ ],
612
+ 'KR' => [
613
+ 'state' => [
614
+ 'required' => false,
615
+ 'hidden' => true,
616
+ ],
617
+ ],
618
+ 'KW' => [
619
+ 'state' => [
620
+ 'required' => false,
621
+ ],
622
+ ],
623
+ 'LB' => [
624
+ 'state' => [
625
+ 'required' => false,
626
+ ],
627
+ ],
628
+ 'MC' => [
629
+ 'state' => [
630
+ 'required' => false,
631
+ 'hidden' => true,
632
+ ],
633
+ ],
634
+ 'MQ' => [
635
+ 'state' => [
636
+ 'required' => false,
637
+ ],
638
+ ],
639
+ 'NL' => [
640
+ 'state' => [
641
+ 'required' => false,
642
+ 'label' => __( 'Province', 'event-tickets' ),
643
+ 'hidden' => true,
644
+ ],
645
+ ],
646
+ 'NZ' => [
647
+ 'state' => [
648
+ 'label' => __( 'Region', 'event-tickets' ),
649
+ ],
650
+ ],
651
+ 'NO' => [
652
+ 'state' => [
653
+ 'required' => false,
654
+ 'hidden' => true,
655
+ ],
656
+ ],
657
+ 'NP' => [
658
+ 'state' => [
659
+ 'label' => __( 'State / Zone', 'event-tickets' ),
660
+ ],
661
+ ],
662
+ 'PL' => [
663
+ 'state' => [
664
+ 'required' => false,
665
+ 'hidden' => true,
666
+ ],
667
+ ],
668
+ 'PT' => [
669
+ 'state' => [
670
+ 'required' => false,
671
+ 'hidden' => true,
672
+ ],
673
+ ],
674
+ 'RE' => [
675
+ 'state' => [
676
+ 'required' => false,
677
+ ],
678
+ ],
679
+ 'RO' => [
680
+ 'state' => [
681
+ 'required' => false,
682
+ ],
683
+ ],
684
+ 'SG' => [
685
+ 'state' => [
686
+ 'required' => false,
687
+ ],
688
+ 'city' => [
689
+ 'required' => false,
690
+ ],
691
+ ],
692
+ 'SK' => [
693
+ 'state' => [
694
+ 'required' => false,
695
+ 'hidden' => true,
696
+ ],
697
+ ],
698
+ 'SI' => [
699
+ 'state' => [
700
+ 'required' => false,
701
+ 'hidden' => true,
702
+ ],
703
+ ],
704
+ 'ES' => [
705
+ 'state' => [
706
+ 'label' => __( 'Province', 'event-tickets' ),
707
+ ],
708
+ ],
709
+ 'LI' => [
710
+ 'state' => [
711
+ 'label' => __( 'Municipality', 'event-tickets' ),
712
+ 'required' => false,
713
+ 'hidden' => true,
714
+ ],
715
+ ],
716
+ 'LK' => [
717
+ 'state' => [
718
+ 'required' => false,
719
+ ],
720
+ ],
721
+ 'SE' => [
722
+ 'state' => [
723
+ 'required' => false,
724
+ 'hidden' => true,
725
+ ],
726
+ ],
727
+ 'TR' => [
728
+ 'state' => [
729
+ 'label' => __( 'Province', 'event-tickets' ),
730
+ ],
731
+ ],
732
+ 'US' => [
733
+ 'state' => [
734
+ 'label' => __( 'State', 'event-tickets' ),
735
+ ],
736
+ ],
737
+ 'GB' => [
738
+ 'state' => [
739
+ 'label' => __( 'County', 'event-tickets' ),
740
+ 'required' => false,
741
+ ],
742
+ ],
743
+ 'VN' => [
744
+ 'state' => [
745
+ 'required' => false,
746
+ 'hidden' => true,
747
+ ],
748
+ ],
749
+ 'YT' => [
750
+ 'state' => [
751
+ 'required' => false,
752
+ ],
753
+ ],
754
+ 'ZA' => [
755
+ 'state' => [
756
+ 'label' => __( 'Province', 'event-tickets' ),
757
+ ],
758
+ ],
759
+ 'PA' => [
760
+ 'state' => [
761
+ 'required' => true,
762
+ ],
763
+ ],
764
+ ]
765
+ );
766
+ }
767
+
768
+ /**
769
+ * List of Country that have no states init.
770
+ *
771
+ * There are some country which does not have states init Example: germany.
772
+ *
773
+ * @since 5.2.0
774
+ *
775
+ * @return array $country_list
776
+ */
777
+ public function list_no_states() {
778
+ $country_list = [];
779
+ $locale = $this->get_list_locale();
780
+ foreach ( $locale as $key => $value ) {
781
+ if ( ! empty( $value['state'] ) && isset( $value['state']['hidden'] ) && true === $value['state']['hidden'] ) {
782
+ $country_list[ $key ] = $value['state'];
783
+ }
784
+ }
785
+
786
+ /**
787
+ * Filter can be used to add or remove the Country that does not have states init.
788
+ *
789
+ * @since 5.2.0
790
+ *
791
+ * @param array $country Contain key as there country code & value as there country name.
792
+ */
793
+ return (array) apply_filters( 'tec_tickets_commerce_gateway_paypal_countries_no_states', $country_list );
794
+ }
795
+
796
+ /**
797
+ * List of Country in which states fields is not required.
798
+ *
799
+ * There are some country in which states fields is not required Example: United Kingdom ( uk ).
800
+ *
801
+ * @since 5.2.0
802
+ *
803
+ * @return array $country_list
804
+ */
805
+ public function list_states_not_required() {
806
+ $country_list = [];
807
+ $locale = $this->get_list_locale();
808
+ foreach ( $locale as $key => $value ) {
809
+ if ( ! empty( $value['state'] ) && isset( $value['state']['required'] ) && false === $value['state']['required'] ) {
810
+ $country_list[ $key ] = $value['state'];
811
+ }
812
+ }
813
+
814
+ /**
815
+ * Filter can be used to add or remove the Country in which states fields is not required.
816
+ *
817
+ * @since 5.2.0
818
+ *
819
+ * @param array $country Contain key as there country code & value as there country name.
820
+ */
821
+ return (array) apply_filters( 'tec_tickets_commerce_gateway_paypal_countries_states_not_required', $country_list );
822
+ }
823
+
824
+ /**
825
+ * List of Country in which city fields is not required.
826
+ *
827
+ * There are some country in which city fields is not required Example: Singapore ( sk ).
828
+ *
829
+ * @since 5.2.0
830
+ *
831
+ * @return array $country_list
832
+ */
833
+ public function list_city_not_required() {
834
+ $country_list = [];
835
+ $locale = $this->get_list_locale();
836
+ foreach ( $locale as $key => $value ) {
837
+ if ( ! empty( $value['city'] ) && isset( $value['city']['required'] ) && false === $value['city']['required'] ) {
838
+ $country_list[ $key ] = $value['city'];
839
+ }
840
+ }
841
+
842
+ /**
843
+ * Filter can be used to add or remove the Country in which city fields is not required.
844
+ *
845
+ * @since 5.2.0
846
+ *
847
+ * @param array $country_list Contain key as there country code & value as there country name.
848
+ */
849
+ return (array) apply_filters( 'tec_tickets_commerce_gateway_paypal_countries_city_not_required', $country_list );
850
+ }
851
+ }
src/Tickets/Commerce/Gateways/PayPal/Location/State.php ADDED
@@ -0,0 +1,1699 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class State.
5
+ *
6
+ * Currently this file is not in use for PayPal yet, but we might implement in the near future, this is code ported from
7
+ * GiveWP that we modified, but it's not in use. Modifications and usage should be verified.
8
+ *
9
+ * @since 5.2.0
10
+ */
11
+ class State {
12
+ /**
13
+ * Get Turkey States
14
+ *
15
+ * @since 5.2.0
16
+ *
17
+ * @return array $states A list of states
18
+ */
19
+ public function get_turkey_list() {
20
+ $states = [
21
+ '' => '',
22
+ 'TR01' => __( 'Adana', 'event-tickets' ),
23
+ 'TR02' => __( 'Ad&#305;yaman', 'event-tickets' ),
24
+ 'TR03' => __( 'Afyon', 'event-tickets' ),
25
+ 'TR04' => __( 'A&#287;r&#305;', 'event-tickets' ),
26
+ 'TR05' => __( 'Amasya', 'event-tickets' ),
27
+ 'TR06' => __( 'Ankara', 'event-tickets' ),
28
+ 'TR07' => __( 'Antalya', 'event-tickets' ),
29
+ 'TR08' => __( 'Artvin', 'event-tickets' ),
30
+ 'TR09' => __( 'Ayd&#305;n', 'event-tickets' ),
31
+ 'TR10' => __( 'Bal&#305;kesir', 'event-tickets' ),
32
+ 'TR11' => __( 'Bilecik', 'event-tickets' ),
33
+ 'TR12' => __( 'Bing&#246;l', 'event-tickets' ),
34
+ 'TR13' => __( 'Bitlis', 'event-tickets' ),
35
+ 'TR14' => __( 'Bolu', 'event-tickets' ),
36
+ 'TR15' => __( 'Burdur', 'event-tickets' ),
37
+ 'TR16' => __( 'Bursa', 'event-tickets' ),
38
+ 'TR17' => __( '&#199;anakkale', 'event-tickets' ),
39
+ 'TR18' => __( '&#199;ank&#305;r&#305;', 'event-tickets' ),
40
+ 'TR19' => __( '&#199;orum', 'event-tickets' ),
41
+ 'TR20' => __( 'Denizli', 'event-tickets' ),
42
+ 'TR21' => __( 'Diyarbak&#305;r', 'event-tickets' ),
43
+ 'TR22' => __( 'Edirne', 'event-tickets' ),
44
+ 'TR23' => __( 'Elaz&#305;&#287;', 'event-tickets' ),
45
+ 'TR24' => __( 'Erzincan', 'event-tickets' ),
46
+ 'TR25' => __( 'Erzurum', 'event-tickets' ),
47
+ 'TR26' => __( 'Eski&#351;ehir', 'event-tickets' ),
48
+ 'TR27' => __( 'Gaziantep', 'event-tickets' ),
49
+ 'TR28' => __( 'Giresun', 'event-tickets' ),
50
+ 'TR29' => __( 'G&#252;m&#252;&#351;hane', 'event-tickets' ),
51
+ 'TR30' => __( 'Hakkari', 'event-tickets' ),
52
+ 'TR31' => __( 'Hatay', 'event-tickets' ),
53
+ 'TR32' => __( 'Isparta', 'event-tickets' ),
54
+ 'TR33' => __( '&#304;&#231;el', 'event-tickets' ),
55
+ 'TR34' => __( '&#304;stanbul', 'event-tickets' ),
56
+ 'TR35' => __( '&#304;zmir', 'event-tickets' ),
57
+ 'TR36' => __( 'Kars', 'event-tickets' ),
58
+ 'TR37' => __( 'Kastamonu', 'event-tickets' ),
59
+ 'TR38' => __( 'Kayseri', 'event-tickets' ),
60
+ 'TR39' => __( 'K&#305;rklareli', 'event-tickets' ),
61
+ 'TR40' => __( 'K&#305;r&#351;ehir', 'event-tickets' ),
62
+ 'TR41' => __( 'Kocaeli', 'event-tickets' ),
63
+ 'TR42' => __( 'Konya', 'event-tickets' ),
64
+ 'TR43' => __( 'K&#252;tahya', 'event-tickets' ),
65
+ 'TR44' => __( 'Malatya', 'event-tickets' ),
66
+ 'TR45' => __( 'Manisa', 'event-tickets' ),
67
+ 'TR46' => __( 'Kahramanmara&#351;', 'event-tickets' ),
68
+ 'TR47' => __( 'Mardin', 'event-tickets' ),
69
+ 'TR48' => __( 'Mu&#287;la', 'event-tickets' ),
70
+ 'TR49' => __( 'Mu&#351;', 'event-tickets' ),
71
+ 'TR50' => __( 'Nev&#351;ehir', 'event-tickets' ),
72
+ 'TR51' => __( 'Ni&#287;de', 'event-tickets' ),
73
+ 'TR52' => __( 'Ordu', 'event-tickets' ),
74
+ 'TR53' => __( 'Rize', 'event-tickets' ),
75
+ 'TR54' => __( 'Sakarya', 'event-tickets' ),
76
+ 'TR55' => __( 'Samsun', 'event-tickets' ),
77
+ 'TR56' => __( 'Siirt', 'event-tickets' ),
78
+ 'TR57' => __( 'Sinop', 'event-tickets' ),
79
+ 'TR58' => __( 'Sivas', 'event-tickets' ),
80
+ 'TR59' => __( 'Tekirda&#287;', 'event-tickets' ),
81
+ 'TR60' => __( 'Tokat', 'event-tickets' ),
82
+ 'TR61' => __( 'Trabzon', 'event-tickets' ),
83
+ 'TR62' => __( 'Tunceli', 'event-tickets' ),
84
+ 'TR63' => __( '&#350;anl&#305;urfa', 'event-tickets' ),
85
+ 'TR64' => __( 'U&#351;ak', 'event-tickets' ),
86
+ 'TR65' => __( 'Van', 'event-tickets' ),
87
+ 'TR66' => __( 'Yozgat', 'event-tickets' ),
88
+ 'TR67' => __( 'Zonguldak', 'event-tickets' ),
89
+ 'TR68' => __( 'Aksaray', 'event-tickets' ),
90
+ 'TR69' => __( 'Bayburt', 'event-tickets' ),
91
+ 'TR70' => __( 'Karaman', 'event-tickets' ),
92
+ 'TR71' => __( 'K&#305;r&#305;kkale', 'event-tickets' ),
93
+ 'TR72' => __( 'Batman', 'event-tickets' ),
94
+ 'TR73' => __( '&#350;&#305;rnak', 'event-tickets' ),
95
+ 'TR74' => __( 'Bart&#305;n', 'event-tickets' ),
96
+ 'TR75' => __( 'Ardahan', 'event-tickets' ),
97
+ 'TR76' => __( 'I&#287;d&#305;r', 'event-tickets' ),
98
+ 'TR77' => __( 'Yalova', 'event-tickets' ),
99
+ 'TR78' => __( 'Karab&#252;k', 'event-tickets' ),
100
+ 'TR79' => __( 'Kilis', 'event-tickets' ),
101
+ 'TR80' => __( 'Osmaniye', 'event-tickets' ),
102
+ 'TR81' => __( 'D&#252;zce', 'event-tickets' ),
103
+ ];
104
+
105
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_turkey_states', $states );
106
+ }
107
+
108
+ /**
109
+ * Get Romania States
110
+ *
111
+ * @since 5.2.0
112
+ *
113
+ * @return array $states A list of states
114
+ */
115
+ public function get_romania_list() {
116
+ $states = [
117
+ '' => '',
118
+ 'AB' => __( 'Alba', 'event-tickets' ),
119
+ 'AR' => __( 'Arad', 'event-tickets' ),
120
+ 'AG' => __( 'Arges', 'event-tickets' ),
121
+ 'BC' => __( 'Bacau', 'event-tickets' ),
122
+ 'BH' => __( 'Bihor', 'event-tickets' ),
123
+ 'BN' => __( 'Bistrita-Nasaud', 'event-tickets' ),
124
+ 'BT' => __( 'Botosani', 'event-tickets' ),
125
+ 'BR' => __( 'Braila', 'event-tickets' ),
126
+ 'BV' => __( 'Brasov', 'event-tickets' ),
127
+ 'B' => __( 'Bucuresti', 'event-tickets' ),
128
+ 'BZ' => __( 'Buzau', 'event-tickets' ),
129
+ 'CL' => __( 'Calarasi', 'event-tickets' ),
130
+ 'CS' => __( 'Caras-Severin', 'event-tickets' ),
131
+ 'CJ' => __( 'Cluj', 'event-tickets' ),
132
+ 'CT' => __( 'Constanta', 'event-tickets' ),
133
+ 'CV' => __( 'Covasna', 'event-tickets' ),
134
+ 'DB' => __( 'Dambovita', 'event-tickets' ),
135
+ 'DJ' => __( 'Dolj', 'event-tickets' ),
136
+ 'GL' => __( 'Galati', 'event-tickets' ),
137
+ 'GR' => __( 'Giurgiu', 'event-tickets' ),
138
+ 'GJ' => __( 'Gorj', 'event-tickets' ),
139
+ 'HR' => __( 'Harghita', 'event-tickets' ),
140
+ 'HD' => __( 'Hunedoara', 'event-tickets' ),
141
+ 'IL' => __( 'Ialomita', 'event-tickets' ),
142
+ 'IS' => __( 'Iasi', 'event-tickets' ),
143
+ 'IF' => __( 'Ilfov', 'event-tickets' ),
144
+ 'MM' => __( 'Maramures', 'event-tickets' ),
145
+ 'MH' => __( 'Mehedinti', 'event-tickets' ),
146
+ 'MS' => __( 'Mures', 'event-tickets' ),
147
+ 'NT' => __( 'Neamt', 'event-tickets' ),
148
+ 'OT' => __( 'Olt', 'event-tickets' ),
149
+ 'PH' => __( 'Prahova', 'event-tickets' ),
150
+ 'SJ' => __( 'Salaj', 'event-tickets' ),
151
+ 'SM' => __( 'Satu Mare', 'event-tickets' ),
152
+ 'SB' => __( 'Sibiu', 'event-tickets' ),
153
+ 'SV' => __( 'Suceava', 'event-tickets' ),
154
+ 'TR' => __( 'Teleorman', 'event-tickets' ),
155
+ 'TM' => __( 'Timis', 'event-tickets' ),
156
+ 'TL' => __( 'Tulcea', 'event-tickets' ),
157
+ 'VL' => __( 'Valcea', 'event-tickets' ),
158
+ 'VS' => __( 'Vaslui', 'event-tickets' ),
159
+ 'VN' => __( 'Vrancea', 'event-tickets' ),
160
+ ];
161
+
162
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_romania_states', $states );
163
+ }
164
+
165
+ /**
166
+ * Get Pakistan States
167
+ *
168
+ * @since 5.2.0
169
+ *
170
+ * @return array $states A list of states
171
+ */
172
+ public function get_pakistan_list() {
173
+ $states = [
174
+ '' => '',
175
+ 'JK' => __( 'Azad Kashmir', 'event-tickets' ),
176
+ 'BA' => __( 'Balochistan', 'event-tickets' ),
177
+ 'TA' => __( 'FATA', 'event-tickets' ),
178
+ 'GB' => __( 'Gilgit Baltistan', 'event-tickets' ),
179
+ 'IS' => __( 'Islamabad Capital Territory', 'event-tickets' ),
180
+ 'KP' => __( 'Khyber Pakhtunkhwa', 'event-tickets' ),
181
+ 'PB' => __( 'Punjab', 'event-tickets' ),
182
+ 'SD' => __( 'Sindh', 'event-tickets' ),
183
+ ];
184
+
185
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_pakistan_states', $states );
186
+ }
187
+
188
+ /**
189
+ * Get Philippines States
190
+ *
191
+ * @since 5.2.0
192
+ *
193
+ * @return array $states A list of states
194
+ */
195
+ public function get_philippines_list() {
196
+ $states = [
197
+ '' => '',
198
+ 'ABR' => __( 'Abra', 'event-tickets' ),
199
+ 'AGN' => __( 'Agusan del Norte', 'event-tickets' ),
200
+ 'AGS' => __( 'Agusan del Sur', 'event-tickets' ),
201
+ 'AKL' => __( 'Aklan', 'event-tickets' ),
202
+ 'ALB' => __( 'Albay', 'event-tickets' ),
203
+ 'ANT' => __( 'Antique', 'event-tickets' ),
204
+ 'APA' => __( 'Apayao', 'event-tickets' ),
205
+ 'AUR' => __( 'Aurora', 'event-tickets' ),
206
+ 'BAS' => __( 'Basilan', 'event-tickets' ),
207
+ 'BAN' => __( 'Bataan', 'event-tickets' ),
208
+ 'BTN' => __( 'Batanes', 'event-tickets' ),
209
+ 'BTG' => __( 'Batangas', 'event-tickets' ),
210
+ 'BEN' => __( 'Benguet', 'event-tickets' ),
211
+ 'BIL' => __( 'Biliran', 'event-tickets' ),
212
+ 'BOH' => __( 'Bohol', 'event-tickets' ),
213
+ 'BUK' => __( 'Bukidnon', 'event-tickets' ),
214
+ 'BUL' => __( 'Bulacan', 'event-tickets' ),
215
+ 'CAG' => __( 'Cagayan', 'event-tickets' ),
216
+ 'CAN' => __( 'Camarines Norte', 'event-tickets' ),
217
+ 'CAS' => __( 'Camarines Sur', 'event-tickets' ),
218
+ 'CAM' => __( 'Camiguin', 'event-tickets' ),
219
+ 'CAP' => __( 'Capiz', 'event-tickets' ),
220
+ 'CAT' => __( 'Catanduanes', 'event-tickets' ),
221
+ 'CAV' => __( 'Cavite', 'event-tickets' ),
222
+ 'CEB' => __( 'Cebu', 'event-tickets' ),
223
+ 'COM' => __( 'Compostela Valley', 'event-tickets' ),
224
+ 'NCO' => __( 'Cotabato', 'event-tickets' ),
225
+ 'DAV' => __( 'Davao del Norte', 'event-tickets' ),
226
+ 'DAS' => __( 'Davao del Sur', 'event-tickets' ),
227
+ 'DAC' => __( 'Davao Occidental', 'event-tickets' ), // TODO: Needs to be updated when ISO code is assigned
228
+ 'DAO' => __( 'Davao Oriental', 'event-tickets' ),
229
+ 'DIN' => __( 'Dinagat Islands', 'event-tickets' ),
230
+ 'EAS' => __( 'Eastern Samar', 'event-tickets' ),
231
+ 'GUI' => __( 'Guimaras', 'event-tickets' ),
232
+ 'IFU' => __( 'Ifugao', 'event-tickets' ),
233
+ 'ILN' => __( 'Ilocos Norte', 'event-tickets' ),
234
+ 'ILS' => __( 'Ilocos Sur', 'event-tickets' ),
235
+ 'ILI' => __( 'Iloilo', 'event-tickets' ),
236
+ 'ISA' => __( 'Isabela', 'event-tickets' ),
237
+ 'KAL' => __( 'Kalinga', 'event-tickets' ),
238
+ 'LUN' => __( 'La Union', 'event-tickets' ),
239
+ 'LAG' => __( 'Laguna', 'event-tickets' ),
240
+ 'LAN' => __( 'Lanao del Norte', 'event-tickets' ),
241
+ 'LAS' => __( 'Lanao del Sur', 'event-tickets' ),
242
+ 'LEY' => __( 'Leyte', 'event-tickets' ),
243
+ 'MAG' => __( 'Maguindanao', 'event-tickets' ),
244
+ 'MAD' => __( 'Marinduque', 'event-tickets' ),
245
+ 'MAS' => __( 'Masbate', 'event-tickets' ),
246
+ 'MSC' => __( 'Misamis Occidental', 'event-tickets' ),
247
+ 'MSR' => __( 'Misamis Oriental', 'event-tickets' ),
248
+ 'MOU' => __( 'Mountain Province', 'event-tickets' ),
249
+ 'NEC' => __( 'Negros Occidental', 'event-tickets' ),
250
+ 'NER' => __( 'Negros Oriental', 'event-tickets' ),
251
+ 'NSA' => __( 'Northern Samar', 'event-tickets' ),
252
+ 'NUE' => __( 'Nueva Ecija', 'event-tickets' ),
253
+ 'NUV' => __( 'Nueva Vizcaya', 'event-tickets' ),
254
+ 'MDC' => __( 'Occidental Mindoro', 'event-tickets' ),
255
+ 'MDR' => __( 'Oriental Mindoro', 'event-tickets' ),
256
+ 'PLW' => __( 'Palawan', 'event-tickets' ),
257
+ 'PAM' => __( 'Pampanga', 'event-tickets' ),
258
+ 'PAN' => __( 'Pangasinan', 'event-tickets' ),
259
+ 'QUE' => __( 'Quezon', 'event-tickets' ),
260
+ 'QUI' => __( 'Quirino', 'event-tickets' ),
261
+ 'RIZ' => __( 'Rizal', 'event-tickets' ),
262
+ 'ROM' => __( 'Romblon', 'event-tickets' ),
263
+ 'WSA' => __( 'Samar', 'event-tickets' ),
264
+ 'SAR' => __( 'Sarangani', 'event-tickets' ),
265
+ 'SIQ' => __( 'Siquijor', 'event-tickets' ),
266
+ 'SOR' => __( 'Sorsogon', 'event-tickets' ),
267
+ 'SCO' => __( 'South Cotabato', 'event-tickets' ),
268
+ 'SLE' => __( 'Southern Leyte', 'event-tickets' ),
269
+ 'SUK' => __( 'Sultan Kudarat', 'event-tickets' ),
270
+ 'SLU' => __( 'Sulu', 'event-tickets' ),
271
+ 'SUN' => __( 'Surigao del Norte', 'event-tickets' ),
272
+ 'SUR' => __( 'Surigao del Sur', 'event-tickets' ),
273
+ 'TAR' => __( 'Tarlac', 'event-tickets' ),
274
+ 'TAW' => __( 'Tawi-Tawi', 'event-tickets' ),
275
+ 'ZMB' => __( 'Zambales', 'event-tickets' ),
276
+ 'ZAN' => __( 'Zamboanga del Norte', 'event-tickets' ),
277
+ 'ZAS' => __( 'Zamboanga del Sur', 'event-tickets' ),
278
+ 'ZSI' => __( 'Zamboanga Sibugay', 'event-tickets' ),
279
+ '00' => __( 'Metro Manila', 'event-tickets' ),
280
+ ];
281
+
282
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_philippines_states', $states );
283
+ }
284
+
285
+ /**
286
+ * Get Peru States
287
+ *
288
+ * @since 5.2.0
289
+ *
290
+ * @return array $states A list of states
291
+ */
292
+ public function get_peru_list() {
293
+ $states = [
294
+ '' => '',
295
+ 'CAL' => __( 'El Callao', 'event-tickets' ),
296
+ 'LMA' => __( 'Municipalidad Metropolitana de Lima', 'event-tickets' ),
297
+ 'AMA' => __( 'Amazonas', 'event-tickets' ),
298
+ 'ANC' => __( 'Ancash', 'event-tickets' ),
299
+ 'APU' => __( 'Apur&iacute;mac', 'event-tickets' ),
300
+ 'ARE' => __( 'Arequipa', 'event-tickets' ),
301
+ 'AYA' => __( 'Ayacucho', 'event-tickets' ),
302
+ 'CAJ' => __( 'Cajamarca', 'event-tickets' ),
303
+ 'CUS' => __( 'Cusco', 'event-tickets' ),
304
+ 'HUV' => __( 'Huancavelica', 'event-tickets' ),
305
+ 'HUC' => __( 'Hu&aacute;nuco', 'event-tickets' ),
306
+ 'ICA' => __( 'Ica', 'event-tickets' ),
307
+ 'JUN' => __( 'Jun&iacute;n', 'event-tickets' ),
308
+ 'LAL' => __( 'La Libertad', 'event-tickets' ),
309
+ 'LAM' => __( 'Lambayeque', 'event-tickets' ),
310
+ 'LIM' => __( 'Lima', 'event-tickets' ),
311
+ 'LOR' => __( 'Loreto', 'event-tickets' ),
312
+ 'MDD' => __( 'Madre de Dios', 'event-tickets' ),
313
+ 'MOQ' => __( 'Moquegua', 'event-tickets' ),
314
+ 'PAS' => __( 'Pasco', 'event-tickets' ),
315
+ 'PIU' => __( 'Piura', 'event-tickets' ),
316
+ 'PUN' => __( 'Puno', 'event-tickets' ),
317
+ 'SAM' => __( 'San Mart&iacute;n', 'event-tickets' ),
318
+ 'TAC' => __( 'Tacna', 'event-tickets' ),
319
+ 'TUM' => __( 'Tumbes', 'event-tickets' ),
320
+ 'UCA' => __( 'Ucayali', 'event-tickets' ),
321
+ ];
322
+
323
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_peru_states', $states );
324
+ }
325
+
326
+ /**
327
+ * Get Nepal States
328
+ *
329
+ * @since 5.2.0
330
+ *
331
+ * @return array $states A list of states
332
+ */
333
+ public function get_nepal_list() {
334
+ $states = [
335
+ '' => '',
336
+ 'BAG' => __( 'Bagmati', 'event-tickets' ),
337
+ 'BHE' => __( 'Bheri', 'event-tickets' ),
338
+ 'DHA' => __( 'Dhaulagiri', 'event-tickets' ),
339
+ 'GAN' => __( 'Gandaki', 'event-tickets' ),
340
+ 'JAN' => __( 'Janakpur', 'event-tickets' ),
341
+ 'KAR' => __( 'Karnali', 'event-tickets' ),
342
+ 'KOS' => __( 'Koshi', 'event-tickets' ),
343
+ 'LUM' => __( 'Lumbini', 'event-tickets' ),
344
+ 'MAH' => __( 'Mahakali', 'event-tickets' ),
345
+ 'MEC' => __( 'Mechi', 'event-tickets' ),
346
+ 'NAR' => __( 'Narayani', 'event-tickets' ),
347
+ 'RAP' => __( 'Rapti', 'event-tickets' ),
348
+ 'SAG' => __( 'Sagarmatha', 'event-tickets' ),
349
+ 'SET' => __( 'Seti', 'event-tickets' ),
350
+ ];
351
+
352
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_nepal_states', $states );
353
+ }
354
+
355
+ /**
356
+ * Get Nigerian States
357
+ *
358
+ * @since 5.2.0
359
+ *
360
+ * @return array $states A list of states
361
+ */
362
+ public function get_nigerian_list() {
363
+ $states = [
364
+ '' => '',
365
+ 'AB' => __( 'Abia', 'event-tickets' ),
366
+ 'FC' => __( 'Abuja', 'event-tickets' ),
367
+ 'AD' => __( 'Adamawa', 'event-tickets' ),
368
+ 'AK' => __( 'Akwa Ibom', 'event-tickets' ),
369
+ 'AN' => __( 'Anambra', 'event-tickets' ),
370
+ 'BA' => __( 'Bauchi', 'event-tickets' ),
371
+ 'BY' => __( 'Bayelsa', 'event-tickets' ),
372
+ 'BE' => __( 'Benue', 'event-tickets' ),
373
+ 'BO' => __( 'Borno', 'event-tickets' ),
374
+ 'CR' => __( 'Cross River', 'event-tickets' ),
375
+ 'DE' => __( 'Delta', 'event-tickets' ),
376
+ 'EB' => __( 'Ebonyi', 'event-tickets' ),
377
+ 'ED' => __( 'Edo', 'event-tickets' ),
378
+ 'EK' => __( 'Ekiti', 'event-tickets' ),
379
+ 'EN' => __( 'Enugu', 'event-tickets' ),
380
+ 'GO' => __( 'Gombe', 'event-tickets' ),
381
+ 'IM' => __( 'Imo', 'event-tickets' ),
382
+ 'JI' => __( 'Jigawa', 'event-tickets' ),
383
+ 'KD' => __( 'Kaduna', 'event-tickets' ),
384
+ 'KN' => __( 'Kano', 'event-tickets' ),
385
+ 'KT' => __( 'Katsina', 'event-tickets' ),
386
+ 'KE' => __( 'Kebbi', 'event-tickets' ),
387
+ 'KO' => __( 'Kogi', 'event-tickets' ),
388
+ 'KW' => __( 'Kwara', 'event-tickets' ),
389
+ 'LA' => __( 'Lagos', 'event-tickets' ),
390
+ 'NA' => __( 'Nasarawa', 'event-tickets' ),
391
+ 'NI' => __( 'Niger', 'event-tickets' ),
392
+ 'OG' => __( 'Ogun', 'event-tickets' ),
393
+ 'ON' => __( 'Ondo', 'event-tickets' ),
394
+ 'OS' => __( 'Osun', 'event-tickets' ),
395
+ 'OY' => __( 'Oyo', 'event-tickets' ),
396
+ 'PL' => __( 'Plateau', 'event-tickets' ),
397
+ 'RI' => __( 'Rivers', 'event-tickets' ),
398
+ 'SO' => __( 'Sokoto', 'event-tickets' ),
399
+ 'TA' => __( 'Taraba', 'event-tickets' ),
400
+ 'YO' => __( 'Yobe', 'event-tickets' ),
401
+ 'ZA' => __( 'Zamfara', 'event-tickets' ),
402
+ ];
403
+
404
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_nigerian_states', $states );
405
+ }
406
+
407
+ /**
408
+ * Get Mexico States
409
+ *
410
+ * @since 5.2.0
411
+ *
412
+ * @return array $states A list of states
413
+ */
414
+ public function get_mexico_list() {
415
+ $states = [
416
+ '' => '',
417
+ 'Distrito Federal' => __( 'Distrito Federal', 'event-tickets' ),
418
+ 'Jalisco' => __( 'Jalisco', 'event-tickets' ),
419
+ 'Nuevo Leon' => __( 'Nuevo León', 'event-tickets' ),
420
+ 'Aguascalientes' => __( 'Aguascalientes', 'event-tickets' ),
421
+ 'Baja California' => __( 'Baja California', 'event-tickets' ),
422
+ 'Baja California Sur' => __( 'Baja California Sur', 'event-tickets' ),
423
+ 'Campeche' => __( 'Campeche', 'event-tickets' ),
424
+ 'Chiapas' => __( 'Chiapas', 'event-tickets' ),
425
+ 'Chihuahua' => __( 'Chihuahua', 'event-tickets' ),
426
+ 'Coahuila' => __( 'Coahuila', 'event-tickets' ),
427
+ 'Colima' => __( 'Colima', 'event-tickets' ),
428
+ 'Durango' => __( 'Durango', 'event-tickets' ),
429
+ 'Guanajuato' => __( 'Guanajuato', 'event-tickets' ),
430
+ 'Guerrero' => __( 'Guerrero', 'event-tickets' ),
431
+ 'Hidalgo' => __( 'Hidalgo', 'event-tickets' ),
432
+ 'Estado de Mexico' => __( 'Edo. de México', 'event-tickets' ),
433
+ 'Michoacan' => __( 'Michoacán', 'event-tickets' ),
434
+ 'Morelos' => __( 'Morelos', 'event-tickets' ),
435
+ 'Nayarit' => __( 'Nayarit', 'event-tickets' ),
436
+ 'Oaxaca' => __( 'Oaxaca', 'event-tickets' ),
437
+ 'Puebla' => __( 'Puebla', 'event-tickets' ),
438
+ 'Queretaro' => __( 'Querétaro', 'event-tickets' ),
439
+ 'Quintana Roo' => __( 'Quintana Roo', 'event-tickets' ),
440
+ 'San Luis Potosi' => __( 'San Luis Potosí', 'event-tickets' ),
441
+ 'Sinaloa' => __( 'Sinaloa', 'event-tickets' ),
442
+ 'Sonora' => __( 'Sonora', 'event-tickets' ),
443
+ 'Tabasco' => __( 'Tabasco', 'event-tickets' ),
444
+ 'Tamaulipas' => __( 'Tamaulipas', 'event-tickets' ),
445
+ 'Tlaxcala' => __( 'Tlaxcala', 'event-tickets' ),
446
+ 'Veracruz' => __( 'Veracruz', 'event-tickets' ),
447
+ 'Yucatan' => __( 'Yucatán', 'event-tickets' ),
448
+ 'Zacatecas' => __( 'Zacatecas', 'event-tickets' ),
449
+ ];
450
+
451
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_mexico_states', $states );
452
+ }
453
+
454
+ /**
455
+ * Get Japan States
456
+ *
457
+ * @since 5.2.0
458
+ *
459
+ * @return array $states A list of states
460
+ */
461
+ public function get_japan_list() {
462
+ $states = [
463
+ '' => '',
464
+ 'JP01' => __( 'Hokkaido', 'event-tickets' ),
465
+ 'JP02' => __( 'Aomori', 'event-tickets' ),
466
+ 'JP03' => __( 'Iwate', 'event-tickets' ),
467
+ 'JP04' => __( 'Miyagi', 'event-tickets' ),
468
+ 'JP05' => __( 'Akita', 'event-tickets' ),
469
+ 'JP06' => __( 'Yamagata', 'event-tickets' ),
470
+ 'JP07' => __( 'Fukushima', 'event-tickets' ),
471
+ 'JP08' => __( 'Ibaraki', 'event-tickets' ),
472
+ 'JP09' => __( 'Tochigi', 'event-tickets' ),
473
+ 'JP10' => __( 'Gunma', 'event-tickets' ),
474
+ 'JP11' => __( 'Saitama', 'event-tickets' ),
475
+ 'JP12' => __( 'Chiba', 'event-tickets' ),
476
+ 'JP13' => __( 'Tokyo', 'event-tickets' ),
477
+ 'JP14' => __( 'Kanagawa', 'event-tickets' ),
478
+ 'JP15' => __( 'Niigata', 'event-tickets' ),
479
+ 'JP16' => __( 'Toyama', 'event-tickets' ),
480
+ 'JP17' => __( 'Ishikawa', 'event-tickets' ),
481
+ 'JP18' => __( 'Fukui', 'event-tickets' ),
482
+ 'JP19' => __( 'Yamanashi', 'event-tickets' ),
483
+ 'JP20' => __( 'Nagano', 'event-tickets' ),
484
+ 'JP21' => __( 'Gifu', 'event-tickets' ),
485
+ 'JP22' => __( 'Shizuoka', 'event-tickets' ),
486
+ 'JP23' => __( 'Aichi', 'event-tickets' ),
487
+ 'JP24' => __( 'Mie', 'event-tickets' ),
488
+ 'JP25' => __( 'Shiga', 'event-tickets' ),
489
+ 'JP26' => __( 'Kyoto', 'event-tickets' ),
490
+ 'JP27' => __( 'Osaka', 'event-tickets' ),
491
+ 'JP28' => __( 'Hyogo', 'event-tickets' ),
492
+ 'JP29' => __( 'Nara', 'event-tickets' ),
493
+ 'JP30' => __( 'Wakayama', 'event-tickets' ),
494
+ 'JP31' => __( 'Tottori', 'event-tickets' ),
495
+ 'JP32' => __( 'Shimane', 'event-tickets' ),
496
+ 'JP33' => __( 'Okayama', 'event-tickets' ),
497
+ 'JP34' => __( 'Hiroshima', 'event-tickets' ),
498
+ 'JP35' => __( 'Yamaguchi', 'event-tickets' ),
499
+ 'JP36' => __( 'Tokushima', 'event-tickets' ),
500
+ 'JP37' => __( 'Kagawa', 'event-tickets' ),
501
+ 'JP38' => __( 'Ehime', 'event-tickets' ),
502
+ 'JP39' => __( 'Kochi', 'event-tickets' ),
503
+ 'JP40' => __( 'Fukuoka', 'event-tickets' ),
504
+ 'JP41' => __( 'Saga', 'event-tickets' ),
505
+ 'JP42' => __( 'Nagasaki', 'event-tickets' ),
506
+ 'JP43' => __( 'Kumamoto', 'event-tickets' ),
507
+ 'JP44' => __( 'Oita', 'event-tickets' ),
508
+ 'JP45' => __( 'Miyazaki', 'event-tickets' ),
509
+ 'JP46' => __( 'Kagoshima', 'event-tickets' ),
510
+ 'JP47' => __( 'Okinawa', 'event-tickets' ),
511
+ ];
512
+
513
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_japan_states', $states );
514
+ }
515
+
516
+ /**
517
+ * Get Italy States
518
+ *
519
+ * @since 5.2.0
520
+ *
521
+ * @return array $states A list of states
522
+ */
523
+ public function get_italy_list() {
524
+ $states = [
525
+ '' => '',
526
+ 'AG' => __( 'Agrigento', 'event-tickets' ),
527
+ 'AL' => __( 'Alessandria', 'event-tickets' ),
528
+ 'AN' => __( 'Ancona', 'event-tickets' ),
529
+ 'AO' => __( 'Aosta', 'event-tickets' ),
530
+ 'AR' => __( 'Arezzo', 'event-tickets' ),
531
+ 'AP' => __( 'Ascoli Piceno', 'event-tickets' ),
532
+ 'AT' => __( 'Asti', 'event-tickets' ),
533
+ 'AV' => __( 'Avellino', 'event-tickets' ),
534
+ 'BA' => __( 'Bari', 'event-tickets' ),
535
+ 'BT' => __( 'Barletta-Andria-Trani', 'event-tickets' ),
536
+ 'BL' => __( 'Belluno', 'event-tickets' ),
537
+ 'BN' => __( 'Benevento', 'event-tickets' ),
538
+ 'BG' => __( 'Bergamo', 'event-tickets' ),
539
+ 'BI' => __( 'Biella', 'event-tickets' ),
540
+ 'BO' => __( 'Bologna', 'event-tickets' ),
541
+ 'BZ' => __( 'Bolzano', 'event-tickets' ),
542
+ 'BS' => __( 'Brescia', 'event-tickets' ),
543
+ 'BR' => __( 'Brindisi', 'event-tickets' ),
544
+ 'CA' => __( 'Cagliari', 'event-tickets' ),
545
+ 'CL' => __( 'Caltanissetta', 'event-tickets' ),
546
+ 'CB' => __( 'Campobasso', 'event-tickets' ),
547
+ 'CI' => __( 'Carbonia-Iglesias', 'event-tickets' ),
548
+ 'CE' => __( 'Caserta', 'event-tickets' ),
549
+ 'CT' => __( 'Catania', 'event-tickets' ),
550
+ 'CZ' => __( 'Catanzaro', 'event-tickets' ),
551
+ 'CH' => __( 'Chieti', 'event-tickets' ),
552
+ 'CO' => __( 'Como', 'event-tickets' ),
553
+ 'CS' => __( 'Cosenza', 'event-tickets' ),
554
+ 'CR' => __( 'Cremona', 'event-tickets' ),
555
+ 'KR' => __( 'Crotone', 'event-tickets' ),
556
+ 'CN' => __( 'Cuneo', 'event-tickets' ),
557
+ 'EN' => __( 'Enna', 'event-tickets' ),
558
+ 'FM' => __( 'Fermo', 'event-tickets' ),
559
+ 'FE' => __( 'Ferrara', 'event-tickets' ),
560
+ 'FI' => __( 'Firenze', 'event-tickets' ),
561
+ 'FG' => __( 'Foggia', 'event-tickets' ),
562
+ 'FC' => __( 'Forlì-Cesena', 'event-tickets' ),
563
+ 'FR' => __( 'Frosinone', 'event-tickets' ),
564
+ 'GE' => __( 'Genova', 'event-tickets' ),
565
+ 'GO' => __( 'Gorizia', 'event-tickets' ),
566
+ 'GR' => __( 'Grosseto', 'event-tickets' ),
567
+ 'IM' => __( 'Imperia', 'event-tickets' ),
568
+ 'IS' => __( 'Isernia', 'event-tickets' ),
569
+ 'SP' => __( 'La Spezia', 'event-tickets' ),
570
+ 'AQ' => __( "L'Aquila", 'event-tickets' ),
571
+ 'LT' => __( 'Latina', 'event-tickets' ),
572
+ 'LE' => __( 'Lecce', 'event-tickets' ),
573
+ 'LC' => __( 'Lecco', 'event-tickets' ),
574
+ 'LI' => __( 'Livorno', 'event-tickets' ),
575
+ 'LO' => __( 'Lodi', 'event-tickets' ),
576
+ 'LU' => __( 'Lucca', 'event-tickets' ),
577
+ 'MC' => __( 'Macerata', 'event-tickets' ),
578
+ 'MN' => __( 'Mantova', 'event-tickets' ),
579
+ 'MS' => __( 'Massa-Carrara', 'event-tickets' ),
580
+ 'MT' => __( 'Matera', 'event-tickets' ),
581
+ 'ME' => __( 'Messina', 'event-tickets' ),
582
+ 'MI' => __( 'Milano', 'event-tickets' ),
583
+ 'MO' => __( 'Modena', 'event-tickets' ),
584
+ 'MB' => __( 'Monza e della Brianza', 'event-tickets' ),
585
+ 'NA' => __( 'Napoli', 'event-tickets' ),
586
+ 'NO' => __( 'Novara', 'event-tickets' ),
587
+ 'NU' => __( 'Nuoro', 'event-tickets' ),
588
+ 'OT' => __( 'Olbia-Tempio', 'event-tickets' ),
589
+ 'OR' => __( 'Oristano', 'event-tickets' ),
590
+ 'PD' => __( 'Padova', 'event-tickets' ),
591
+ 'PA' => __( 'Palermo', 'event-tickets' ),
592
+ 'PR' => __( 'Parma', 'event-tickets' ),
593
+ 'PV' => __( 'Pavia', 'event-tickets' ),
594
+ 'PG' => __( 'Perugia', 'event-tickets' ),
595
+ 'PU' => __( 'Pesaro e Urbino', 'event-tickets' ),
596
+ 'PE' => __( 'Pescara', 'event-tickets' ),
597
+ 'PC' => __( 'Piacenza', 'event-tickets' ),
598
+ 'PI' => __( 'Pisa', 'event-tickets' ),
599
+ 'PT' => __( 'Pistoia', 'event-tickets' ),
600
+ 'PN' => __( 'Pordenone', 'event-tickets' ),
601
+ 'PZ' => __( 'Potenza', 'event-tickets' ),
602
+ 'PO' => __( 'Prato', 'event-tickets' ),
603
+ 'RG' => __( 'Ragusa', 'event-tickets' ),
604
+ 'RA' => __( 'Ravenna', 'event-tickets' ),
605
+ 'RC' => __( 'Reggio Calabria', 'event-tickets' ),
606
+ 'RE' => __( 'Reggio Emilia', 'event-tickets' ),
607
+ 'RI' => __( 'Rieti', 'event-tickets' ),
608
+ 'RN' => __( 'Rimini', 'event-tickets' ),
609
+ 'RM' => __( 'Roma', 'event-tickets' ),
610
+ 'RO' => __( 'Rovigo', 'event-tickets' ),
611
+ 'SA' => __( 'Salerno', 'event-tickets' ),
612
+ 'VS' => __( 'Medio Campidano', 'event-tickets' ),
613
+ 'SS' => __( 'Sassari', 'event-tickets' ),
614
+ 'SV' => __( 'Savona', 'event-tickets' ),
615
+ 'SI' => __( 'Siena', 'event-tickets' ),
616
+ 'SR' => __( 'Siracusa', 'event-tickets' ),
617
+ 'SO' => __( 'Sondrio', 'event-tickets' ),
618
+ 'TA' => __( 'Taranto', 'event-tickets' ),
619
+ 'TE' => __( 'Teramo', 'event-tickets' ),
620
+ 'TR' => __( 'Terni', 'event-tickets' ),
621
+ 'TO' => __( 'Torino', 'event-tickets' ),
622
+ 'OG' => __( 'Ogliastra', 'event-tickets' ),
623
+ 'TP' => __( 'Trapani', 'event-tickets' ),
624
+ 'TN' => __( 'Trento', 'event-tickets' ),
625
+ 'TV' => __( 'Treviso', 'event-tickets' ),
626
+ 'TS' => __( 'Trieste', 'event-tickets' ),
627
+ 'UD' => __( 'Udine', 'event-tickets' ),
628
+ 'VA' => __( 'Varese', 'event-tickets' ),
629
+ 'VE' => __( 'Venezia', 'event-tickets' ),
630
+ 'VB' => __( 'Verbano-Cusio-Ossola', 'event-tickets' ),
631
+ 'VC' => __( 'Vercelli', 'event-tickets' ),
632
+ 'VR' => __( 'Verona', 'event-tickets' ),
633
+ 'VV' => __( 'Vibo Valentia', 'event-tickets' ),
634
+ 'VI' => __( 'Vicenza', 'event-tickets' ),
635
+ 'VT' => __( 'Viterbo', 'event-tickets' ),
636
+ ];
637
+
638
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_italy_states', $states );
639
+ }
640
+
641
+ /**
642
+ * Get Iran States
643
+ *
644
+ * @since 5.2.0
645
+ *
646
+ * @return array $states A list of states
647
+ */
648
+ public function get_iran_list() {
649
+ $states = [
650
+ '' => '',
651
+ 'KHZ' => __( 'Khuzestan (خوزستان)', 'event-tickets' ),
652
+ 'THR' => __( 'Tehran (تهران)', 'event-tickets' ),
653
+ 'ILM' => __( 'Ilaam (ایلام)', 'event-tickets' ),
654
+ 'BHR' => __( 'Bushehr (بوشهر)', 'event-tickets' ),
655
+ 'ADL' => __( 'Ardabil (اردبیل)', 'event-tickets' ),
656
+ 'ESF' => __( 'Isfahan (اصفهان)', 'event-tickets' ),
657
+ 'YZD' => __( 'Yazd (یزد)', 'event-tickets' ),
658
+ 'KRH' => __( 'Kermanshah (کرمانشاه)', 'event-tickets' ),
659
+ 'KRN' => __( 'Kerman (کرمان)', 'event-tickets' ),
660
+ 'HDN' => __( 'Hamadan (همدان)', 'event-tickets' ),
661
+ 'GZN' => __( 'Ghazvin (قزوین)', 'event-tickets' ),
662
+ 'ZJN' => __( 'Zanjan (زنجان)', 'event-tickets' ),
663
+ 'LRS' => __( 'Luristan (لرستان)', 'event-tickets' ),
664
+ 'ABZ' => __( 'Alborz (البرز)', 'event-tickets' ),
665
+ 'EAZ' => __( 'East Azarbaijan (آذربایجان شرقی)', 'event-tickets' ),
666
+ 'WAZ' => __( 'West Azarbaijan (آذربایجان غربی)', 'event-tickets' ),
667
+ 'CHB' => __( 'Chaharmahal and Bakhtiari (چهارمحال و بختیاری)', 'event-tickets' ),
668
+ 'SKH' => __( 'South Khorasan (خراسان جنوبی)', 'event-tickets' ),
669
+ 'RKH' => __( 'Razavi Khorasan (خراسان رضوی)', 'event-tickets' ),
670
+ 'NKH' => __( 'North Khorasan (خراسان جنوبی)', 'event-tickets' ),
671
+ 'SMN' => __( 'Semnan (سمنان)', 'event-tickets' ),
672
+ 'FRS' => __( 'Fars (فارس)', 'event-tickets' ),
673
+ 'QHM' => __( 'Qom (قم)', 'event-tickets' ),
674
+ 'KRD' => __( 'Kurdistan / کردستان)', 'event-tickets' ),
675
+ 'KBD' => __( 'Kohgiluyeh and BoyerAhmad (کهگیلوییه و بویراحمد)', 'event-tickets' ),
676
+ 'GLS' => __( 'Golestan (گلستان)', 'event-tickets' ),
677
+ 'GIL' => __( 'Gilan (گیلان)', 'event-tickets' ),
678
+ 'MZN' => __( 'Mazandaran (مازندران)', 'event-tickets' ),
679
+ 'MKZ' => __( 'Markazi (مرکزی)', 'event-tickets' ),
680
+ 'HRZ' => __( 'Hormozgan (هرمزگان)', 'event-tickets' ),
681
+ 'SBN' => __( 'Sistan and Baluchestan (سیستان و بلوچستان)', 'event-tickets' ),
682
+ ];
683
+
684
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_iran_states', $states );
685
+ }
686
+
687
+ /**
688
+ * Get Ireland States
689
+ *
690
+ * @since 5.2.0
691
+ *
692
+ * @return array $states A list of states
693
+ */
694
+ public function get_ireland_list() {
695
+ $states = [
696
+ '' => '',
697
+ 'AN' => __( 'Antrim', 'event-tickets' ),
698
+ 'AR' => __( 'Armagh', 'event-tickets' ),
699
+ 'CE' => __( 'Clare', 'event-tickets' ),
700
+ 'CK' => __( 'Cork', 'event-tickets' ),
701
+ 'CN' => __( 'Cavan', 'event-tickets' ),
702
+ 'CW' => __( 'Carlow', 'event-tickets' ),
703
+ 'DL' => __( 'Donegal', 'event-tickets' ),
704
+ 'DN' => __( 'Dublin', 'event-tickets' ),
705
+ 'DO' => __( 'Down', 'event-tickets' ),
706
+ 'DY' => __( 'Derry', 'event-tickets' ),
707
+ 'FM' => __( 'Fermanagh', 'event-tickets' ),
708
+ 'GY' => __( 'Galway', 'event-tickets' ),
709
+ 'KE' => __( 'Kildare', 'event-tickets' ),
710
+ 'KK' => __( 'Kilkenny', 'event-tickets' ),
711
+ 'KY' => __( 'Kerry', 'event-tickets' ),
712
+ 'LD' => __( 'Longford', 'event-tickets' ),
713
+ 'LH' => __( 'Louth', 'event-tickets' ),
714
+ 'LK' => __( 'Limerick', 'event-tickets' ),
715
+ 'LM' => __( 'Leitrim', 'event-tickets' ),
716
+ 'LS' => __( 'Laois', 'event-tickets' ),
717
+ 'MH' => __( 'Meath', 'event-tickets' ),
718
+ 'MN' => __( 'Monaghan', 'event-tickets' ),
719
+ 'MO' => __( 'Mayo', 'event-tickets' ),
720
+ 'OY' => __( 'Offaly', 'event-tickets' ),
721
+ 'RN' => __( 'Roscommon', 'event-tickets' ),
722
+ 'SO' => __( 'Sligo', 'event-tickets' ),
723
+ 'TR' => __( 'Tyrone', 'event-tickets' ),
724
+ 'TY' => __( 'Tipperary', 'event-tickets' ),
725
+ 'WD' => __( 'Waterford', 'event-tickets' ),
726
+ 'WH' => __( 'Westmeath', 'event-tickets' ),
727
+ 'WW' => __( 'Wicklow', 'event-tickets' ),
728
+ 'WX' => __( 'Wexford', 'event-tickets' ),
729
+ ];
730
+
731
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_ireland_states', $states );
732
+ }
733
+
734
+ /**
735
+ * Get Greek States
736
+ *
737
+ * @since 5.2.0
738
+ *
739
+ * @return array $states A list of states
740
+ */
741
+ public function get_greek_list() {
742
+ $states = [
743
+ '' => '',
744
+ 'I' => __( 'Αττική', 'event-tickets' ),
745
+ 'A' => __( 'Ανατολική Μακεδονία και Θράκη', 'event-tickets' ),
746
+ 'B' => __( 'Κεντρική Μακεδονία', 'event-tickets' ),
747
+ 'C' => __( 'Δυτική Μακεδονία', 'event-tickets' ),
748
+ 'D' => __( 'Ήπειρος', 'event-tickets' ),
749
+ 'E' => __( 'Θεσσαλία', 'event-tickets' ),
750
+ 'F' => __( 'Ιόνιοι Νήσοι', 'event-tickets' ),
751
+ 'G' => __( 'Δυτική Ελλάδα', 'event-tickets' ),
752
+ 'H' => __( 'Στερεά Ελλάδα', 'event-tickets' ),
753
+ 'J' => __( 'Πελοπόννησος', 'event-tickets' ),
754
+ 'K' => __( 'Βόρειο Αιγαίο', 'event-tickets' ),
755
+ 'L' => __( 'Νότιο Αιγαίο', 'event-tickets' ),
756
+ 'M' => __( 'Κρήτη', 'event-tickets' ),
757
+ ];
758
+
759
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_greek_states', $states );
760
+ }
761
+
762
+ /**
763
+ * Get bolivian States
764
+ *
765
+ * @since 5.2.0
766
+ *
767
+ * @return array $states A list of states
768
+ */
769
+ public function get_bolivian_list() {
770
+ $states = [
771
+ '' => '',
772
+ 'B' => __( 'Chuquisaca', 'event-tickets' ),
773
+ 'H' => __( 'Beni', 'event-tickets' ),
774
+ 'C' => __( 'Cochabamba', 'event-tickets' ),
775
+ 'L' => __( 'La Paz', 'event-tickets' ),
776
+ 'O' => __( 'Oruro', 'event-tickets' ),
777
+ 'N' => __( 'Pando', 'event-tickets' ),
778
+ 'P' => __( 'Potosí', 'event-tickets' ),
779
+ 'S' => __( 'Santa Cruz', 'event-tickets' ),
780
+ 'T' => __( 'Tarija', 'event-tickets' ),
781
+ ];
782
+
783
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_bolivian_states', $states );
784
+ }
785
+
786
+ /**
787
+ * Get Bulgarian States
788
+ *
789
+ * @since 5.2.0
790
+ *
791
+ * @return array $states A list of states
792
+ */
793
+ public function get_bulgarian_list() {
794
+ $states = [
795
+ '' => '',
796
+ 'BG-01' => __( 'Blagoevgrad', 'event-tickets' ),
797
+ 'BG-02' => __( 'Burgas', 'event-tickets' ),
798
+ 'BG-08' => __( 'Dobrich', 'event-tickets' ),
799
+ 'BG-07' => __( 'Gabrovo', 'event-tickets' ),
800
+ 'BG-26' => __( 'Haskovo', 'event-tickets' ),
801
+ 'BG-09' => __( 'Kardzhali', 'event-tickets' ),
802
+ 'BG-10' => __( 'Kyustendil', 'event-tickets' ),
803
+ 'BG-11' => __( 'Lovech', 'event-tickets' ),
804
+ 'BG-12' => __( 'Montana', 'event-tickets' ),
805
+ 'BG-13' => __( 'Pazardzhik', 'event-tickets' ),
806
+ 'BG-14' => __( 'Pernik', 'event-tickets' ),
807
+ 'BG-15' => __( 'Pleven', 'event-tickets' ),
808
+ 'BG-16' => __( 'Plovdiv', 'event-tickets' ),
809
+ 'BG-17' => __( 'Razgrad', 'event-tickets' ),
810
+ 'BG-18' => __( 'Ruse', 'event-tickets' ),
811
+ 'BG-27' => __( 'Shumen', 'event-tickets' ),
812
+ 'BG-19' => __( 'Silistra', 'event-tickets' ),
813
+ 'BG-20' => __( 'Sliven', 'event-tickets' ),
814
+ 'BG-21' => __( 'Smolyan', 'event-tickets' ),
815
+ 'BG-23' => __( 'Sofia', 'event-tickets' ),
816
+ 'BG-22' => __( 'Sofia-Grad', 'event-tickets' ),
817
+ 'BG-24' => __( 'Stara Zagora', 'event-tickets' ),
818
+ 'BG-25' => __( 'Targovishte', 'event-tickets' ),
819
+ 'BG-03' => __( 'Varna', 'event-tickets' ),
820
+ 'BG-04' => __( 'Veliko Tarnovo', 'event-tickets' ),
821
+ 'BG-05' => __( 'Vidin', 'event-tickets' ),
822
+ 'BG-06' => __( 'Vratsa', 'event-tickets' ),
823
+ 'BG-28' => __( 'Yambol', 'event-tickets' ),
824
+ ];
825
+
826
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_bulgarian_states', $states );
827
+ }
828
+
829
+ /**
830
+ * Get Bangladeshi States
831
+ *
832
+ * @since 5.2.0
833
+ *
834
+ * @return array $states A list of states
835
+ */
836
+ public function get_bangladeshi_list() {
837
+ $states = [
838
+ '' => '',
839
+ 'BAG' => __( 'Bagerhat', 'event-tickets' ),
840
+ 'BAN' => __( 'Bandarban', 'event-tickets' ),
841
+ 'BAR' => __( 'Barguna', 'event-tickets' ),
842
+ 'BARI' => __( 'Barisal', 'event-tickets' ),
843
+ 'BHO' => __( 'Bhola', 'event-tickets' ),
844
+ 'BOG' => __( 'Bogra', 'event-tickets' ),
845
+ 'BRA' => __( 'Brahmanbaria', 'event-tickets' ),
846
+ 'CHA' => __( 'Chandpur', 'event-tickets' ),
847
+ 'CHI' => __( 'Chittagong', 'event-tickets' ),
848
+ 'CHU' => __( 'Chuadanga', 'event-tickets' ),
849
+ 'COM' => __( 'Comilla', 'event-tickets' ),
850
+ 'COX' => __( "Cox's Bazar", 'event-tickets' ),
851
+ 'DHA' => __( 'Dhaka', 'event-tickets' ),
852
+ 'DIN' => __( 'Dinajpur', 'event-tickets' ),
853
+ 'FAR' => __( 'Faridpur ', 'event-tickets' ),
854
+ 'FEN' => __( 'Feni', 'event-tickets' ),
855
+ 'GAI' => __( 'Gaibandha', 'event-tickets' ),
856
+ 'GAZI' => __( 'Gazipur', 'event-tickets' ),
857
+ 'GOP' => __( 'Gopalganj', 'event-tickets' ),
858
+ 'HAB' => __( 'Habiganj', 'event-tickets' ),
859
+ 'JAM' => __( 'Jamalpur', 'event-tickets' ),
860
+ 'JES' => __( 'Jessore', 'event-tickets' ),
861
+ 'JHA' => __( 'Jhalokati', 'event-tickets' ),
862
+ 'JHE' => __( 'Jhenaidah', 'event-tickets' ),
863
+ 'JOY' => __( 'Joypurhat', 'event-tickets' ),
864
+ 'KHA' => __( 'Khagrachhari', 'event-tickets' ),
865
+ 'KHU' => __( 'Khulna', 'event-tickets' ),
866
+ 'KIS' => __( 'Kishoreganj', 'event-tickets' ),
867
+ 'KUR' => __( 'Kurigram', 'event-tickets' ),
868
+ 'KUS' => __( 'Kushtia', 'event-tickets' ),
869
+ 'LAK' => __( 'Lakshmipur', 'event-tickets' ),
870
+ 'LAL' => __( 'Lalmonirhat', 'event-tickets' ),
871
+ 'MAD' => __( 'Madaripur', 'event-tickets' ),
872
+ 'MAG' => __( 'Magura', 'event-tickets' ),
873
+ 'MAN' => __( 'Manikganj ', 'event-tickets' ),
874
+ 'MEH' => __( 'Meherpur', 'event-tickets' ),
875
+ 'MOU' => __( 'Moulvibazar', 'event-tickets' ),
876
+ 'MUN' => __( 'Munshiganj', 'event-tickets' ),
877
+ 'MYM' => __( 'Mymensingh', 'event-tickets' ),
878
+ 'NAO' => __( 'Naogaon', 'event-tickets' ),
879
+ 'NAR' => __( 'Narail', 'event-tickets' ),
880
+ 'NARG' => __( 'Narayanganj', 'event-tickets' ),
881
+ 'NARD' => __( 'Narsingdi', 'event-tickets' ),
882
+ 'NAT' => __( 'Natore', 'event-tickets' ),
883
+ 'NAW' => __( 'Nawabganj', 'event-tickets' ),
884
+ 'NET' => __( 'Netrakona', 'event-tickets' ),
885
+ 'NIL' => __( 'Nilphamari', 'event-tickets' ),
886
+ 'NOA' => __( 'Noakhali', 'event-tickets' ),
887
+ 'PAB' => __( 'Pabna', 'event-tickets' ),
888
+ 'PAN' => __( 'Panchagarh', 'event-tickets' ),
889
+ 'PAT' => __( 'Patuakhali', 'event-tickets' ),
890
+ 'PIR' => __( 'Pirojpur', 'event-tickets' ),
891
+ 'RAJB' => __( 'Rajbari', 'event-tickets' ),
892
+ 'RAJ' => __( 'Rajshahi', 'event-tickets' ),
893
+ 'RAN' => __( 'Rangamati', 'event-tickets' ),
894
+ 'RANP' => __( 'Rangpur', 'event-tickets' ),
895
+ 'SAT' => __( 'Satkhira', 'event-tickets' ),
896
+ 'SHA' => __( 'Shariatpur', 'event-tickets' ),
897
+ 'SHE' => __( 'Sherpur', 'event-tickets' ),
898
+ 'SIR' => __( 'Sirajganj', 'event-tickets' ),
899
+ 'SUN' => __( 'Sunamganj', 'event-tickets' ),
900
+ 'SYL' => __( 'Sylhet', 'event-tickets' ),
901
+ 'TAN' => __( 'Tangail', 'event-tickets' ),
902
+ 'THA' => __( 'Thakurgaon', 'event-tickets' ),
903
+ ];
904
+
905
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_bangladeshi_states', $states );
906
+ }
907
+
908
+ /**
909
+ * Get Argentina States
910
+ *
911
+ * @since 5.2.0
912
+ *
913
+ * @return array $states A list of states
914
+ */
915
+ public function get_argentina_list() {
916
+ $states = [
917
+ '' => '',
918
+ 'C' => __( 'Ciudad Aut&oacute;noma de Buenos Aires', 'event-tickets' ),
919
+ 'B' => __( 'Buenos Aires', 'event-tickets' ),
920
+ 'K' => __( 'Catamarca', 'event-tickets' ),
921
+ 'H' => __( 'Chaco', 'event-tickets' ),
922
+ 'U' => __( 'Chubut', 'event-tickets' ),
923
+ 'X' => __( 'C&oacute;rdoba', 'event-tickets' ),
924
+ 'W' => __( 'Corrientes', 'event-tickets' ),
925
+ 'E' => __( 'Entre R&iacute;os', 'event-tickets' ),
926
+ 'P' => __( 'Formosa', 'event-tickets' ),
927
+ 'Y' => __( 'Jujuy', 'event-tickets' ),
928
+ 'L' => __( 'La Pampa', 'event-tickets' ),
929
+ 'F' => __( 'La Rioja', 'event-tickets' ),
930
+ 'M' => __( 'Mendoza', 'event-tickets' ),
931
+ 'N' => __( 'Misiones', 'event-tickets' ),
932
+ 'Q' => __( 'Neuqu&eacute;n', 'event-tickets' ),
933
+ 'R' => __( 'R&iacute;o Negro', 'event-tickets' ),
934
+ 'A' => __( 'Salta', 'event-tickets' ),
935
+ 'J' => __( 'San Juan', 'event-tickets' ),
936
+ 'D' => __( 'San Luis', 'event-tickets' ),
937
+ 'Z' => __( 'Santa Cruz', 'event-tickets' ),
938
+ 'S' => __( 'Santa Fe', 'event-tickets' ),
939
+ 'G' => __( 'Santiago del Estero', 'event-tickets' ),
940
+ 'V' => __( 'Tierra del Fuego', 'event-tickets' ),
941
+ 'T' => __( 'Tucum&aacute;n', 'event-tickets' ),
942
+ ];
943
+
944
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_argentina_states', $states );
945
+ }
946
+
947
+ /**
948
+ * Get States List
949
+ *
950
+ * @since 5.2.0
951
+ *
952
+ * @return array
953
+ */
954
+ public function get_us_list() {
955
+ $states = [
956
+ '' => '',
957
+ 'AL' => 'Alabama',
958
+ 'AK' => 'Alaska',
959
+ 'AZ' => 'Arizona',
960
+ 'AR' => 'Arkansas',
961
+ 'CA' => 'California',
962
+ 'CO' => 'Colorado',
963
+ 'CT' => 'Connecticut',
964
+ 'DE' => 'Delaware',
965
+ 'DC' => 'District of Columbia',
966
+ 'FL' => 'Florida',
967
+ 'GA' => 'Georgia',
968
+ 'HI' => 'Hawaii',
969
+ 'ID' => 'Idaho',
970
+ 'IL' => 'Illinois',
971
+ 'IN' => 'Indiana',
972
+ 'IA' => 'Iowa',
973
+ 'KS' => 'Kansas',
974
+ 'KY' => 'Kentucky',
975
+ 'LA' => 'Louisiana',
976
+ 'ME' => 'Maine',
977
+ 'MD' => 'Maryland',
978
+ 'MA' => 'Massachusetts',
979
+ 'MI' => 'Michigan',
980
+ 'MN' => 'Minnesota',
981
+ 'MS' => 'Mississippi',
982
+ 'MO' => 'Missouri',
983
+ 'MT' => 'Montana',
984
+ 'NE' => 'Nebraska',
985
+ 'NV' => 'Nevada',
986
+ 'NH' => 'New Hampshire',
987
+ 'NJ' => 'New Jersey',
988
+ 'NM' => 'New Mexico',
989
+ 'NY' => 'New York',
990
+ 'NC' => 'North Carolina',
991
+ 'ND' => 'North Dakota',
992
+ 'OH' => 'Ohio',
993
+ 'OK' => 'Oklahoma',
994
+ 'OR' => 'Oregon',
995
+ 'PA' => 'Pennsylvania',
996
+ 'RI' => 'Rhode Island',
997
+ 'SC' => 'South Carolina',
998
+ 'SD' => 'South Dakota',
999
+ 'TN' => 'Tennessee',
1000
+ 'TX' => 'Texas',
1001
+ 'UT' => 'Utah',
1002
+ 'VT' => 'Vermont',
1003
+ 'VA' => 'Virginia',
1004
+ 'WA' => 'Washington',
1005
+ 'WV' => 'West Virginia',
1006
+ 'WI' => 'Wisconsin',
1007
+ 'WY' => 'Wyoming',
1008
+ 'AS' => 'American Samoa',
1009
+ 'CZ' => 'Canal Zone',
1010
+ 'CM' => 'Commonwealth of the Northern Mariana Islands',
1011
+ 'FM' => 'Federated States of Micronesia',
1012
+ 'GU' => 'Guam',
1013
+ 'MH' => 'Marshall Islands',
1014
+ 'MP' => 'Northern Mariana Islands',
1015
+ 'PW' => 'Palau',
1016
+ 'PI' => 'Philippine Islands',
1017
+ 'PR' => 'Puerto Rico',
1018
+ 'TT' => 'Trust Territory of the Pacific Islands',
1019
+ 'VI' => 'Virgin Islands',
1020
+ 'AA' => 'Armed Forces - Americas',
1021
+ 'AE' => 'Armed Forces - Europe, Canada, Middle East, Africa',
1022
+ 'AP' => 'Armed Forces - Pacific',
1023
+ ];
1024
+
1025
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_us_states', $states );
1026
+ }
1027
+
1028
+ /**
1029
+ * Get Provinces List
1030
+ *
1031
+ * @since 5.2.0
1032
+ *
1033
+ * @return array
1034
+ */
1035
+ public function get_provinces_list() {
1036
+ $provinces = [
1037
+ '' => '',
1038
+ 'AB' => esc_html__( 'Alberta', 'event-tickets' ),
1039
+ 'BC' => esc_html__( 'British Columbia', 'event-tickets' ),
1040
+ 'MB' => esc_html__( 'Manitoba', 'event-tickets' ),
1041
+ 'NB' => esc_html__( 'New Brunswick', 'event-tickets' ),
1042
+ 'NL' => esc_html__( 'Newfoundland and Labrador', 'event-tickets' ),
1043
+ 'NS' => esc_html__( 'Nova Scotia', 'event-tickets' ),
1044
+ 'NT' => esc_html__( 'Northwest Territories', 'event-tickets' ),
1045
+ 'NU' => esc_html__( 'Nunavut', 'event-tickets' ),
1046
+ 'ON' => esc_html__( 'Ontario', 'event-tickets' ),
1047
+ 'PE' => esc_html__( 'Prince Edward Island', 'event-tickets' ),
1048
+ 'QC' => esc_html__( 'Quebec', 'event-tickets' ),
1049
+ 'SK' => esc_html__( 'Saskatchewan', 'event-tickets' ),
1050
+ 'YT' => esc_html__( 'Yukon', 'event-tickets' ),
1051
+ ];
1052
+
1053
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_canada_provinces', $provinces );
1054
+ }
1055
+
1056
+ /**
1057
+ * Get Australian States
1058
+ *
1059
+ * @since 5.2.0
1060
+ *
1061
+ * @return array $states A list of states
1062
+ */
1063
+ public function get_australian_list() {
1064
+ $states = [
1065
+ '' => '',
1066
+ 'ACT' => 'Australian Capital Territory',
1067
+ 'NSW' => 'New South Wales',
1068
+ 'NT' => 'Northern Territory',
1069
+ 'QLD' => 'Queensland',
1070
+ 'SA' => 'South Australia',
1071
+ 'TAS' => 'Tasmania',
1072
+ 'VIC' => 'Victoria',
1073
+ 'WA' => 'Western Australia',
1074
+ ];
1075
+
1076
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_australian_states', $states );
1077
+ }
1078
+
1079
+ /**
1080
+ * Get Brazil States
1081
+ *
1082
+ * @since 5.2.0
1083
+ *
1084
+ * @return array $states A list of states
1085
+ */
1086
+ public function get_brazil_list() {
1087
+ $states = [
1088
+ '' => '',
1089
+ 'AC' => 'Acre',
1090
+ 'AL' => 'Alagoas',
1091
+ 'AP' => 'Amap&aacute;',
1092
+ 'AM' => 'Amazonas',
1093
+ 'BA' => 'Bahia',
1094
+ 'CE' => 'Cear&aacute;',
1095
+ 'DF' => 'Distrito Federal',
1096
+ 'ES' => 'Esp&iacute;rito Santo',
1097
+ 'GO' => 'Goi&aacute;s',
1098
+ 'MA' => 'Maranh&atilde;o',
1099
+ 'MT' => 'Mato Grosso',
1100
+ 'MS' => 'Mato Grosso do Sul',
1101
+ 'MG' => 'Minas Gerais',
1102
+ 'PA' => 'Par&aacute;',
1103
+ 'PB' => 'Para&iacute;ba',
1104
+ 'PR' => 'Paran&aacute;',
1105
+ 'PE' => 'Pernambuco',
1106
+ 'PI' => 'Piau&iacute;',
1107
+ 'RJ' => 'Rio de Janeiro',
1108
+ 'RN' => 'Rio Grande do Norte',
1109
+ 'RS' => 'Rio Grande do Sul',
1110
+ 'RO' => 'Rond&ocirc;nia',
1111
+ 'RR' => 'Roraima',
1112
+ 'SC' => 'Santa Catarina',
1113
+ 'SP' => 'S&atilde;o Paulo',
1114
+ 'SE' => 'Sergipe',
1115
+ 'TO' => 'Tocantins',
1116
+ ];
1117
+
1118
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_brazil_states', $states );
1119
+ }
1120
+
1121
+ /**
1122
+ * Get Hong Kong States
1123
+ *
1124
+ * @since 5.2.0
1125
+ *
1126
+ * @return array $states A list of states
1127
+ */
1128
+ public function get_hong_kong_list() {
1129
+ $states = [
1130
+ '' => '',
1131
+ 'HONG KONG' => 'Hong Kong Island',
1132
+ 'KOWLOON' => 'Kowloon',
1133
+ 'NEW TERRITORIES' => 'New Territories',
1134
+ ];
1135
+
1136
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_hong_kong_states', $states );
1137
+ }
1138
+
1139
+ /**
1140
+ * Get Hungary States
1141
+ *
1142
+ * @since 5.2.0
1143
+ *
1144
+ * @return array $states A list of states
1145
+ */
1146
+ public function get_hungary_list() {
1147
+ $states = [
1148
+ '' => '',
1149
+ 'BK' => 'Bács-Kiskun',
1150
+ 'BE' => 'Békés',
1151
+ 'BA' => 'Baranya',
1152
+ 'BZ' => 'Borsod-Abaúj-Zemplén',
1153
+ 'BU' => 'Budapest',
1154
+ 'CS' => 'Csongrád',
1155
+ 'FE' => 'Fejér',
1156
+ 'GS' => 'Győr-Moson-Sopron',
1157
+ 'HB' => 'Hajdú-Bihar',
1158
+ 'HE' => 'Heves',
1159
+ 'JN' => 'Jász-Nagykun-Szolnok',
1160
+ 'KE' => 'Komárom-Esztergom',
1161
+ 'NO' => 'Nógrád',
1162
+ 'PE' => 'Pest',
1163
+ 'SO' => 'Somogy',
1164
+ 'SZ' => 'Szabolcs-Szatmár-Bereg',
1165
+ 'TO' => 'Tolna',
1166
+ 'VA' => 'Vas',
1167
+ 'VE' => 'Veszprém',
1168
+ 'ZA' => 'Zala',
1169
+ ];
1170
+
1171
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_hungary_states', $states );
1172
+ }
1173
+
1174
+ /**
1175
+ * Get Chinese States
1176
+ *
1177
+ * @since 5.2.0
1178
+ *
1179
+ * @return array $states A list of states
1180
+ */
1181
+ public function get_chinese_list() {
1182
+ $states = [
1183
+ '' => '',
1184
+ 'CN1' => 'Yunnan / &#20113;&#21335;',
1185
+ 'CN2' => 'Beijing / &#21271;&#20140;',
1186
+ 'CN3' => 'Tianjin / &#22825;&#27941;',
1187
+ 'CN4' => 'Hebei / &#27827;&#21271;',
1188
+ 'CN5' => 'Shanxi / &#23665;&#35199;',
1189
+ 'CN6' => 'Inner Mongolia / &#20839;&#33945;&#21476;',
1190
+ 'CN7' => 'Liaoning / &#36797;&#23425;',
1191
+ 'CN8' => 'Jilin / &#21513;&#26519;',
1192
+ 'CN9' => 'Heilongjiang / &#40657;&#40857;&#27743;',
1193
+ 'CN10' => 'Shanghai / &#19978;&#28023;',
1194
+ 'CN11' => 'Jiangsu / &#27743;&#33487;',
1195
+ 'CN12' => 'Zhejiang / &#27993;&#27743;',
1196
+ 'CN13' => 'Anhui / &#23433;&#24509;',
1197
+ 'CN14' => 'Fujian / &#31119;&#24314;',
1198
+ 'CN15' => 'Jiangxi / &#27743;&#35199;',
1199
+ 'CN16' => 'Shandong / &#23665;&#19996;',
1200
+ 'CN17' => 'Henan / &#27827;&#21335;',
1201
+ 'CN18' => 'Hubei / &#28246;&#21271;',
1202
+ 'CN19' => 'Hunan / &#28246;&#21335;',
1203
+ 'CN20' => 'Guangdong / &#24191;&#19996;',
1204
+ 'CN21' => 'Guangxi Zhuang / &#24191;&#35199;&#22766;&#26063;',
1205
+ 'CN22' => 'Hainan / &#28023;&#21335;',
1206
+ 'CN23' => 'Chongqing / &#37325;&#24198;',
1207
+ 'CN24' => 'Sichuan / &#22235;&#24029;',
1208
+ 'CN25' => 'Guizhou / &#36149;&#24030;',
1209
+ 'CN26' => 'Shaanxi / &#38485;&#35199;',
1210
+ 'CN27' => 'Gansu / &#29976;&#32899;',
1211
+ 'CN28' => 'Qinghai / &#38738;&#28023;',
1212
+ 'CN29' => 'Ningxia Hui / &#23425;&#22799;',
1213
+ 'CN30' => 'Macau / &#28595;&#38376;',
1214
+ 'CN31' => 'Tibet / &#35199;&#34255;',
1215
+ 'CN32' => 'Xinjiang / &#26032;&#30086;',
1216
+ ];
1217
+
1218
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_chinese_states', $states );
1219
+ }
1220
+
1221
+ /**
1222
+ * Get New Zealand States
1223
+ *
1224
+ * @since 5.2.0
1225
+ *
1226
+ * @return array $states A list of states
1227
+ */
1228
+ public function get_new_zealand_list() {
1229
+ $states = [
1230
+ '' => '',
1231
+ 'AK' => 'Auckland',
1232
+ 'BP' => 'Bay of Plenty',
1233
+ 'CT' => 'Canterbury',
1234
+ 'HB' => 'Hawke&rsquo;s Bay',
1235
+ 'MW' => 'Manawatu-Wanganui',
1236
+ 'MB' => 'Marlborough',
1237
+ 'NS' => 'Nelson',
1238
+ 'NL' => 'Northland',
1239
+ 'OT' => 'Otago',
1240
+ 'SL' => 'Southland',
1241
+ 'TK' => 'Taranaki',
1242
+ 'TM' => 'Tasman',
1243
+ 'WA' => 'Waikato',
1244
+ 'WE' => 'Wellington',
1245
+ 'WC' => 'West Coast',
1246
+ ];
1247
+
1248
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_new_zealand_states', $states );
1249
+ }
1250
+
1251
+ /**
1252
+ * Get Indonesian States
1253
+ *
1254
+ * @since 5.2.0
1255
+ *
1256
+ * @return array $states A list of states
1257
+ */
1258
+ public function get_indonesian_list() {
1259
+ $states = [
1260
+ '' => '',
1261
+ 'AC' => 'Daerah Istimewa Aceh',
1262
+ 'SU' => 'Sumatera Utara',
1263
+ 'SB' => 'Sumatera Barat',
1264
+ 'RI' => 'Riau',
1265
+ 'KR' => 'Kepulauan Riau',
1266
+ 'JA' => 'Jambi',
1267
+ 'SS' => 'Sumatera Selatan',
1268
+ 'BB' => 'Bangka Belitung',
1269
+ 'BE' => 'Bengkulu',
1270
+ 'LA' => 'Lampung',
1271
+ 'JK' => 'DKI Jakarta',
1272
+ 'JB' => 'Jawa Barat',
1273
+ 'BT' => 'Banten',
1274
+ 'JT' => 'Jawa Tengah',
1275
+ 'JI' => 'Jawa Timur',
1276
+ 'YO' => 'Daerah Istimewa Yogyakarta',
1277
+ 'BA' => 'Bali',
1278
+ 'NB' => 'Nusa Tenggara Barat',
1279
+ 'NT' => 'Nusa Tenggara Timur',
1280
+ 'KB' => 'Kalimantan Barat',
1281
+ 'KT' => 'Kalimantan Tengah',
1282
+ 'KI' => 'Kalimantan Timur',
1283
+ 'KS' => 'Kalimantan Selatan',
1284
+ 'KU' => 'Kalimantan Utara',
1285
+ 'SA' => 'Sulawesi Utara',
1286
+ 'ST' => 'Sulawesi Tengah',
1287
+ 'SG' => 'Sulawesi Tenggara',
1288
+ 'SR' => 'Sulawesi Barat',
1289
+ 'SN' => 'Sulawesi Selatan',
1290
+ 'GO' => 'Gorontalo',
1291
+ 'MA' => 'Maluku',
1292
+ 'MU' => 'Maluku Utara',
1293
+ 'PA' => 'Papua',
1294
+ 'PB' => 'Papua Barat',
1295
+ ];
1296
+
1297
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_indonesia_states', $states );
1298
+ }
1299
+
1300
+ /**
1301
+ * Get Indian States
1302
+ *
1303
+ * @since 5.2.0
1304
+ *
1305
+ *
1306
+ * @return array $states A list of states
1307
+ */
1308
+ public function get_indian_list() {
1309
+ $states = [
1310
+ '' => '',
1311
+ 'AP' => 'Andhra Pradesh',
1312
+ 'AR' => 'Arunachal Pradesh',
1313
+ 'AS' => 'Assam',
1314
+ 'BR' => 'Bihar',
1315
+ 'CT' => 'Chhattisgarh',
1316
+ 'GA' => 'Goa',
1317
+ 'GJ' => 'Gujarat',
1318
+ 'HR' => 'Haryana',
1319
+ 'HP' => 'Himachal Pradesh',
1320
+ 'JK' => 'Jammu and Kashmir',
1321
+ 'JH' => 'Jharkhand',
1322
+ 'KA' => 'Karnataka',
1323
+ 'KL' => 'Kerala',
1324
+ 'MP' => 'Madhya Pradesh',
1325
+ 'MH' => 'Maharashtra',
1326
+ 'MN' => 'Manipur',
1327
+ 'ML' => 'Meghalaya',
1328
+ 'MZ' => 'Mizoram',
1329
+ 'NL' => 'Nagaland',
1330
+ 'OR' => 'Odisha',
1331
+ 'PB' => 'Punjab',
1332
+ 'RJ' => 'Rajasthan',
1333
+ 'SK' => 'Sikkim',
1334
+ 'TN' => 'Tamil Nadu',
1335
+ 'TG' => 'Telangana',
1336
+ 'TR' => 'Tripura',
1337
+ 'UT' => 'Uttarakhand',
1338
+ 'UP' => 'Uttar Pradesh',
1339
+ 'WB' => 'West Bengal',
1340
+ 'AN' => 'Andaman and Nicobar Islands',
1341
+ 'CH' => 'Chandigarh',
1342
+ 'DN' => 'Dadar and Nagar Haveli',
1343
+ 'DD' => 'Daman and Diu',
1344
+ 'DL' => 'Delhi',
1345
+ 'LD' => 'Lakshadweep',
1346
+ 'PY' => 'Pondicherry (Puducherry)',
1347
+ ];
1348
+
1349
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_indian_states', $states );
1350
+ }
1351
+
1352
+ /**
1353
+ * Get Malaysian States
1354
+ *
1355
+ * @since 5.2.0
1356
+ *
1357
+ * @return array $states A list of states
1358
+ */
1359
+ public function get_malaysian_list() {
1360
+ $states = [
1361
+ '' => '',
1362
+ 'JHR' => 'Johor',
1363
+ 'KDH' => 'Kedah',
1364
+ 'KTN' => 'Kelantan',
1365
+ 'MLK' => 'Melaka',
1366
+ 'NSN' => 'Negeri Sembilan',
1367
+ 'PHG' => 'Pahang',
1368
+ 'PRK' => 'Perak',
1369
+ 'PLS' => 'Perlis',
1370
+ 'PNG' => 'Pulau Pinang',
1371
+ 'SBH' => 'Sabah',
1372
+ 'SWK' => 'Sarawak',
1373
+ 'SGR' => 'Selangor',
1374
+ 'TRG' => 'Terengganu',
1375
+ 'KUL' => 'W.P. Kuala Lumpur',
1376
+ 'LBN' => 'W.P. Labuan',
1377
+ 'PJY' => 'W.P. Putrajaya',
1378
+ ];
1379
+
1380
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_malaysian_states', $states );
1381
+ }
1382
+
1383
+ /**
1384
+ * Get South African States
1385
+ *
1386
+ * @since 5.2.0
1387
+ *
1388
+ * @return array $states A list of states
1389
+ */
1390
+ public function get_south_african_list() {
1391
+ $states = [
1392
+ '' => '',
1393
+ 'EC' => 'Eastern Cape',
1394
+ 'FS' => 'Free State',
1395
+ 'GP' => 'Gauteng',
1396
+ 'KZN' => 'KwaZulu-Natal',
1397
+ 'LP' => 'Limpopo',
1398
+ 'MP' => 'Mpumalanga',
1399
+ 'NC' => 'Northern Cape',
1400
+ 'NW' => 'North West',
1401
+ 'WC' => 'Western Cape',
1402
+ ];
1403
+
1404
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_south_african_states', $states );
1405
+ }
1406
+
1407
+ /**
1408
+ * Get Thailand States
1409
+ *
1410
+ * @since 5.2.0
1411
+ *
1412
+ * @return array $states A list of states
1413
+ */
1414
+ public function get_thailand_list() {
1415
+ $states = [
1416
+ '' => '',
1417
+ 'TH-37' => 'Amnat Charoen (&#3629;&#3635;&#3609;&#3634;&#3592;&#3648;&#3592;&#3619;&#3636;&#3597;)',
1418
+ 'TH-15' => 'Ang Thong (&#3629;&#3656;&#3634;&#3591;&#3607;&#3629;&#3591;)',
1419
+ 'TH-14' => 'Ayutthaya (&#3614;&#3619;&#3632;&#3609;&#3588;&#3619;&#3624;&#3619;&#3637;&#3629;&#3618;&#3640;&#3608;&#3618;&#3634;)',
1420
+ 'TH-10' => 'Bangkok (&#3585;&#3619;&#3640;&#3591;&#3648;&#3607;&#3614;&#3617;&#3627;&#3634;&#3609;&#3588;&#3619;)',
1421
+ 'TH-38' => 'Bueng Kan (&#3610;&#3638;&#3591;&#3585;&#3634;&#3628;)',
1422
+ 'TH-31' => 'Buri Ram (&#3610;&#3640;&#3619;&#3637;&#3619;&#3633;&#3617;&#3618;&#3660;)',
1423
+ 'TH-24' => 'Chachoengsao (&#3593;&#3632;&#3648;&#3594;&#3636;&#3591;&#3648;&#3607;&#3619;&#3634;)',
1424
+ 'TH-18' => 'Chai Nat (&#3594;&#3633;&#3618;&#3609;&#3634;&#3607;)',
1425
+ 'TH-36' => 'Chaiyaphum (&#3594;&#3633;&#3618;&#3616;&#3641;&#3617;&#3636;)',
1426
+ 'TH-22' => 'Chanthaburi (&#3592;&#3633;&#3609;&#3607;&#3610;&#3640;&#3619;&#3637;)',
1427
+ 'TH-50' => 'Chiang Mai (&#3648;&#3594;&#3637;&#3618;&#3591;&#3651;&#3627;&#3617;&#3656;)',
1428
+ 'TH-57' => 'Chiang Rai (&#3648;&#3594;&#3637;&#3618;&#3591;&#3619;&#3634;&#3618;)',
1429
+ 'TH-20' => 'Chonburi (&#3594;&#3621;&#3610;&#3640;&#3619;&#3637;)',
1430
+ 'TH-86' => 'Chumphon (&#3594;&#3640;&#3617;&#3614;&#3619;)',
1431
+ 'TH-46' => 'Kalasin (&#3585;&#3634;&#3628;&#3626;&#3636;&#3609;&#3608;&#3640;&#3660;)',
1432
+ 'TH-62' => 'Kamphaeng Phet (&#3585;&#3635;&#3649;&#3614;&#3591;&#3648;&#3614;&#3594;&#3619;)',
1433
+ 'TH-71' => 'Kanchanaburi (&#3585;&#3634;&#3597;&#3592;&#3609;&#3610;&#3640;&#3619;&#3637;)',
1434
+ 'TH-40' => 'Khon Kaen (&#3586;&#3629;&#3609;&#3649;&#3585;&#3656;&#3609;)',
1435
+ 'TH-81' => 'Krabi (&#3585;&#3619;&#3632;&#3610;&#3637;&#3656;)',
1436
+ 'TH-52' => 'Lampang (&#3621;&#3635;&#3611;&#3634;&#3591;)',
1437
+ 'TH-51' => 'Lamphun (&#3621;&#3635;&#3614;&#3641;&#3609;)',
1438
+ 'TH-42' => 'Loei (&#3648;&#3621;&#3618;)',
1439
+ 'TH-16' => 'Lopburi (&#3621;&#3614;&#3610;&#3640;&#3619;&#3637;)',
1440
+ 'TH-58' => 'Mae Hong Son (&#3649;&#3617;&#3656;&#3630;&#3656;&#3629;&#3591;&#3626;&#3629;&#3609;)',
1441
+ 'TH-44' => 'Maha Sarakham (&#3617;&#3627;&#3634;&#3626;&#3634;&#3619;&#3588;&#3634;&#3617;)',
1442
+ 'TH-49' => 'Mukdahan (&#3617;&#3640;&#3585;&#3604;&#3634;&#3627;&#3634;&#3619;)',
1443
+ 'TH-26' => 'Nakhon Nayok (&#3609;&#3588;&#3619;&#3609;&#3634;&#3618;&#3585;)',
1444
+ 'TH-73' => 'Nakhon Pathom (&#3609;&#3588;&#3619;&#3611;&#3600;&#3617;)',
1445
+ 'TH-48' => 'Nakhon Phanom (&#3609;&#3588;&#3619;&#3614;&#3609;&#3617;)',
1446
+ 'TH-30' => 'Nakhon Ratchasima (&#3609;&#3588;&#3619;&#3619;&#3634;&#3594;&#3626;&#3637;&#3617;&#3634;)',
1447
+ 'TH-60' => 'Nakhon Sawan (&#3609;&#3588;&#3619;&#3626;&#3623;&#3619;&#3619;&#3588;&#3660;)',
1448
+ 'TH-80' => 'Nakhon Si Thammarat (&#3609;&#3588;&#3619;&#3624;&#3619;&#3637;&#3608;&#3619;&#3619;&#3617;&#3619;&#3634;&#3594;)',
1449
+ 'TH-55' => 'Nan (&#3609;&#3656;&#3634;&#3609;)',
1450
+ 'TH-96' => 'Narathiwat (&#3609;&#3619;&#3634;&#3608;&#3636;&#3623;&#3634;&#3626;)',
1451
+ 'TH-39' => 'Nong Bua Lam Phu (&#3627;&#3609;&#3629;&#3591;&#3610;&#3633;&#3623;&#3621;&#3635;&#3616;&#3641;)',
1452
+ 'TH-43' => 'Nong Khai (&#3627;&#3609;&#3629;&#3591;&#3588;&#3634;&#3618;)',
1453
+ 'TH-12' => 'Nonthaburi (&#3609;&#3609;&#3607;&#3610;&#3640;&#3619;&#3637;)',
1454
+ 'TH-13' => 'Pathum Thani (&#3611;&#3607;&#3640;&#3617;&#3608;&#3634;&#3609;&#3637;)',
1455
+ 'TH-94' => 'Pattani (&#3611;&#3633;&#3605;&#3605;&#3634;&#3609;&#3637;)',
1456
+ 'TH-82' => 'Phang Nga (&#3614;&#3633;&#3591;&#3591;&#3634;)',
1457
+ 'TH-93' => 'Phatthalung (&#3614;&#3633;&#3607;&#3621;&#3640;&#3591;)',
1458
+ 'TH-56' => 'Phayao (&#3614;&#3632;&#3648;&#3618;&#3634;)',
1459
+ 'TH-67' => 'Phetchabun (&#3648;&#3614;&#3594;&#3619;&#3610;&#3641;&#3619;&#3603;&#3660;)',
1460
+ 'TH-76' => 'Phetchaburi (&#3648;&#3614;&#3594;&#3619;&#3610;&#3640;&#3619;&#3637;)',
1461
+ 'TH-66' => 'Phichit (&#3614;&#3636;&#3592;&#3636;&#3605;&#3619;)',
1462
+ 'TH-65' => 'Phitsanulok (&#3614;&#3636;&#3625;&#3603;&#3640;&#3650;&#3621;&#3585;)',
1463
+ 'TH-54' => 'Phrae (&#3649;&#3614;&#3619;&#3656;)',
1464
+ 'TH-83' => 'Phuket (&#3616;&#3641;&#3648;&#3585;&#3655;&#3605;)',
1465
+ 'TH-25' => 'Prachin Buri (&#3611;&#3619;&#3634;&#3592;&#3637;&#3609;&#3610;&#3640;&#3619;&#3637;)',
1466
+ 'TH-77' => 'Prachuap Khiri Khan (&#3611;&#3619;&#3632;&#3592;&#3623;&#3610;&#3588;&#3637;&#3619;&#3637;&#3586;&#3633;&#3609;&#3608;&#3660;)',
1467
+ 'TH-85' => 'Ranong (&#3619;&#3632;&#3609;&#3629;&#3591;)',
1468
+ 'TH-70' => 'Ratchaburi (&#3619;&#3634;&#3594;&#3610;&#3640;&#3619;&#3637;)',
1469
+ 'TH-21' => 'Rayong (&#3619;&#3632;&#3618;&#3629;&#3591;)',
1470
+ 'TH-45' => 'Roi Et (&#3619;&#3657;&#3629;&#3618;&#3648;&#3629;&#3655;&#3604;)',
1471
+ 'TH-27' => 'Sa Kaeo (&#3626;&#3619;&#3632;&#3649;&#3585;&#3657;&#3623;)',
1472
+ 'TH-47' => 'Sakon Nakhon (&#3626;&#3585;&#3621;&#3609;&#3588;&#3619;)',
1473
+ 'TH-11' => 'Samut Prakan (&#3626;&#3617;&#3640;&#3607;&#3619;&#3611;&#3619;&#3634;&#3585;&#3634;&#3619;)',
1474
+ 'TH-74' => 'Samut Sakhon (&#3626;&#3617;&#3640;&#3607;&#3619;&#3626;&#3634;&#3588;&#3619;)',
1475
+ 'TH-75' => 'Samut Songkhram (&#3626;&#3617;&#3640;&#3607;&#3619;&#3626;&#3591;&#3588;&#3619;&#3634;&#3617;)',
1476
+ 'TH-19' => 'Saraburi (&#3626;&#3619;&#3632;&#3610;&#3640;&#3619;&#3637;)',
1477
+ 'TH-91' => 'Satun (&#3626;&#3605;&#3641;&#3621;)',
1478
+ 'TH-17' => 'Sing Buri (&#3626;&#3636;&#3591;&#3627;&#3660;&#3610;&#3640;&#3619;&#3637;)',
1479
+ 'TH-33' => 'Sisaket (&#3624;&#3619;&#3637;&#3626;&#3632;&#3648;&#3585;&#3625;)',
1480
+ 'TH-90' => 'Songkhla (&#3626;&#3591;&#3586;&#3621;&#3634;)',
1481
+ 'TH-64' => 'Sukhothai (&#3626;&#3640;&#3650;&#3586;&#3607;&#3633;&#3618;)',
1482
+ 'TH-72' => 'Suphan Buri (&#3626;&#3640;&#3614;&#3619;&#3619;&#3603;&#3610;&#3640;&#3619;&#3637;)',
1483
+ 'TH-84' => 'Surat Thani (&#3626;&#3640;&#3619;&#3634;&#3625;&#3598;&#3619;&#3660;&#3608;&#3634;&#3609;&#3637;)',
1484
+ 'TH-32' => 'Surin (&#3626;&#3640;&#3619;&#3636;&#3609;&#3607;&#3619;&#3660;)',
1485
+ 'TH-63' => 'Tak (&#3605;&#3634;&#3585;)',
1486
+ 'TH-92' => 'Trang (&#3605;&#3619;&#3633;&#3591;)',
1487
+ 'TH-23' => 'Trat (&#3605;&#3619;&#3634;&#3604;)',
1488
+ 'TH-34' => 'Ubon Ratchathani (&#3629;&#3640;&#3610;&#3621;&#3619;&#3634;&#3594;&#3608;&#3634;&#3609;&#3637;)',
1489
+ 'TH-41' => 'Udon Thani (&#3629;&#3640;&#3604;&#3619;&#3608;&#3634;&#3609;&#3637;)',
1490
+ 'TH-61' => 'Uthai Thani (&#3629;&#3640;&#3607;&#3633;&#3618;&#3608;&#3634;&#3609;&#3637;)',
1491
+ 'TH-53' => 'Uttaradit (&#3629;&#3640;&#3605;&#3619;&#3604;&#3636;&#3605;&#3606;&#3660;)',
1492
+ 'TH-95' => 'Yala (&#3618;&#3632;&#3621;&#3634;)',
1493
+ 'TH-35' => 'Yasothon (&#3618;&#3650;&#3626;&#3608;&#3619;)',
1494
+ ];
1495
+
1496
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_thailand_states', $states );
1497
+ }
1498
+
1499
+ /**
1500
+ * Get Spain States
1501
+ *
1502
+ * @since 5.2.0
1503
+ *
1504
+ * @return array $states A list of states
1505
+ */
1506
+ public function get_spain_list() {
1507
+ $states = [
1508
+ '' => '',
1509
+ 'C' => esc_html__( 'A Coru&ntilde;a', 'event-tickets' ),
1510
+ 'VI' => esc_html__( 'Álava', 'event-tickets' ),
1511
+ 'AB' => esc_html__( 'Albacete', 'event-tickets' ),
1512
+ 'A' => esc_html__( 'Alicante', 'event-tickets' ),
1513
+ 'AL' => esc_html__( 'Almer&iacute;a', 'event-tickets' ),
1514
+ 'O' => esc_html__( 'Asturias', 'event-tickets' ),
1515
+ 'AV' => esc_html__( '&Aacute;vila', 'event-tickets' ),
1516
+ 'BA' => esc_html__( 'Badajoz', 'event-tickets' ),
1517
+ 'PM' => esc_html__( 'Baleares', 'event-tickets' ),
1518
+ 'B' => esc_html__( 'Barcelona', 'event-tickets' ),
1519
+ 'BU' => esc_html__( 'Burgos', 'event-tickets' ),
1520
+ 'CC' => esc_html__( 'C&aacute;ceres', 'event-tickets' ),
1521
+ 'CA' => esc_html__( 'C&aacute;diz', 'event-tickets' ),
1522
+ 'S' => esc_html__( 'Cantabria', 'event-tickets' ),
1523
+ 'CS' => esc_html__( 'Castell&oacute;n', 'event-tickets' ),
1524
+ 'CE' => esc_html__( 'Ceuta', 'event-tickets' ),
1525
+ 'CR' => esc_html__( 'Ciudad Real', 'event-tickets' ),
1526
+ 'CO' => esc_html__( 'C&oacute;rdoba', 'event-tickets' ),
1527
+ 'CU' => esc_html__( 'Cuenca', 'event-tickets' ),
1528
+ 'GI' => esc_html__( 'Girona', 'event-tickets' ),
1529
+ 'GR' => esc_html__( 'Granada', 'event-tickets' ),
1530
+ 'GU' => esc_html__( 'Guadalajara', 'event-tickets' ),
1531
+ 'SS' => esc_html__( 'Gipuzkoa', 'event-tickets' ),
1532
+ 'H' => esc_html__( 'Huelva', 'event-tickets' ),
1533
+ 'HU' => esc_html__( 'Huesca', 'event-tickets' ),
1534
+ 'J' => esc_html__( 'Ja&eacute;n', 'event-tickets' ),
1535
+ 'LO' => esc_html__( 'La Rioja', 'event-tickets' ),
1536
+ 'GC' => esc_html__( 'Las Palmas', 'event-tickets' ),
1537
+ 'LE' => esc_html__( 'Le&oacute;n', 'event-tickets' ),
1538
+ 'L' => esc_html__( 'Lleida', 'event-tickets' ),
1539
+ 'LU' => esc_html__( 'Lugo', 'event-tickets' ),
1540
+ 'M' => esc_html__( 'Madrid', 'event-tickets' ),
1541
+ 'MA' => esc_html__( 'M&aacute;laga', 'event-tickets' ),
1542
+ 'ML' => esc_html__( 'Melilla', 'event-tickets' ),
1543
+ 'MU' => esc_html__( 'Murcia', 'event-tickets' ),
1544
+ 'NA' => esc_html__( 'Navarra', 'event-tickets' ),
1545
+ 'OR' => esc_html__( 'Ourense', 'event-tickets' ),
1546
+ 'P' => esc_html__( 'Palencia', 'event-tickets' ),
1547
+ 'PO' => esc_html__( 'Pontevedra', 'event-tickets' ),
1548
+ 'SA' => esc_html__( 'Salamanca', 'event-tickets' ),
1549
+ 'TF' => esc_html__( 'Santa Cruz de Tenerife', 'event-tickets' ),
1550
+ 'SG' => esc_html__( 'Segovia', 'event-tickets' ),
1551
+ 'SE' => esc_html__( 'Sevilla', 'event-tickets' ),
1552
+ 'SO' => esc_html__( 'Soria', 'event-tickets' ),
1553
+ 'T' => esc_html__( 'Tarragona', 'event-tickets' ),
1554
+ 'TE' => esc_html__( 'Teruel', 'event-tickets' ),
1555
+ 'TO' => esc_html__( 'Toledo', 'event-tickets' ),
1556
+ 'V' => esc_html__( 'Valencia', 'event-tickets' ),
1557
+ 'VA' => esc_html__( 'Valladolid', 'event-tickets' ),
1558
+ 'BI' => esc_html__( 'Bizkaia', 'event-tickets' ),
1559
+ 'ZA' => esc_html__( 'Zamora', 'event-tickets' ),
1560
+ 'Z' => esc_html__( 'Zaragoza', 'event-tickets' ),
1561
+ ];
1562
+
1563
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_states_spain_states', $states );
1564
+ }
1565
+
1566
+
1567
+ /**
1568
+ * Get the label that need to show as an placeholder.
1569
+ *
1570
+ * @since 5.2.0
1571
+ *
1572
+ * @return array $country_states_label
1573
+ */
1574
+ public function get_states_label() {
1575
+ $country_states_label = [];
1576
+ $default_label = __( 'State', 'event-tickets' );
1577
+ $locale = tribe( \TEC\Tickets\Commerce\Gateways\PayPal\Location\Country::class )->get_list_locale();
1578
+ foreach ( $locale as $key => $value ) {
1579
+ $label = $default_label;
1580
+ if ( ! empty( $value['state'] ) && ! empty( $value['state']['label'] ) ) {
1581
+ $label = $value['state']['label'];
1582
+ }
1583
+ $country_states_label[ $key ] = $label;
1584
+ }
1585
+
1586
+ /**
1587
+ * Filter can be used to add or remove the Country that does not have states init.
1588
+ *
1589
+ * @since 5.2.0
1590
+ *
1591
+ * @param array $country Contain key as there country code & value as there country name.
1592
+ */
1593
+ return (array) apply_filters( 'tec_tickets_commerce_gateway_paypal_states_get_states_label', $country_states_label );
1594
+ }
1595
+
1596
+ /**
1597
+ * Get Site Base State
1598
+ *
1599
+ * @since 5.2.0
1600
+ *
1601
+ * @return string $state The site's base state name
1602
+ */
1603
+ public function get_state() {
1604
+ $state = tribe_get_option( 'tec-tickets-commerce-gateway-paypal-merchant-state' );
1605
+
1606
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_state', $state );
1607
+ }
1608
+
1609
+ /**
1610
+ * Get Site States
1611
+ *
1612
+ * @since 5.2.0
1613
+ *
1614
+ * @param null $country
1615
+ *
1616
+ * @return mixed A list of states for the site's base country.
1617
+ */
1618
+ public function get_states_for( $country = null ) {
1619
+ // If Country have no states return empty array.
1620
+ $states = [];
1621
+
1622
+ // Check if Country Code is empty or not.
1623
+ if ( empty( $country ) ) {
1624
+ // Get default country code that is being set by the admin.
1625
+ $country = tribe( \TEC\Tickets\Commerce\Gateways\PayPal\Location\Country::class )->get_setting();
1626
+ }
1627
+
1628
+ // Get all the list of the states in array key format where key is the country code and value is the states that it contain.
1629
+ $states_list = $this->get_list();
1630
+
1631
+ // Check if $country code exists in the array key.
1632
+ if ( array_key_exists( $country, $states_list ) ) {
1633
+ $states = $states_list[ $country ];
1634
+ }
1635
+
1636
+ /**
1637
+ * Filter the query in case tables are non-standard.
1638
+ *
1639
+ * @since 5.2.0
1640
+ *
1641
+ * @param string $query Database count query
1642
+ */
1643
+ return (array) apply_filters( 'tec_tickets_commerce_gateway_paypal_states_for_country', $states );
1644
+ }
1645
+
1646
+ /**
1647
+ * Get States List.
1648
+ *
1649
+ * @since 5.2.0
1650
+ *
1651
+ * @return array $states A list of the available states as in array key format.
1652
+ */
1653
+ public function get_list() {
1654
+ $states = [
1655
+ 'US' => $this->get_us_list(),
1656
+ 'CA' => $this->get_provinces_list(),
1657
+ 'AU' => $this->get_australian_list(),
1658
+ 'BR' => $this->get_brazil_list(),
1659
+ 'CN' => $this->get_chinese_list(),
1660
+ 'HK' => $this->get_hong_kong_list(),
1661
+ 'HU' => $this->get_hungary_list(),
1662
+ 'ID' => $this->get_indonesian_list(),
1663
+ 'IN' => $this->get_indian_list(),
1664
+ 'MY' => $this->get_malaysian_list(),
1665
+ 'NZ' => $this->get_new_zealand_list(),
1666
+ 'TH' => $this->get_thailand_list(),
1667
+ 'ZA' => $this->get_south_african_list(),
1668
+ 'ES' => $this->get_spain_list(),
1669
+ 'TR' => $this->get_turkey_list(),
1670
+ 'RO' => $this->get_romania_list(),
1671
+ 'PK' => $this->get_pakistan_list(),
1672
+ 'PH' => $this->get_philippines_list(),
1673
+ 'PE' => $this->get_peru_list(),
1674
+ 'NP' => $this->get_nepal_list(),
1675
+ 'NG' => $this->get_nigerian_list(),
1676
+ 'MX' => $this->get_mexico_list(),
1677
+ 'JP' => $this->get_japan_list(),
1678
+ 'IT' => $this->get_italy_list(),
1679
+ 'IR' => $this->get_iran_list(),
1680
+ 'IE' => $this->get_ireland_list(),
1681
+ 'GR' => $this->get_greek_list(),
1682
+ 'BO' => $this->get_bolivian_list(),
1683
+ 'BG' => $this->get_bulgarian_list(),
1684
+ 'BD' => $this->get_bangladeshi_list(),
1685
+ 'AR' => $this->get_argentina_list(),
1686
+ ];
1687
+
1688
+ /**
1689
+ * Filter can be used to add or remove the States from the Country.
1690
+ *
1691
+ * Filters can be use to add states inside the country all the states will be in array format ans the array key will be country code.
1692
+ *
1693
+ * @since 5.2.0
1694
+ *
1695
+ * @param array $states Contain the list of states in array key format where key of the array is there respected country code.
1696
+ */
1697
+ return (array) apply_filters( 'tec_tickets_commerce_gateway_paypal_list', $states );
1698
+ }
1699
+ }
src/Tickets/Commerce/Gateways/PayPal/Merchant.php CHANGED
@@ -30,7 +30,9 @@ class Merchant {
30
  'client_id',
31
  'client_secret',
32
  'account_is_ready',
 
33
  'supports_custom_payments',
 
34
  'account_country',
35
  'access_token',
36
  ];
@@ -126,7 +128,17 @@ class Merchant {
126
  protected $account_is_ready = false;
127
 
128
  /**
129
- * Whether or not the account can make custom payments (i.e Advanced Fields & PPCP)
 
 
 
 
 
 
 
 
 
 
130
  *
131
  * @since 5.1.9
132
  *
@@ -134,6 +146,15 @@ class Merchant {
134
  */
135
  protected $supports_custom_payments = false;
136
 
 
 
 
 
 
 
 
 
 
137
  /**
138
  * PayPal account account country.
139
  *
@@ -304,6 +325,29 @@ class Merchant {
304
  $this->set_value( 'account_is_ready', $value, $needs_save );
305
  }
306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  /**
308
  * Gets the value stored for if this account supports custom payments.
309
  *
@@ -312,7 +356,7 @@ class Merchant {
312
  * @return bool
313
  */
314
  public function get_supports_custom_payments() {
315
- return $this->supports_custom_payments;
316
  }
317
 
318
  /**
@@ -327,6 +371,29 @@ class Merchant {
327
  $this->set_value( 'supports_custom_payments', $value, $needs_save );
328
  }
329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  /**
331
  * Gets the value stored for the Country Code.
332
  *
@@ -440,7 +507,7 @@ class Merchant {
440
  * @since 5.1.9
441
  */
442
  public function init() {
443
- $this->set_mode( tribe_tickets_commerce_is_test_mode() ? 'sandbox' : 'live' );
444
  $this->from_array( $this->get_details_data(), false );
445
  }
446
 
@@ -459,7 +526,9 @@ class Merchant {
459
  'client_id' => $this->get_client_id(),
460
  'client_secret' => $this->get_client_secret(),
461
  'account_is_ready' => $this->get_account_is_ready(),
 
462
  'supports_custom_payments' => $this->get_supports_custom_payments(),
 
463
  'account_country' => $this->get_account_country(),
464
  'access_token' => $this->get_access_token(),
465
  ];
@@ -531,6 +600,12 @@ class Merchant {
531
  if ( array_key_exists( 'account_is_ready', $data ) ) {
532
  $this->set_account_is_ready( $data['account_is_ready'], $needs_save );
533
  }
 
 
 
 
 
 
534
  if ( array_key_exists( 'supports_custom_payments', $data ) ) {
535
  $this->set_supports_custom_payments( $data['supports_custom_payments'], $needs_save );
536
  }
@@ -797,6 +872,37 @@ class Merchant {
797
  return in_array( false, $statuses, true );
798
  }
799
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
800
  /**
801
  * Determines if the Merchant is active.
802
  *
@@ -811,17 +917,36 @@ class Merchant {
811
  return false;
812
  }
813
 
 
 
 
 
814
  if ( ! $recheck && true === $this->get_account_is_ready() ) {
815
  return true;
816
  }
817
 
818
- $seller_status = tribe( WhoDat::class )->get_seller_status( $saved_merchant_id );
819
-
820
- $payments_receivable = Arr::get( $seller_status, 'payments_receivable' );
821
- $paypal_product_name = Arr::get( $seller_status, [ 'products', 0, 'name' ] );
822
- $paypal_product_status = Arr::get( $seller_status, [ 'products', 0, 'status' ] );
823
-
824
- $is_active = ( true === $payments_receivable && 'EXPRESS_CHECKOUT' === $paypal_product_name && 'ACTIVE' === $paypal_product_status );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
825
 
826
  if ( $is_active ) {
827
  $this->set_account_is_ready( true );
@@ -830,4 +955,24 @@ class Merchant {
830
 
831
  return $is_active;
832
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
833
  }
30
  'client_id',
31
  'client_secret',
32
  'account_is_ready',
33
+ 'account_is_connected',
34
  'supports_custom_payments',
35
+ 'active_custom_payments',
36
  'account_country',
37
  'access_token',
38
  ];
128
  protected $account_is_ready = false;
129
 
130
  /**
131
+ * Whether or not an account is connected.
132
+ *
133
+ * @since 5.2.0
134
+ *
135
+ * @var bool
136
+ */
137
+ protected $account_is_connected = false;
138
+
139
+ /**
140
+ * Whether or not the account is setup make custom payments (i.e Advanced Fields & PPCP), doesn't necessarily mean
141
+ * that the account can accept payments yet.
142
  *
143
  * @since 5.1.9
144
  *
146
  */
147
  protected $supports_custom_payments = false;
148
 
149
+ /**
150
+ * Whether or not the account is ready to take custom payments (i.e Advanced Fields & PPCP).
151
+ *
152
+ * @since 5.2.0
153
+ *
154
+ * @var bool
155
+ */
156
+ protected $active_custom_payments = false;
157
+
158
  /**
159
  * PayPal account account country.
160
  *
325
  $this->set_value( 'account_is_ready', $value, $needs_save );
326
  }
327
 
328
+ /**
329
+ * Gets the value stored for if the account is ready for usage.
330
+ *
331
+ * @since 5.2.0
332
+ *
333
+ * @return string
334
+ */
335
+ public function get_account_is_connected() {
336
+ return $this->account_is_connected;
337
+ }
338
+
339
+ /**
340
+ * Sets the value for if this account is connected for usage locally, in this instance of the Merchant.
341
+ *
342
+ * @since 5.2.0
343
+ *
344
+ * @param mixed $value Value used for the Account is Connect.
345
+ * @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
346
+ */
347
+ public function set_account_is_connected( $value, $needs_save = true ) {
348
+ $this->set_value( 'account_is_connected', $value, $needs_save );
349
+ }
350
+
351
  /**
352
  * Gets the value stored for if this account supports custom payments.
353
  *
356
  * @return bool
357
  */
358
  public function get_supports_custom_payments() {
359
+ return tribe_is_truthy( $this->supports_custom_payments );
360
  }
361
 
362
  /**
371
  $this->set_value( 'supports_custom_payments', $value, $needs_save );
372
  }
373
 
374
+ /**
375
+ * Gets the value stored for if this account supports custom payments.
376
+ *
377
+ * @since 5.2.0
378
+ *
379
+ * @return bool
380
+ */
381
+ public function get_active_custom_payments() {
382
+ return tribe_is_truthy( $this->active_custom_payments );
383
+ }
384
+
385
+ /**
386
+ * Sets the value determining if this supports custom payments locally, in this instance of the Merchant.
387
+ *
388
+ * @since 5.2.0
389
+ *
390
+ * @param mixed $value Value used for the Support for Custom Payments.
391
+ * @param boolean $needs_save Determines if the proprieties saved need to save to the DB.
392
+ */
393
+ public function set_active_custom_payments( $value, $needs_save = true ) {
394
+ $this->set_value( 'active_custom_payments', $value, $needs_save );
395
+ }
396
+
397
  /**
398
  * Gets the value stored for the Country Code.
399
  *
507
  * @since 5.1.9
508
  */
509
  public function init() {
510
+ $this->set_mode( tec_tickets_commerce_is_sandbox_mode() ? 'sandbox' : 'live' );
511
  $this->from_array( $this->get_details_data(), false );
512
  }
513
 
526
  'client_id' => $this->get_client_id(),
527
  'client_secret' => $this->get_client_secret(),
528
  'account_is_ready' => $this->get_account_is_ready(),
529
+ 'account_is_connected' => $this->get_account_is_connected(),
530
  'supports_custom_payments' => $this->get_supports_custom_payments(),
531
+ 'active_custom_payments' => $this->get_active_custom_payments(),
532
  'account_country' => $this->get_account_country(),
533
  'access_token' => $this->get_access_token(),
534
  ];
600
  if ( array_key_exists( 'account_is_ready', $data ) ) {
601
  $this->set_account_is_ready( $data['account_is_ready'], $needs_save );
602
  }
603
+ if ( array_key_exists( 'account_is_connected', $data ) ) {
604
+ $this->set_account_is_connected( $data['account_is_connected'], $needs_save );
605
+ }
606
+ if ( array_key_exists( 'active_custom_payments', $data ) ) {
607
+ $this->set_active_custom_payments( $data['active_custom_payments'], $needs_save );
608
+ }
609
  if ( array_key_exists( 'supports_custom_payments', $data ) ) {
610
  $this->set_supports_custom_payments( $data['supports_custom_payments'], $needs_save );
611
  }
872
  return in_array( false, $statuses, true );
873
  }
874
 
875
+ /**
876
+ * Determines if the Merchant is connected.
877
+ *
878
+ * @since 5.2.0
879
+ *
880
+ * @return bool
881
+ */
882
+ public function is_connected( $recheck = false ) {
883
+ $saved_merchant_id = $this->get_merchant_id_in_paypal();
884
+
885
+ if ( ! $saved_merchant_id ) {
886
+ return false;
887
+ }
888
+
889
+ if ( ! $recheck && true === $this->get_account_is_connected() ) {
890
+ return true;
891
+ }
892
+
893
+ $seller_status = tribe( WhoDat::class )->get_seller_status( $saved_merchant_id );
894
+ $product_names = wp_list_pluck( Arr::get( $seller_status, [ 'products' ] ), 'name' );
895
+
896
+ $is_connected = count( array_intersect( $product_names, [ 'EXPRESS_CHECKOUT', 'PPCP_CUSTOM', 'PPCP_STANDARD' ] ) ) >= 1;
897
+
898
+ if ( $is_connected ) {
899
+ $this->set_account_is_connected( true );
900
+ $this->save();
901
+ }
902
+
903
+ return $is_connected;
904
+ }
905
+
906
  /**
907
  * Determines if the Merchant is active.
908
  *
917
  return false;
918
  }
919
 
920
+ if ( ! $this->is_connected( $recheck ) ) {
921
+ return false;
922
+ }
923
+
924
  if ( ! $recheck && true === $this->get_account_is_ready() ) {
925
  return true;
926
  }
927
 
928
+ $seller_status = tribe( WhoDat::class )->get_seller_status( $saved_merchant_id );
929
+ $payments_receivable = tribe_is_truthy( Arr::get( $seller_status, 'payments_receivable' ) );
930
+ $primary_email_confirmed = tribe_is_truthy( Arr::get( $seller_status, 'primary_email_confirmed' ) );
931
+
932
+ $is_active = ( $payments_receivable && $primary_email_confirmed );
933
+
934
+ if ( $is_active && $this->get_supports_custom_payments() ) {
935
+ // Grab the PPCP_CUSTOM product from the status data
936
+ $custom_product = current(
937
+ array_filter(
938
+ $seller_status['products'],
939
+ static function ( $product ) {
940
+ return 'PPCP_CUSTOM' === $product['name'];
941
+ }
942
+ )
943
+ );
944
+ $active_custom_payments = 'SUBSCRIBED' === Arr::get( $custom_product, 'vetting_status' );
945
+
946
+ // For custom payments we save here.
947
+ $this->set_active_custom_payments( $active_custom_payments );
948
+ $this->save();
949
+ }
950
 
951
  if ( $is_active ) {
952
  $this->set_account_is_ready( true );
955
 
956
  return $is_active;
957
  }
958
+
959
+ /**
960
+ * Fetches the locale for the website, but pass it on a filter to allow changing of the locale here.
961
+ *
962
+ * @since 5.2.0
963
+ *
964
+ * @return string
965
+ */
966
+ public function get_locale() {
967
+ $locale = get_locale();
968
+
969
+ /**
970
+ * Allows filtering of the locale for the Merchant.
971
+ *
972
+ * @since 5.2.0
973
+ *
974
+ * @param string $locale
975
+ */
976
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_merchant_locale', $locale );
977
+ }
978
  }
src/Tickets/Commerce/Gateways/PayPal/On_Boarding_Redirect_Handler.php DELETED
@@ -1,241 +0,0 @@
1
- <?php
2
-
3
- namespace TEC\Tickets\Commerce\Gateways\PayPal;
4
-
5
- use Exception;
6
- use TEC\Tickets\Commerce\Gateways\PayPal\Repositories\Webhooks;
7
- use Tribe__Settings;
8
-
9
- /**
10
- * Class On_Boarding_Redirect_Handler
11
- *
12
- * @todo This whole file will stop exsiting once we deprecate all Give's code usage.
13
- *
14
- * @since 5.1.6
15
- * @package TEC\Tickets\Commerce\Gateways\PayPal
16
- *
17
- */
18
- class On_Boarding_Redirect_Handler {
19
- /**
20
- * Return on boarding trouble notice.
21
- *
22
- * @TODO this method needs to be completely refactored into an admin page action.
23
- *
24
- * @since 5.1.6
25
- */
26
- public function on_boarding_trouble_notice() {
27
-
28
- $action_list = sprintf(
29
- '<ol><li>%1$s</li><li>%2$s</li><li>%3$s %4$s</li></ol>',
30
- esc_html__( 'Make sure to complete the entire PayPal process. Do not close the window you have finished the process.', 'event-tickets' ),
31
- esc_html__( 'The last screen of the PayPal connect process includes a button to be sent back to your site. It is important you click this and do not close the window yourself.', 'event-tickets' ),
32
- esc_html__( 'If you’re still having problems connecting:', 'event-tickets' ),
33
- $this->settings->get_guidance_html()
34
- );
35
-
36
- $standard_error = sprintf(
37
- '<div id="give-paypal-onboarding-trouble-notice" class="tribe-common-a11y-hidden"><p class="error-message">%1$s</p><p>%2$s</p></div>',
38
- esc_html__( 'Having trouble connecting to PayPal?', 'event-tickets' ),
39
- $action_list
40
- );
41
-
42
- wp_send_json_success( $standard_error );
43
- }
44
-
45
- /**
46
- * Sets up the webhook for the connected account
47
- *
48
- * @since 5.1.6
49
- */
50
- private function set_up_webhook() {
51
- if ( ! is_ssl() ) {
52
- return;
53
- }
54
-
55
- try {
56
- $webhook_config = $this->webhooks_repository->create_webhook( $this->merchant->get_access_token() );
57
-
58
- $this->webhooks_repository->save_webhook_config( $webhook_config );
59
- } catch ( Exception $ex ) {
60
- tribe( 'logger' )->log_error( $ex->getMessage(), 'tickets-commerce-gateway-paypal' );
61
-
62
- $errors = [];
63
-
64
- $errors[] = esc_html__( 'There was a problem with creating webhook on PayPal. A gateway error log also added to get details information about PayPal response.', 'event-tickets' );
65
-
66
- // Log error messages.
67
- array_map( static function ( $error_message ) {
68
- $error_message = is_array( $error_message ) ? $error_message['message'] . ' ' . $error_message['value'] : $error_message;
69
- tribe( 'logger' )->log_error( $error_message, 'tickets-commerce-gateway-paypal' );
70
- }, $errors );
71
-
72
- $this->merchant->save_account_errors( $errors );
73
- $this->redirect_when_on_boarding_fail();
74
- }
75
- }
76
-
77
- /**
78
- * Validate rest api credential.
79
- *
80
- * @since 5.1.6
81
- *
82
- * @param array $array
83
- *
84
- */
85
- private function did_we_get_valid_seller_rest_api_credentials( $array ) {
86
- $required = [ 'client_id', 'client_secret' ];
87
- $array = array_filter( $array ); // Remove empty values.
88
-
89
- $errors = [];
90
-
91
- if ( array_diff( $required, array_keys( $array ) ) ) {
92
- $errors[] = [
93
- 'type' => 'json',
94
- 'message' => esc_html__( 'PayPal client access token API request response is:', 'event-tickets' ),
95
- 'value' => wp_json_encode( $this->settings->get_access_token() ),
96
- ];
97
-
98
- $errors[] = [
99
- 'type' => 'json',
100
- 'message' => esc_html__( 'PayPal client rest API credentials API request response is:', 'event-tickets' ),
101
- 'value' => wp_json_encode( $array ),
102
- ];
103
-
104
- $errors[] = esc_html__( 'There was a problem with PayPal client rest API request and we could not find valid client id and secret.', 'event-tickets' );
105
-
106
- // Log error messages.
107
- array_map( static function ( $error_message ) {
108
- $error_message = is_array( $error_message ) ? $error_message['message'] . ' ' . $error_message['value'] : $error_message;
109
- tribe( 'logger' )->log_error( $error_message, 'tickets-commerce-gateway-paypal' );
110
- }, $errors );
111
-
112
- $this->merchant->save_account_errors( $errors );
113
- //$this->redirect_when_on_boarding_fail();
114
- }
115
- }
116
-
117
- /**
118
- * Validate seller on Boarding status.
119
- *
120
- * @since 5.1.6
121
- *
122
- * @param string $merchant_id
123
- * @param string $access_token
124
- * @param bool $uses_custom_payments
125
- *
126
- * @return bool|string[]
127
- */
128
- private function is_admin_successfully_on_boarded( $merchant_id, $access_token, $uses_custom_payments ) {
129
- $on_boarded_data = (array) tribe( WhoDat::class )->get_seller_on_boarding_details_from_paypal( $merchant_id, $access_token );
130
- $on_boarded_data = array_filter( $on_boarded_data ); // Remove empty values.
131
- $error_messages[] = [
132
- 'type' => 'json',
133
- 'message' => esc_html__( 'PayPal merchant status check API request response is:', 'event-tickets' ),
134
- 'value' => wp_json_encode( $on_boarded_data ),
135
- ];
136
-
137
- if ( ! is_ssl() ) {
138
- $error_messages[] = esc_html__( 'A valid SSL certificate is required to accept payments and set up your PayPal account. Once a
139
- certificate is installed and the site is using https, please disconnect and reconnect your account.', 'event-tickets' );
140
- }
141
-
142
- if ( array_diff( [ 'payments_receivable', 'primary_email_confirmed' ], array_keys( $on_boarded_data ) ) ) {
143
- $error_messages[] = esc_html__( 'There was a problem with the status check for your account. Please try disconnecting and connecting again. If the problem persists, please contact support.', 'event-tickets' );
144
-
145
- // Log error messages.
146
- array_map( static function ( $error_message ) {
147
- $error_message = is_array( $error_message ) ? $error_message['message'] . ' ' . $error_message['value'] : $error_message;
148
- tribe( 'logger' )->log_error( $error_message, 'tickets-commerce-gateway-paypal' );
149
- }, $error_messages );
150
-
151
- // Return here since the rest of the validations will definitely fail
152
- return $error_messages;
153
- }
154
-
155
- if ( ! $on_boarded_data['payments_receivable'] ) {
156
- $error_messages[] = esc_html__( 'Set up an account to receive payment from PayPal', 'event-tickets' );
157
- }
158
-
159
- if ( ! $on_boarded_data['primary_email_confirmed'] ) {
160
- $error_messages[] = esc_html__( 'Confirm your primary email address', 'event-tickets' );
161
- }
162
-
163
- if ( ! $uses_custom_payments ) {
164
- return count( $error_messages ) > 1 ? $error_messages : true;
165
- }
166
-
167
- if ( array_diff( [ 'products', 'capabilities' ], array_keys( $on_boarded_data ) ) ) {
168
- $error_messages[] = esc_html__( 'Your account was expected to be able to accept custom payments, but is not. Please make sure your
169
- account country matches the country setting. If the problem persists, please contact PayPal.', 'event-tickets' );
170
-
171
- // Return here since the rest of the validations will definitely fail
172
- return $error_messages;
173
- }
174
-
175
- // Grab the PPCP_CUSTOM product from the status data
176
- $custom_product = current(
177
- array_filter(
178
- $on_boarded_data['products'],
179
- static function ( $product ) {
180
- return 'PPCP_CUSTOM' === $product['name'];
181
- }
182
- )
183
- );
184
-
185
- if ( empty( $custom_product ) || $custom_product['vetting_status'] !== 'SUBSCRIBED' ) {
186
- $error_messages[] = esc_html__( 'Reach out to PayPal to enable PPCP_CUSTOM for your account', 'event-tickets' );
187
- }
188
-
189
- // Loop through the capabilities and see if any are not active
190
- $invalid_capabilities = [];
191
- foreach ( $on_boarded_data['capabilities'] as $capability ) {
192
- if ( $capability['status'] !== 'ACTIVE' ) {
193
- $invalid_capabilities[] = $capability['name'];
194
- }
195
- }
196
-
197
- if ( ! empty( $invalid_capabilities ) ) {
198
- $error_messages[] = esc_html__( 'Reach out to PayPal to resolve the following capabilities:', 'event-tickets' ) . ' ' . implode( ', ', $invalid_capabilities );
199
- }
200
-
201
- // If there were errors then redirect the user with notices
202
- return count( $error_messages ) > 1 ? $error_messages : true;
203
- }
204
-
205
- /**
206
- * Displays a notice of the site is not using SSL.
207
- *
208
- * @since 5.1.6
209
- */
210
- private function register_paypal_ssl_notice() {
211
- if ( ! is_ssl() || ! empty( $this->webhooks_repository->get_webhook_config() ) ) {
212
- return;
213
- }
214
-
215
- /** @var Tribe__Settings $settings */
216
- $settings = tribe( 'settings' );
217
-
218
- // Get link to Help page.
219
- $log_url = $settings->get_url( [
220
- 'page' => 'tribe-help',
221
- ] ) . '#tribe-event-log';
222
-
223
- $log_link = sprintf(
224
- '<a href="%1$s">%2$s</a>',
225
- $log_url,
226
- esc_html__( 'logged data', 'event-tickets' )
227
- );
228
-
229
- tribe_error(
230
- 'paypal-webhook-error',
231
- sprintf(
232
- // Translators: %1$s: The logged data link.
233
- esc_html__( 'There was a problem setting up the webhooks for your PayPal account. Please try disconnecting and reconnecting your PayPal account. If the problem persists, please contact support and provide them with the latest %1$s', 'event-tickets' ),
234
- $log_link
235
- ),
236
- [
237
- 'type' => 'error',
238
- ]
239
- );
240
- }
241
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Tickets/Commerce/Gateways/PayPal/Provider.php CHANGED
@@ -21,13 +21,8 @@ class Provider extends \tad_DI52_ServiceProvider {
21
  $this->register_hooks();
22
  $this->register_assets();
23
 
24
- // @todo Is this needed?
25
- // $this->container->singleton( PaymentFormElements::class );
26
- // $this->container->singleton( PaymentProcessor::class );
27
-
28
  $this->container->singleton( Merchant::class, Merchant::class, [ 'init' ] );
29
 
30
- $this->container->singleton( On_Boarding_Redirect_Handler::class );
31
  $this->container->singleton( Refresh_Token::class );
32
  $this->container->singleton( Client::class );
33
  $this->container->singleton( Signup::class );
21
  $this->register_hooks();
22
  $this->register_assets();
23
 
 
 
 
 
24
  $this->container->singleton( Merchant::class, Merchant::class, [ 'init' ] );
25
 
 
26
  $this->container->singleton( Refresh_Token::class );
27
  $this->container->singleton( Client::class );
28
  $this->container->singleton( Signup::class );
src/Tickets/Commerce/Gateways/PayPal/REST/On_Boarding_Endpoint.php CHANGED
@@ -9,6 +9,7 @@ use TEC\Tickets\Commerce\Gateways\PayPal\Refresh_Token;
9
  use TEC\Tickets\Commerce\Gateways\PayPal\Signup;
10
  use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks;
11
  use TEC\Tickets\Commerce\Gateways\PayPal\WhoDat;
 
12
  use Tribe__Documentation__Swagger__Provider_Interface;
13
  use Tribe__Settings;
14
  use Tribe__Utils__Array as Arr;
@@ -22,7 +23,7 @@ use WP_REST_Server;
22
  /**
23
  * Class On_Boarding_Endpoint
24
  *
25
- * @since 5.1.9
26
  *
27
  * @package TEC\Tickets\Commerce\Gateways\PayPal\REST
28
  */
@@ -166,14 +167,14 @@ class On_Boarding_Endpoint implements Tribe__Documentation__Swagger__Provider_In
166
  $signup = tribe( Signup::class );
167
  $existing_hash = $signup->get_transient_hash();
168
  $request_hash = $request->get_param( 'hash' );
169
- $return_url = Tribe__Settings::instance()->get_url( [ 'tab' => 'payments', ] );
170
 
171
  if ( $request_hash !== $existing_hash ) {
172
  $this->redirect_with( 'invalid-paypal-signup-hash', $return_url );
173
  }
174
 
175
- $seller_data = tribe( WhoDat::class )->get_seller_referral_data( $signup->get_referral_data_link() );
176
- $has_custom_payments = in_array( 'PPCP', Arr::get( $seller_data, [ 'referral_data', 'products' ], [] ), true );
177
 
178
  $merchant_id = $request->get_param( 'merchantId' );
179
  $merchant_id_in_paypal = $request->get_param( 'merchantIdInPayPal' );
@@ -194,7 +195,7 @@ class On_Boarding_Endpoint implements Tribe__Documentation__Swagger__Provider_In
194
  $merchant->set_merchant_id_in_paypal( $merchant_id_in_paypal );
195
 
196
  $access_token = $merchant->get_access_token();
197
- $credentials = tribe( WhoDat::class )->get_seller_credentials( $access_token );
198
 
199
  if ( ! isset( $credentials['client_id'], $credentials['client_secret'] ) ) {
200
  // Save what we have before moving forward.
@@ -205,8 +206,12 @@ class On_Boarding_Endpoint implements Tribe__Documentation__Swagger__Provider_In
205
 
206
  $merchant->set_client_id( $credentials['client_id'] );
207
  $merchant->set_client_secret( $credentials['client_secret'] );
208
- $merchant->set_account_is_ready( true );
209
- $merchant->set_supports_custom_payments( $has_custom_payments );
 
 
 
 
210
  $merchant->save();
211
 
212
  $client = tribe( Client::class );
@@ -222,6 +227,10 @@ class On_Boarding_Endpoint implements Tribe__Documentation__Swagger__Provider_In
222
  // Configures the Webhooks when setting up the new merchant.
223
  tribe( Webhooks::class )->create_or_update_existing();
224
 
 
 
 
 
225
  /**
226
  * @todo Need to figure out where this gets saved in the merchant API.
227
  */
@@ -229,6 +238,8 @@ class On_Boarding_Endpoint implements Tribe__Documentation__Swagger__Provider_In
229
  update_option( 'tickets_commerce_consent_status', $consent_status );
230
  update_option( 'tickets_commerce_account_status', $account_status );
231
 
 
 
232
  $this->redirect_with( 'paypal-signup-complete', $return_url );
233
  }
234
 
9
  use TEC\Tickets\Commerce\Gateways\PayPal\Signup;
10
  use TEC\Tickets\Commerce\Gateways\PayPal\Webhooks;
11
  use TEC\Tickets\Commerce\Gateways\PayPal\WhoDat;
12
+ use TEC\Tickets\Commerce\Notice_Handler;
13
  use Tribe__Documentation__Swagger__Provider_Interface;
14
  use Tribe__Settings;
15
  use Tribe__Utils__Array as Arr;
23
  /**
24
  * Class On_Boarding_Endpoint
25
  *
26
+ * @since 5.1.9
27
  *
28
  * @package TEC\Tickets\Commerce\Gateways\PayPal\REST
29
  */
167
  $signup = tribe( Signup::class );
168
  $existing_hash = $signup->get_transient_hash();
169
  $request_hash = $request->get_param( 'hash' );
170
+ $return_url = Tribe__Settings::instance()->get_url( [ 'tab' => 'payments' ] );
171
 
172
  if ( $request_hash !== $existing_hash ) {
173
  $this->redirect_with( 'invalid-paypal-signup-hash', $return_url );
174
  }
175
 
176
+ $seller_data = tribe( WhoDat::class )->get_seller_referral_data( $signup->get_referral_data_link() );
177
+ $supports_custom_payments = in_array( 'PPCP', Arr::get( $seller_data, [ 'referral_data', 'products' ], [] ), true );
178
 
179
  $merchant_id = $request->get_param( 'merchantId' );
180
  $merchant_id_in_paypal = $request->get_param( 'merchantIdInPayPal' );
195
  $merchant->set_merchant_id_in_paypal( $merchant_id_in_paypal );
196
 
197
  $access_token = $merchant->get_access_token();
198
+ $credentials = tribe( WhoDat::class )->get_seller_credentials( $access_token );
199
 
200
  if ( ! isset( $credentials['client_id'], $credentials['client_secret'] ) ) {
201
  // Save what we have before moving forward.
206
 
207
  $merchant->set_client_id( $credentials['client_id'] );
208
  $merchant->set_client_secret( $credentials['client_secret'] );
209
+
210
+ $merchant->set_supports_custom_payments( $supports_custom_payments );
211
+
212
+ $merchant->set_account_is_connected( true );
213
+ $merchant->set_account_is_ready( false );
214
+
215
  $merchant->save();
216
 
217
  $client = tribe( Client::class );
227
  // Configures the Webhooks when setting up the new merchant.
228
  tribe( Webhooks::class )->create_or_update_existing();
229
 
230
+ // Force the recheck of if the merchant is active.
231
+ // This will also check if the custom payments are active.
232
+ $merchant->is_active( true );
233
+
234
  /**
235
  * @todo Need to figure out where this gets saved in the merchant API.
236
  */
238
  update_option( 'tickets_commerce_consent_status', $consent_status );
239
  update_option( 'tickets_commerce_account_status', $account_status );
240
 
241
+ tribe( Notice_Handler::class )->trigger_admin( 'tc-paypal-signup-complete' );
242
+
243
  $this->redirect_with( 'paypal-signup-complete', $return_url );
244
  }
245
 
src/Tickets/Commerce/Gateways/PayPal/REST/Order_Endpoint.php CHANGED
@@ -16,9 +16,12 @@ use TEC\Tickets\Commerce\Gateways\PayPal\Signup;
16
  use TEC\Tickets\Commerce\Gateways\PayPal\WhoDat;
17
 
18
 
 
 
19
  use TEC\Tickets\Commerce\Status\Pending;
20
  use TEC\Tickets\Commerce\Status\Completed;
21
  use TEC\Tickets\Commerce\Status\Created;
 
22
  use TEC\Tickets\Commerce\Success;
23
  use Tribe__Documentation__Swagger__Provider_Interface;
24
  use Tribe__Settings;
@@ -79,6 +82,17 @@ class Order_Endpoint implements Tribe__Documentation__Swagger__Provider_Interfac
79
  ]
80
  );
81
 
 
 
 
 
 
 
 
 
 
 
 
82
  $documentation->register_documentation_provider( $this->get_endpoint_path(), $this );
83
  }
84
 
@@ -120,21 +134,39 @@ class Order_Endpoint implements Tribe__Documentation__Swagger__Provider_Interfac
120
  'success' => false,
121
  ];
122
 
 
 
123
  $order = tribe( Order::class )->create_from_cart( tribe( Gateway::class ) );
124
 
125
  $unit = [
126
  'reference_id' => $order->ID,
127
  'value' => $order->total_value,
128
  'currency' => $order->currency,
129
- 'first_name' => $order->purchaser_first_name,
130
- 'last_name' => $order->purchaser_last_name,
131
- 'email' => $order->purchaser_email,
132
  ];
133
 
 
 
 
 
 
 
 
 
 
 
 
134
  $paypal_order = tribe( Client::class )->create_order( $unit );
135
 
136
  if ( empty( $paypal_order['id'] ) || empty( $paypal_order['create_time'] ) ) {
137
- return new WP_Error( 'tec-tc-gateway-paypal-failed-creating-order', null, $order );
 
 
 
 
 
138
  }
139
 
140
  $updated = tribe( Order::class )->modify_status( $order->ID, Pending::SLUG, [
@@ -167,29 +199,44 @@ class Order_Endpoint implements Tribe__Documentation__Swagger__Provider_Interfac
167
  'success' => false,
168
  ];
169
 
 
 
170
  $paypal_order_id = $request->get_param( 'order_id' );
171
 
172
- $order = tec_tc_orders()->by_args( [
173
  'status' => tribe( Pending::class )->get_wp_slug(),
174
  'gateway_order_id' => $paypal_order_id,
175
  ] )->first();
176
 
177
  if ( ! $order ) {
178
- return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', null, $order );
179
  }
180
 
181
  $payer_id = $request->get_param( 'payer_id' );
 
182
  $paypal_capture_response = tribe( Client::class )->capture_order( $paypal_order_id, $payer_id );
183
 
184
- if ( ! $paypal_capture_response ) {
185
- return new WP_Error( 'tec-tc-gateway-paypal-failed-capture', null, $paypal_capture_response );
 
 
 
 
 
 
 
 
 
 
 
 
186
  }
187
 
188
  $paypal_capture_status = Arr::get( $paypal_capture_response, [ 'status' ] );
189
  $status = tribe( Status::class )->convert_to_commerce_status( $paypal_capture_status );
190
 
191
  if ( ! $status ) {
192
- return new WP_Error( 'tec-tc-gateway-paypal-invalid-capture-status', null, $paypal_capture_response );
193
  }
194
 
195
  $updated = tribe( Order::class )->modify_status( $order->ID, $status->get_slug(), [
@@ -212,6 +259,64 @@ class Order_Endpoint implements Tribe__Documentation__Swagger__Provider_Interfac
212
  return new WP_REST_Response( $response );
213
  }
214
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  /**
216
  * Arguments used for the signup redirect.
217
  *
@@ -224,7 +329,7 @@ class Order_Endpoint implements Tribe__Documentation__Swagger__Provider_Interfac
224
  }
225
 
226
  /**
227
- * Arguments used for the signup redirect.
228
  *
229
  * @since 5.1.9
230
  *
@@ -245,6 +350,70 @@ class Order_Endpoint implements Tribe__Documentation__Swagger__Provider_Interfac
245
  },
246
  'sanitize_callback' => [ $this, 'sanitize_callback' ],
247
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  ];
249
  }
250
 
@@ -277,4 +446,30 @@ class Order_Endpoint implements Tribe__Documentation__Swagger__Provider_Interfac
277
  public function get_documentation() {
278
  return [];
279
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  }
16
  use TEC\Tickets\Commerce\Gateways\PayPal\WhoDat;
17
 
18
 
19
+ use TEC\Tickets\Commerce\Module;
20
+ use TEC\Tickets\Commerce\Status\Denied;
21
  use TEC\Tickets\Commerce\Status\Pending;
22
  use TEC\Tickets\Commerce\Status\Completed;
23
  use TEC\Tickets\Commerce\Status\Created;
24
+ use TEC\Tickets\Commerce\Status\Status_Handler;
25
  use TEC\Tickets\Commerce\Success;
26
  use Tribe__Documentation__Swagger__Provider_Interface;
27
  use Tribe__Settings;
82
  ]
83
  );
84
 
85
+ register_rest_route(
86
+ $namespace,
87
+ $this->get_endpoint_path() . '/(?P<order_id>[0-9a-zA-Z]+)',
88
+ [
89
+ 'methods' => WP_REST_Server::DELETABLE,
90
+ 'args' => $this->fail_order_args(),
91
+ 'callback' => [ $this, 'handle_fail_order' ],
92
+ 'permission_callback' => '__return_true',
93
+ ]
94
+ );
95
+
96
  $documentation->register_documentation_provider( $this->get_endpoint_path(), $this );
97
  }
98
 
134
  'success' => false,
135
  ];
136
 
137
+ $messages = $this->get_error_messages();
138
+
139
  $order = tribe( Order::class )->create_from_cart( tribe( Gateway::class ) );
140
 
141
  $unit = [
142
  'reference_id' => $order->ID,
143
  'value' => $order->total_value,
144
  'currency' => $order->currency,
145
+ 'first_name' => $order->purchaser['first_name'],
146
+ 'last_name' => $order->purchaser['last_name'],
147
+ 'email' => $order->purchaser['email'],
148
  ];
149
 
150
+ foreach ( $order->items as $item ) {
151
+ $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
152
+ $unit['items'][] = [
153
+ 'name' => $ticket->name,
154
+ 'unit_amount' => [ 'value' => $item['price'], 'currency_code' => $order->currency ],
155
+ 'quantity' => $item['quantity'],
156
+ 'item_total' => [ 'value' => $item['sub_total'], 'currency_code' => $order->currency ],
157
+ 'sku' => $ticket->sku,
158
+ ];
159
+ }
160
+
161
  $paypal_order = tribe( Client::class )->create_order( $unit );
162
 
163
  if ( empty( $paypal_order['id'] ) || empty( $paypal_order['create_time'] ) ) {
164
+ return new WP_Error( 'tec-tc-gateway-paypal-failed-creating-order', $messages['failed-creating-order'], $order );
165
+ }
166
+
167
+ $debug_header = tribe( Client::class )->get_debug_header();
168
+ if ( ! empty( $debug_header ) ) {
169
+ $paypal_order['debug_id'] = $debug_header;
170
  }
171
 
172
  $updated = tribe( Order::class )->modify_status( $order->ID, Pending::SLUG, [
199
  'success' => false,
200
  ];
201
 
202
+ $messages = $this->get_error_messages();
203
+
204
  $paypal_order_id = $request->get_param( 'order_id' );
205
 
206
+ $order = tec_tc_orders()->by_args( [
207
  'status' => tribe( Pending::class )->get_wp_slug(),
208
  'gateway_order_id' => $paypal_order_id,
209
  ] )->first();
210
 
211
  if ( ! $order ) {
212
+ return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', $messages['nonexistent-order-id'], $order );
213
  }
214
 
215
  $payer_id = $request->get_param( 'payer_id' );
216
+
217
  $paypal_capture_response = tribe( Client::class )->capture_order( $paypal_order_id, $payer_id );
218
 
219
+ $debug_header = tribe( Client::class )->get_debug_header();
220
+ if ( ! empty( $debug_header ) ) {
221
+ $paypal_capture_response['debug_id'] = $debug_header;
222
+ }
223
+
224
+ if (
225
+ 'UNPROCESSABLE_ENTITY' === Arr::get( $paypal_capture_response, 'name' )
226
+ ) {
227
+ // Flag the order as Denied.
228
+ tribe( Order::class )->modify_status( $order->ID, Denied::SLUG, [
229
+ 'gateway_payload' => $paypal_capture_response,
230
+ ] );
231
+
232
+ return new WP_Error( 'tec-tc-gateway-paypal-failed-capture', $messages['failed-capture'], $paypal_capture_response );
233
  }
234
 
235
  $paypal_capture_status = Arr::get( $paypal_capture_response, [ 'status' ] );
236
  $status = tribe( Status::class )->convert_to_commerce_status( $paypal_capture_status );
237
 
238
  if ( ! $status ) {
239
+ return new WP_Error( 'tec-tc-gateway-paypal-invalid-capture-status', $messages['invalid-capture-status'], $paypal_capture_response );
240
  }
241
 
242
  $updated = tribe( Order::class )->modify_status( $order->ID, $status->get_slug(), [
259
  return new WP_REST_Response( $response );
260
  }
261
 
262
+ /**
263
+ * Handles the request that handles failing an order with Tickets Commerce and the PayPal gateway.
264
+ *
265
+ * @since 5.2.0
266
+ *
267
+ * @param WP_REST_Request $request The request object.
268
+ *
269
+ * @return WP_Error|WP_REST_Response An array containing the data on success or a WP_Error instance on failure.
270
+ */
271
+ public function handle_fail_order( WP_REST_Request $request ) {
272
+ $response = [
273
+ 'success' => false,
274
+ ];
275
+
276
+ $paypal_order_id = $request->get_param( 'order_id' );
277
+ $order = tec_tc_orders()->by_args( [
278
+ 'status' => 'any',
279
+ 'gateway_order_id' => $paypal_order_id,
280
+ ] )->first();
281
+
282
+ $messages = $this->get_error_messages();
283
+
284
+ if ( ! $order ) {
285
+ return new WP_Error( 'tec-tc-gateway-paypal-nonexistent-order-id', null, $order );
286
+ }
287
+
288
+ $failed_reason = $request->get_param( 'failed_reason' );
289
+ $failed_status = $request->get_param( 'failed_status' );
290
+ if ( empty( $failed_status ) ) {
291
+ $failed_status = 'not-completed';
292
+ }
293
+
294
+ $status = tribe( Status_Handler::class )->get_by_slug( $failed_status );
295
+
296
+ if ( ! $status ) {
297
+ return new WP_Error( 'tec-tc-gateway-paypal-invalid-failed-status', null, [
298
+ 'failed_status' => $failed_status,
299
+ 'failed_reason' => $failed_reason
300
+ ] );
301
+ }
302
+
303
+ /**
304
+ * @todo possible determine if we should have error code associated with the failing of this order.
305
+ */
306
+ $updated = tribe( Order::class )->modify_status( $order->ID, $status->get_slug() );
307
+
308
+ if ( is_wp_error( $updated ) ) {
309
+ return $updated;
310
+ }
311
+
312
+ $response['success'] = true;
313
+ $response['status'] = $status->get_slug();
314
+ $response['order_id'] = $order->ID;
315
+ $response['title'] = $messages['canceled-creating-order'];
316
+
317
+ return new WP_REST_Response( $response );
318
+ }
319
+
320
  /**
321
  * Arguments used for the signup redirect.
322
  *
329
  }
330
 
331
  /**
332
+ * Arguments used for the updating order for PayPal.
333
  *
334
  * @since 5.1.9
335
  *
350
  },
351
  'sanitize_callback' => [ $this, 'sanitize_callback' ],
352
  ],
353
+ 'payer_id' => [
354
+ 'description' => __( 'Payer ID token from PayPal', 'event-tickets' ),
355
+ 'required' => false,
356
+ 'type' => 'string',
357
+ 'validate_callback' => static function ( $value ) {
358
+ if ( ! is_string( $value ) ) {
359
+ return new WP_Error( 'rest_invalid_param', 'The payer ID argument must be a string.', [ 'status' => 400 ] );
360
+ }
361
+
362
+ return $value;
363
+ },
364
+ 'sanitize_callback' => [ $this, 'sanitize_callback' ],
365
+ ],
366
+ ];
367
+ }
368
+
369
+ /**
370
+ * Arguments used for the deleting order for PayPal.
371
+ *
372
+ * @since 5.2.0
373
+ *
374
+ * @return array
375
+ */
376
+ public function fail_order_args() {
377
+ return [
378
+ 'order_id' => [
379
+ 'description' => __( 'Order ID in PayPal', 'event-tickets' ),
380
+ 'required' => true,
381
+ 'type' => 'string',
382
+ 'validate_callback' => static function ( $value ) {
383
+ if ( ! is_string( $value ) ) {
384
+ return new WP_Error( 'rest_invalid_param', 'The order ID argument must be a string.', [ 'status' => 400 ] );
385
+ }
386
+
387
+ return $value;
388
+ },
389
+ 'sanitize_callback' => [ $this, 'sanitize_callback' ],
390
+ ],
391
+ 'failed_status' => [
392
+ 'description' => __( 'To which status the failing should change this order to', 'event-tickets' ),
393
+ 'required' => false,
394
+ 'type' => 'string',
395
+ 'validate_callback' => static function ( $value ) {
396
+ if ( ! is_string( $value ) ) {
397
+ return new WP_Error( 'rest_invalid_param', 'The failed status argument must be a string.', [ 'status' => 400 ] );
398
+ }
399
+
400
+ return $value;
401
+ },
402
+ 'sanitize_callback' => [ $this, 'sanitize_callback' ],
403
+ ],
404
+ 'failed_reason' => [
405
+ 'description' => __( 'Why this particular order has failed.', 'event-tickets' ),
406
+ 'required' => false,
407
+ 'type' => 'string',
408
+ 'validate_callback' => static function ( $value ) {
409
+ if ( ! is_string( $value ) ) {
410
+ return new WP_Error( 'rest_invalid_param', 'The failed reason argument must be a string.', [ 'status' => 400 ] );
411
+ }
412
+
413
+ return $value;
414
+ },
415
+ 'sanitize_callback' => [ $this, 'sanitize_callback' ],
416
+ ],
417
  ];
418
  }
419
 
446
  public function get_documentation() {
447
  return [];
448
  }
449
+
450
+ /**
451
+ * Returns an array of error messages that are used by the API responses.
452
+ *
453
+ * @since 5.2.0
454
+ *
455
+ * @return array $messages Array of error messages.
456
+ */
457
+ public function get_error_messages() {
458
+ $messages = [
459
+ 'failed-creating-order' => __( 'Creating new PayPal order failed. Please try again.', 'event-tickets' ),
460
+ 'canceled-creating-order' => __( 'Your PayPal order was cancelled.', 'event-tickets' ),
461
+ 'nonexistent-order-id' => __( 'Provided Order id is not valid.', 'event-tickets' ),
462
+ 'failed-capture' => __( 'There was a problem while processing your payment, please try again.', 'event-tickets' ),
463
+ 'invalid-capture-status' => __( 'There was a problem with the Order status change, please try again.', 'event-tickets' ),
464
+ ];
465
+
466
+ /**
467
+ * Filter the error messages for PayPal checkout.
468
+ *
469
+ * @since 5.2.0
470
+ *
471
+ * @param array $messages Array of error messages.
472
+ */
473
+ return apply_filters( 'tec_tickets_commerce_order_endpoint_error_messages', $messages );
474
+ }
475
  }
src/Tickets/Commerce/Gateways/PayPal/REST/Webhook_Endpoint.php CHANGED
@@ -176,6 +176,11 @@ class Webhook_Endpoint implements Tribe__Documentation__Swagger__Provider_Interf
176
  return new WP_Error( 'tec-tickets-commerce-paypal-webhook-signature-error', null, [ 'webhook_id' => $webhook_id, 'event' => $event, 'headers' => $headers ] );
177
  }
178
 
 
 
 
 
 
179
  $order = tribe( Webhooks\Handler::class )->process_event( $event );
180
 
181
  if ( is_wp_error( $order ) ) {
176
  return new WP_Error( 'tec-tickets-commerce-paypal-webhook-signature-error', null, [ 'webhook_id' => $webhook_id, 'event' => $event, 'headers' => $headers ] );
177
  }
178
 
179
+ $debug_header = $request->get_header( 'Paypal-Debug-Id' );
180
+ if ( ! empty( $debug_header ) ) {
181
+ $event['debug_id'] = $debug_header;
182
+ }
183
+
184
  $order = tribe( Webhooks\Handler::class )->process_event( $event );
185
 
186
  if ( is_wp_error( $order ) ) {
src/Tickets/Commerce/Gateways/PayPal/Settings.php CHANGED
@@ -55,10 +55,11 @@ class Settings extends Abstract_Settings {
55
  $signup = tribe( SignUp::class );
56
 
57
  $context = [
58
- 'plugin_url' => Tribe__Tickets__Main::instance()->plugin_url,
59
- 'merchant' => $merchant,
60
- 'is_merchant_active' => $merchant->is_active(),
61
- 'signup' => $signup,
 
62
  ];
63
 
64
  $admin_views->add_template_globals( $context );
@@ -81,7 +82,7 @@ class Settings extends Abstract_Settings {
81
  );
82
 
83
  $message = sprintf(
84
- // Translators: %s: The PayPal telephone number.
85
  esc_html__( 'Please call a PayPal support representative at %s', 'event-tickets' ),
86
  $telephone
87
  );
55
  $signup = tribe( SignUp::class );
56
 
57
  $context = [
58
+ 'plugin_url' => Tribe__Tickets__Main::instance()->plugin_url,
59
+ 'merchant' => $merchant,
60
+ 'is_merchant_connected' => $merchant->is_connected(),
61
+ 'is_merchant_active' => $merchant->is_active(),
62
+ 'signup' => $signup,
63
  ];
64
 
65
  $admin_views->add_template_globals( $context );
82
  );
83
 
84
  $message = sprintf(
85
+ // Translators: %s: The PayPal telephone number.
86
  esc_html__( 'Please call a PayPal support representative at %s', 'event-tickets' ),
87
  $telephone
88
  );
src/Tickets/Commerce/Gateways/PayPal/Signup.php CHANGED
@@ -1,6 +1,10 @@
1
  <?php
2
 
3
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
 
 
 
 
4
  use Tribe__Utils__Array as Arr;
5
 
6
  /**
@@ -179,19 +183,25 @@ class Signup {
179
  *
180
  * @since 5.1.9
181
  *
 
 
 
182
  * @return string|false
183
  */
184
- public function generate_url() {
185
  // Fetch the cached value for this user.
186
  $signup = $this->get_transient_data();
187
- if ( $signup_url = Arr::get( $signup, [ 'links', 1, 'href' ] ) ) {
 
 
 
188
  return $signup_url;
189
  }
190
 
191
  $hash = $this->generate_unique_signup_hash();
192
  $this->update_transient_hash( $hash );
193
 
194
- $signup = tribe( WhoDat::class )->get_seller_signup_data( $hash );
195
 
196
  if ( ! $signup_url = Arr::get( $signup, [ 'links', 1, 'href' ] ) ) {
197
  return false;
@@ -218,6 +228,40 @@ class Signup {
218
  return Arr::get( $links, [ 'links', 0, 'href' ], false );
219
  }
220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  /**
222
  * Gets the content for the template used for the sign up link that paypal creates.
223
  *
@@ -226,10 +270,119 @@ class Signup {
226
  * @return false|string
227
  */
228
  public function get_link_html() {
 
229
  $template_vars = [
230
- 'url' => $this->generate_url(),
 
231
  ];
232
 
233
  return $this->get_template()->template( 'signup-link', $template_vars, false );
234
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  }
1
  <?php
2
 
3
  namespace TEC\Tickets\Commerce\Gateways\PayPal;
4
+
5
+ use TEC\Tickets\Commerce\Gateways\PayPal\Location\Country;
6
+ use TEC\Tickets\Commerce\Gateways\PayPal\REST\On_Boarding_Endpoint;
7
+ use TEC\Tickets\Commerce\Settings;
8
  use Tribe__Utils__Array as Arr;
9
 
10
  /**
183
  *
184
  * @since 5.1.9
185
  *
186
+ * @param string $country Which country code we are generating the URL for.
187
+ * @param bool $force It prevents the system from using the cached version of the URL.
188
+ *
189
  * @return string|false
190
  */
191
+ public function generate_url( $country, $force = false ) {
192
  // Fetch the cached value for this user.
193
  $signup = $this->get_transient_data();
194
+ if (
195
+ false === $force
196
+ && $signup_url = Arr::get( $signup, [ 'links', 1, 'href' ] )
197
+ ) {
198
  return $signup_url;
199
  }
200
 
201
  $hash = $this->generate_unique_signup_hash();
202
  $this->update_transient_hash( $hash );
203
 
204
+ $signup = tribe( WhoDat::class )->get_seller_signup_data( $hash, $country );
205
 
206
  if ( ! $signup_url = Arr::get( $signup, [ 'links', 1, 'href' ] ) ) {
207
  return false;
228
  return Arr::get( $links, [ 'links', 0, 'href' ], false );
229
  }
230
 
231
+ /**
232
+ * Refresh the Connect link when someone changes the country.
233
+ *
234
+ * @since 5.2.0
235
+ *
236
+ * @return void
237
+ */
238
+ public function ajax_refresh_connect_url() {
239
+ $data = [];
240
+ $nonce = tribe_get_request_var( 'nonce' );
241
+
242
+ if ( ! wp_verify_nonce( $nonce, 'tec-tickets-commerce-gateway-paypal-refresh-connect-url' ) ) {
243
+ wp_send_json_error( new \WP_Error( 'tec-tickets-commerce-paypal-nonce-problem' ) );
244
+ return;
245
+ }
246
+
247
+ $country = tribe_get_request_var( 'country_code', 'US' );
248
+
249
+ // Save to the DB.
250
+ tribe( Country::class )->save_setting( $country );
251
+
252
+ $new_url = $this->generate_url( $country, true );
253
+ if ( empty( $new_url ) ) {
254
+ wp_send_json_error( new \WP_Error( 'tec-tickets-commerce-paypal-refresh-connect-url-error' ) );
255
+ return;
256
+ }
257
+
258
+ // Append the minibrowser query arg.
259
+ $data['new_url'] = $new_url . '&displayMode=minibrowser';
260
+
261
+ wp_send_json_success( $data );
262
+ return;
263
+ }
264
+
265
  /**
266
  * Gets the content for the template used for the sign up link that paypal creates.
267
  *
270
  * @return false|string
271
  */
272
  public function get_link_html() {
273
+ $country = tribe( Country::class )->get_setting();
274
  $template_vars = [
275
+ 'url' => $this->generate_url( $country ),
276
+ 'country_code' => $country,
277
  ];
278
 
279
  return $this->get_template()->template( 'signup-link', $template_vars, false );
280
  }
281
+
282
+
283
+ /**
284
+ * Validate seller on Boarding status data.
285
+ *
286
+ * @since 5.2.0
287
+ *
288
+ * @return string[]
289
+ */
290
+ public function get_errors_from_on_boarded_data() {
291
+ $error_messages = [];
292
+ $merchant = tribe( Merchant::class );
293
+ $saved_merchant_id = $merchant->get_merchant_id_in_paypal();
294
+ if ( ! $saved_merchant_id ) {
295
+ return [];
296
+ }
297
+
298
+ $seller_status = tribe( WhoDat::class )->get_seller_status( $saved_merchant_id );
299
+
300
+ if ( array_diff( [ 'payments_receivable', 'primary_email_confirmed' ], array_keys( $seller_status ) ) ) {
301
+ $error_messages[] = esc_html__( 'There was a problem with the status check for your account. Please try disconnecting and connecting again. If the problem persists, please contact support.', 'event-tickets' );
302
+
303
+ // Return here since the rest of the validations will definitely fail
304
+ return $error_messages;
305
+ }
306
+
307
+ $payments_receivable = tribe_is_truthy( Arr::get( $seller_status, 'payments_receivable' ) );
308
+ $primary_email_confirmed = tribe_is_truthy( Arr::get( $seller_status, 'primary_email_confirmed' ) );
309
+
310
+ if ( ! $payments_receivable ) {
311
+ $error_messages[] = esc_html__( 'Set up an account to receive payment from PayPal', 'event-tickets' );
312
+ }
313
+
314
+ if ( ! $primary_email_confirmed ) {
315
+ $error_messages[] = esc_html__( 'Confirm your primary email address', 'event-tickets' );
316
+ }
317
+
318
+ $merchant->set_account_is_ready( $payments_receivable && $primary_email_confirmed );
319
+ $merchant->save();
320
+
321
+ if ( ! $merchant->get_supports_custom_payments() ) {
322
+ return ! empty( $error_messages ) ? $error_messages : [];
323
+ }
324
+
325
+ if ( array_diff( [ 'products', 'capabilities' ], array_keys( $seller_status ) ) ) {
326
+ $error_messages[] = esc_html__( 'Your account was expected to be able to accept custom payments, but is not. Please make sure your
327
+ account country matches the country setting. If the problem persists, please contact PayPal.', 'event-tickets' );
328
+
329
+ // Return here since the rest of the validations will definitely fail
330
+ return $error_messages;
331
+ }
332
+
333
+ // Grab the PPCP_CUSTOM product from the status data
334
+ $custom_product = current(
335
+ array_filter(
336
+ $seller_status['products'],
337
+ static function ( $product ) {
338
+ return 'PPCP_CUSTOM' === $product['name'];
339
+ }
340
+ )
341
+ );
342
+
343
+ $has_custom_payments = 'SUBSCRIBED' === Arr::get( $custom_product, 'vetting_status' );
344
+ if ( ! $has_custom_payments ) {
345
+ $error_messages[] = esc_html__( 'Reach out to PayPal to enable PPCP_CUSTOM for your account', 'event-tickets' );
346
+ }
347
+
348
+ // Loop through the capabilities and see if any are not active
349
+ $invalid_capabilities = [];
350
+ foreach ( $seller_status['capabilities'] as $capability ) {
351
+ if ( $capability['status'] !== 'ACTIVE' ) {
352
+ $invalid_capabilities[] = $capability['name'];
353
+ }
354
+ }
355
+
356
+ if ( ! empty( $invalid_capabilities ) ) {
357
+ $error_messages[] = esc_html__( 'Reach out to PayPal to resolve the following capabilities:', 'event-tickets' ) . ' ' . implode( ', ', $invalid_capabilities );
358
+ }
359
+
360
+ // If there were errors then redirect the user with notices
361
+ return $error_messages;
362
+ }
363
+
364
+ /**
365
+ * When toggling between PayPal test mode and live mode, we need to re-generate
366
+ * the transients to make sure the proper URLs are used.
367
+ *
368
+ * @since 5.2.0
369
+ *
370
+ * @param array $options the list of plugin options set for saving
371
+ *
372
+ * @return array
373
+ */
374
+ public function maybe_delete_transient_data( $options ) {
375
+
376
+ if ( ! isset( $options[ Settings::$option_sandbox ] ) ) {
377
+ return $options;
378
+ }
379
+
380
+ if ( tec_tickets_commerce_is_sandbox_mode() === $options[ Settings::$option_sandbox ] ) {
381
+ return $options;
382
+ }
383
+
384
+ $this->delete_transient_data();
385
+
386
+ return $options;
387
+ }
388
  }
src/Tickets/Commerce/Gateways/PayPal/Webhooks.php CHANGED
@@ -108,6 +108,7 @@ class Webhooks {
108
  }
109
 
110
  if ( 'tec-tickets-commerce-gateway-paypal-webhook-url-already-exists' === $webhook->get_error_code() ) {
 
111
  $existing_webhooks = $client->list_webhooks();
112
  $existing_webhooks = array_filter( array_map( static function ( $webhook ) {
113
  if ( tribe( Webhook_Endpoint::class )->get_route_url() !== $webhook['url'] ) {
@@ -117,7 +118,7 @@ class Webhooks {
117
  return $webhook;
118
  }, $existing_webhooks ) );
119
  if ( empty( $existing_webhooks ) ) {
120
- return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-unexpected-update-create' );
121
  }
122
  $existing_webhook = current( $existing_webhooks );
123
 
108
  }
109
 
110
  if ( 'tec-tickets-commerce-gateway-paypal-webhook-url-already-exists' === $webhook->get_error_code() ) {
111
+ $error_message = $webhook->get_error_message();
112
  $existing_webhooks = $client->list_webhooks();
113
  $existing_webhooks = array_filter( array_map( static function ( $webhook ) {
114
  if ( tribe( Webhook_Endpoint::class )->get_route_url() !== $webhook['url'] ) {
118
  return $webhook;
119
  }, $existing_webhooks ) );
120
  if ( empty( $existing_webhooks ) ) {
121
+ return new \WP_Error( 'tec-tickets-commerce-gateway-paypal-webhook-unexpected-update-create', $error_message );
122
  }
123
  $existing_webhook = current( $existing_webhooks );
124
 
src/Tickets/Commerce/Gateways/PayPal/Webhooks/Events.php CHANGED
@@ -62,6 +62,44 @@ class Events {
62
  self::PAYMENT_CAPTURE_REVERSED => Commerce_Status\Reversed::SLUG,
63
  ];
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  /**
66
  * Gets the valid mapping of the webhook events.
67
  *
@@ -77,7 +115,7 @@ class Events {
77
  *
78
  * @param array $map The default map of which event types that translate to a given Status class.
79
  */
80
- return apply_filters( 'tec_tickets_commerce_gateway_paypal_webook_events_map', $this->default_map );
81
  }
82
 
83
  /**
62
  self::PAYMENT_CAPTURE_REVERSED => Commerce_Status\Reversed::SLUG,
63
  ];
64
 
65
+ /**
66
+ * Return webhook label's "Nice name".
67
+ *
68
+ * @since 5.2.0
69
+ *
70
+ * @param string $event_name A PayPal Event String.
71
+ *
72
+ * @return string The Webhook label, false on error.
73
+ */
74
+ public function get_webhook_label( $event_name ) {
75
+ $labels = [
76
+ static::PAYMENT_CAPTURE_COMPLETED => __( 'Completed payments', 'event-tickets' ),
77
+ static::PAYMENT_CAPTURE_DENIED => __( 'Denied payments', 'event-tickets' ),
78
+ static::PAYMENT_CAPTURE_REFUNDED => __( 'Refunds', 'event-tickets' ),
79
+ static::PAYMENT_CAPTURE_REVERSED => __( 'Reversed', 'event-tickets' ),
80
+ ];
81
+
82
+ /**
83
+ * Allows filtering of the Webhook map of events for each one of the types we listen for.
84
+ *
85
+ * @since 5.2.0
86
+ *
87
+ * @param array $labels The default map of which event types that translate to a given label string.
88
+ * @param string $event_name Which event name we are looking for.
89
+ */
90
+ $labels = apply_filters( 'tec_tickets_commerce_gateway_paypal_webhook_events_labels_map', $labels, $event_name );
91
+
92
+ if ( ! $this->is_valid( $event_name ) ) {
93
+ return false;
94
+ }
95
+
96
+ if ( isset( $labels[ $event_name ] ) ) {
97
+ return $labels[ $event_name ];
98
+ }
99
+
100
+ return false;
101
+ }
102
+
103
  /**
104
  * Gets the valid mapping of the webhook events.
105
  *
115
  *
116
  * @param array $map The default map of which event types that translate to a given Status class.
117
  */
118
+ return apply_filters( 'tec_tickets_commerce_gateway_paypal_webhook_events_map', $this->default_map );
119
  }
120
 
121
  /**
src/Tickets/Commerce/Gateways/PayPal/WhoDat.php CHANGED
@@ -41,9 +41,12 @@ class WhoDat {
41
  *
42
  * @since 5.1.9
43
  *
 
 
 
44
  * @return array|string
45
  */
46
- public function get_seller_signup_data( $hash ) {
47
  if ( empty( $hash ) ) {
48
  $hash = tribe( Signup::class )->generate_unique_signup_hash();
49
  }
@@ -54,6 +57,7 @@ class WhoDat {
54
  'nonce' => $hash,
55
  'tracking_id' => urlencode( tribe( Signup::class )->generate_unique_tracking_id() ),
56
  'return_url' => esc_url( $return_url ),
 
57
  ];
58
 
59
  return $this->get( 'seller/signup', $query_args );
@@ -158,11 +162,11 @@ class WhoDat {
158
  'body' => [],
159
  ];
160
 
161
-
162
  foreach ( $default_arguments as $key => $default_argument ) {
163
  $request_arguments[ $key ] = array_merge( $default_argument, Arr::get( $request_arguments, $key, [] ) );
164
  }
165
- $request = wp_remote_post( $url, $request_arguments );
 
166
 
167
  if ( is_wp_error( $request ) ) {
168
  $this->log_error( 'WhoDat request error:', $request->get_error_message(), $url );
41
  *
42
  * @since 5.1.9
43
  *
44
+ * @param string $hash Which unique hash we are passing to the PayPal system.
45
+ * @param string $country Which country code we are using.
46
+ *
47
  * @return array|string
48
  */
49
+ public function get_seller_signup_data( $hash, $country ) {
50
  if ( empty( $hash ) ) {
51
  $hash = tribe( Signup::class )->generate_unique_signup_hash();
52
  }
57
  'nonce' => $hash,
58
  'tracking_id' => urlencode( tribe( Signup::class )->generate_unique_tracking_id() ),
59
  'return_url' => esc_url( $return_url ),
60
+ 'country' => $country,
61
  ];
62
 
63
  return $this->get( 'seller/signup', $query_args );
162
  'body' => [],
163
  ];
164
 
 
165
  foreach ( $default_arguments as $key => $default_argument ) {
166
  $request_arguments[ $key ] = array_merge( $default_argument, Arr::get( $request_arguments, $key, [] ) );
167
  }
168
+ $request_arguments = array_filter( $request_arguments );
169
+ $request = wp_remote_post( $url, $request_arguments );
170
 
171
  if ( is_wp_error( $request ) ) {
172
  $this->log_error( 'WhoDat request error:', $request->get_error_message(), $url );
src/Tickets/Commerce/Hooks.php CHANGED
@@ -18,8 +18,11 @@
18
  namespace TEC\Tickets\Commerce;
19
 
20
  use \tad_DI52_ServiceProvider;
 
 
21
  use TEC\Tickets\Commerce\Status\Completed;
22
- use Tribe\Tickets\Shortcodes\Tribe_Tickets_Checkout;
 
23
 
24
  /**
25
  * Class Hooks.
@@ -46,10 +49,15 @@ class Hooks extends tad_DI52_ServiceProvider {
46
  * @since 5.1.6
47
  */
48
  protected function add_actions() {
49
- add_action( 'tribe_settings_do_tabs', [ $this, 'register_payments_tab' ], 15 );
50
-
51
  add_action( 'init', [ $this, 'register_post_types' ] );
52
  add_action( 'init', [ $this, 'register_order_statuses' ], 11 );
 
 
 
 
 
 
 
53
  add_action( 'tribe_common_loaded', [ $this, 'load_commerce_module' ] );
54
 
55
  add_action( 'template_redirect', [ $this, 'do_cart_parse_request' ] );
@@ -61,7 +69,7 @@ class Hooks extends tad_DI52_ServiceProvider {
61
  add_action( 'wp_loaded', [ $this, 'maybe_delete_expired_products' ], 0 );
62
  add_action( 'wp_loaded', [ $this, 'maybe_redirect_to_attendees_registration_screen' ], 1 );
63
 
64
- add_action( 'tribe_events_tickets_metabox_edit_advanced', [ $this, 'include_metabox_advanced_options' ], 10, 2 );
65
 
66
  add_action( 'tribe_events_tickets_attendees_event_details_top', [ $this, 'setup_attendance_totals' ] );
67
  add_action( 'trashed_post', [ $this, 'maybe_redirect_to_attendees_report' ] );
@@ -71,6 +79,12 @@ class Hooks extends tad_DI52_ServiceProvider {
71
 
72
  // This needs to run earlier than our page setup.
73
  add_action( 'admin_init', [ $this, 'maybe_trigger_process_action' ], 5 );
 
 
 
 
 
 
74
  }
75
 
76
  /**
@@ -82,19 +96,48 @@ class Hooks extends tad_DI52_ServiceProvider {
82
  add_filter( 'tribe_shortcodes', [ $this, 'filter_register_shortcodes' ] );
83
 
84
  add_filter( 'tribe_attendee_registration_form_classes', [ $this, 'filter_registration_form_class' ] );
85
- add_filter( 'tribe_attendee_registration_cart_provider', [ $this, 'filter_registration_cart_provider' ], 10, 2 );
86
 
87
  add_filter( 'tribe_tickets_get_default_module', [ $this, 'filter_de_prioritize_module' ], 5, 2 );
88
 
89
  add_filter( 'tribe_tickets_checkout_urls', [ $this, 'filter_js_include_checkout_url' ] );
90
  add_filter( 'tribe_tickets_cart_urls', [ $this, 'filter_js_include_cart_url' ] );
91
 
 
 
 
 
 
 
 
92
  add_filter( 'event_tickets_attendees_tc_checkin_stati', [ $this, 'filter_checkin_statuses' ] );
93
 
94
  // Add a post display state for special Event Tickets pages.
95
  add_filter( 'display_post_states', [ $this, 'add_display_post_states' ], 10, 2 );
96
 
 
 
 
97
  $this->provider_meta_sanitization_filters();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  }
99
 
100
  /**
@@ -106,10 +149,6 @@ class Hooks extends tad_DI52_ServiceProvider {
106
  $this->container->make( Module::class );
107
  }
108
 
109
- public function register_payments_tab() {
110
- $this->container->make( Settings::class )->register_tab();
111
- }
112
-
113
  /**
114
  * Register all Commerce Post Types in WordPress.
115
  *
@@ -121,6 +160,18 @@ class Hooks extends tad_DI52_ServiceProvider {
121
  $this->container->make( Ticket::class )->register_post_type();
122
  }
123
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  /**
125
  * Register all Order Statuses with WP.
126
  *
@@ -130,6 +181,28 @@ class Hooks extends tad_DI52_ServiceProvider {
130
  $this->container->make( Status\Status_Handler::class )->register_order_statuses();
131
  }
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  /**
134
  * Depending on which page, tab and if an action is present we trigger the processing.
135
  *
@@ -194,11 +267,24 @@ class Hooks extends tad_DI52_ServiceProvider {
194
  * @return array The original array plus the 'yes' status.
195
  */
196
  public function filter_checkin_statuses( array $statuses = [] ) {
197
- $statuses[] = tribe( Completed::class )->get_wp_slug();
198
 
199
  return array_unique( $statuses );
200
  }
201
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  /**
203
  * Parse the cart request, and possibly redirect, so it happens on `template_redirect`.
204
  *
@@ -224,9 +310,9 @@ class Hooks extends tad_DI52_ServiceProvider {
224
  *
225
  * @since 5.1.9
226
  *
227
- * @param int $ticket_id the attendee id being deleted
228
- * @param int $post_id the post or event id for the attendee
229
- * @param int $product_id the ticket-product id in Tribe Commerce
230
  */
231
  public function update_stock_after_deletion( $ticket_id, $post_id, $product_id ) {
232
  $this->container->make( Ticket::class )->update_stock_after_deletion( $ticket_id, $post_id, $product_id );
@@ -246,7 +332,7 @@ class Hooks extends tad_DI52_ServiceProvider {
246
  *
247
  * @since 5.1.94
248
  *
249
- * @param int $post_id WP_Post ID
250
  */
251
  public function maybe_redirect_to_attendees_report( $post_id ) {
252
  $this->container->make( Attendee::class )->maybe_redirect_to_attendees_report( $post_id );
@@ -272,7 +358,6 @@ class Hooks extends tad_DI52_ServiceProvider {
272
  * @param array $attendee_data Information that we are trying to save.
273
  * @param int $attendee_id The attendee ID.
274
  * @param int $post_id The event/post ID.
275
- *
276
  */
277
  public function update_attendee_data( $attendee_data, $attendee_id, $post_id ) {
278
  $this->container->make( Attendee::class )->update_attendee_data( $attendee_data, $attendee_id, $post_id );
@@ -284,7 +369,6 @@ class Hooks extends tad_DI52_ServiceProvider {
284
  * @since 5.1.9
285
  *
286
  * @param int $event_id Which ID we are triggering changes to.
287
- *
288
  */
289
  public function maybe_send_tickets_after_status_change( $event_id ) {
290
  $this->container->make( Attendee::class )->maybe_send_tickets_after_status_change( $event_id );
@@ -440,7 +524,13 @@ class Hooks extends tad_DI52_ServiceProvider {
440
  */
441
  $ticket_handler = tribe( 'tickets.handler' );
442
 
443
- add_filter( "sanitize_post_meta_{$ticket_handler->key_provider_field}" , [ $this, 'filter_modify_sanitization_provider_meta' ] );
 
 
 
 
 
 
444
  }
445
 
446
  /**
@@ -448,11 +538,178 @@ class Hooks extends tad_DI52_ServiceProvider {
448
  *
449
  * @since 5.1.10
450
  *
451
- * @param mixed $meta_value Metadata value.
452
  *
453
  * @return string
454
  */
455
  public function filter_modify_sanitization_provider_meta( $meta_value ) {
456
  return tribe( Settings::class )->skip_sanitization( $meta_value );
457
  }
458
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  namespace TEC\Tickets\Commerce;
19
 
20
  use \tad_DI52_ServiceProvider;
21
+ use TEC\Tickets\Commerce as Base_Commerce;
22
+ use TEC\Tickets\Commerce\Reports\Orders;
23
  use TEC\Tickets\Commerce\Status\Completed;
24
+ use TEC\Tickets\Commerce\Status\Status_Interface;
25
+ use WP_Admin_Bar;
26
 
27
  /**
28
  * Class Hooks.
49
  * @since 5.1.6
50
  */
51
  protected function add_actions() {
 
 
52
  add_action( 'init', [ $this, 'register_post_types' ] );
53
  add_action( 'init', [ $this, 'register_order_statuses' ], 11 );
54
+
55
+ add_action( 'init', [ $this, 'register_order_reports' ] );
56
+ add_action( 'init', [ $this, 'register_attendee_reports' ] );
57
+
58
+ // Compatibility Hooks
59
+ add_action( 'init', [ $this, 'register_event_compatibility_hooks' ] );
60
+
61
  add_action( 'tribe_common_loaded', [ $this, 'load_commerce_module' ] );
62
 
63
  add_action( 'template_redirect', [ $this, 'do_cart_parse_request' ] );
69
  add_action( 'wp_loaded', [ $this, 'maybe_delete_expired_products' ], 0 );
70
  add_action( 'wp_loaded', [ $this, 'maybe_redirect_to_attendees_registration_screen' ], 1 );
71
 
72
+ add_action( 'tribe_events_tickets_metabox_edit_advanced', [ $this, 'include_metabox_advanced_options', ], 10, 2 );
73
 
74
  add_action( 'tribe_events_tickets_attendees_event_details_top', [ $this, 'setup_attendance_totals' ] );
75
  add_action( 'trashed_post', [ $this, 'maybe_redirect_to_attendees_report' ] );
79
 
80
  // This needs to run earlier than our page setup.
81
  add_action( 'admin_init', [ $this, 'maybe_trigger_process_action' ], 5 );
82
+
83
+ add_action( 'tec_tickets_commerce_order_status_transition', [ $this, 'modify_tickets_counters_by_status', ], 15, 3 );
84
+
85
+ add_action( 'admin_bar_menu', [ $this, 'include_admin_bar_test_mode' ], 1000, 1 );
86
+
87
+ add_action( 'tribe_template_before_include:tickets/v2/commerce/checkout', [ $this, 'include_assets_checkout_shortcode' ] );
88
  }
89
 
90
  /**
96
  add_filter( 'tribe_shortcodes', [ $this, 'filter_register_shortcodes' ] );
97
 
98
  add_filter( 'tribe_attendee_registration_form_classes', [ $this, 'filter_registration_form_class' ] );
99
+ add_filter( 'tribe_attendee_registration_cart_provider', [ $this, 'filter_registration_cart_provider', ], 10, 2 );
100
 
101
  add_filter( 'tribe_tickets_get_default_module', [ $this, 'filter_de_prioritize_module' ], 5, 2 );
102
 
103
  add_filter( 'tribe_tickets_checkout_urls', [ $this, 'filter_js_include_checkout_url' ] );
104
  add_filter( 'tribe_tickets_cart_urls', [ $this, 'filter_js_include_cart_url' ] );
105
 
106
+ add_filter( 'tribe_tickets_tickets_in_cart', [ $this, 'filter_tickets_in_cart' ], 10, 2 );
107
+ add_filter( 'tribe_tickets_commerce_cart_get_tickets_' . Base_Commerce::PROVIDER, [ $this, 'filter_rest_get_tickets_in_cart' ] );
108
+ add_filter( 'tribe_rest_url', [ $this, 'filter_rest_cart_url' ], 15, 4 );
109
+
110
+ // @todo @backend We need to revisit the refactoring of this report.
111
+ // add_filter( 'tribe_ticket_filter_attendee_report_link', [ $this, 'filter_attendee_report_link' ], 10, 2 );
112
+
113
  add_filter( 'event_tickets_attendees_tc_checkin_stati', [ $this, 'filter_checkin_statuses' ] );
114
 
115
  // Add a post display state for special Event Tickets pages.
116
  add_filter( 'display_post_states', [ $this, 'add_display_post_states' ], 10, 2 );
117
 
118
+ // Filter the 'View Orders` link from ticket editor.
119
+ add_filter( 'tribe_filter_attendee_order_link', [ $this, 'filter_editor_orders_link' ], 10, 2 );
120
+
121
  $this->provider_meta_sanitization_filters();
122
+
123
+ add_filter( 'tribe_template_context:tickets-plus/v2/tickets/submit/button-modal', [ $this, 'filter_showing_cart_button' ] );
124
+
125
+ add_filter( 'tec_tickets_commerce_payments_tab_settings', [ $this, 'filter_payments_tab_settings' ] );
126
+ }
127
+
128
+ /**
129
+ * Filters the Settings for Payments tab to add the Commerce Provider related fields.
130
+ *
131
+ * @since 5.2.0
132
+ *
133
+ * @param array $settings Settings array data for Payments tab.
134
+ *
135
+ * @return array
136
+ */
137
+ public function filter_payments_tab_settings( $settings ) {
138
+ $settings['fields'] = array_merge( $settings['fields'], tribe( Settings::class )->get_settings() );
139
+
140
+ return $settings;
141
  }
142
 
143
  /**
149
  $this->container->make( Module::class );
150
  }
151
 
 
 
 
 
152
  /**
153
  * Register all Commerce Post Types in WordPress.
154
  *
160
  $this->container->make( Ticket::class )->register_post_type();
161
  }
162
 
163
+ /**
164
+ * Register the Orders report.
165
+ *
166
+ * @todo Currently this is attaching the hook method to the init, which is incorrect we should not be attaching
167
+ * these filters from the orders class if we can avoid it.
168
+ *
169
+ * @since 5.2.0
170
+ */
171
+ public function register_order_reports() {
172
+ $this->container->make( Reports\Orders::class )->hook();
173
+ }
174
+
175
  /**
176
  * Register all Order Statuses with WP.
177
  *
181
  $this->container->make( Status\Status_Handler::class )->register_order_statuses();
182
  }
183
 
184
+ /**
185
+ * Register the Attendees Report
186
+ *
187
+ * @since 5.2.0
188
+ */
189
+ public function register_attendee_reports() {
190
+ $this->container->make( Reports\Attendees::class )->hook();
191
+ }
192
+
193
+ /**
194
+ * Display admin bar when using the Test Mode for payments.
195
+ *
196
+ * @since 5.2.0
197
+ *
198
+ * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference.
199
+ *
200
+ * @return bool
201
+ */
202
+ public function include_admin_bar_test_mode( WP_Admin_Bar $wp_admin_bar ) {
203
+ return $this->container->make( Settings::class )->include_admin_bar_test_mode( $wp_admin_bar );
204
+ }
205
+
206
  /**
207
  * Depending on which page, tab and if an action is present we trigger the processing.
208
  *
267
  * @return array The original array plus the 'yes' status.
268
  */
269
  public function filter_checkin_statuses( array $statuses = [] ) {
270
+ $statuses[] = tribe( Completed::class )->get_name();
271
 
272
  return array_unique( $statuses );
273
  }
274
 
275
+ /**
276
+ * Modify the counters for all the tickets involved on this particular order.
277
+ *
278
+ * @since 5.2.0
279
+ *
280
+ * @param Status_Interface $new_status New post status.
281
+ * @param Status_Interface|null $old_status Old post status.
282
+ * @param \WP_Post $post Post object.
283
+ */
284
+ public function modify_tickets_counters_by_status( $new_status, $old_status, $post ) {
285
+ $this->container->make( Ticket::class )->modify_counters_by_status( $new_status, $old_status, $post );
286
+ }
287
+
288
  /**
289
  * Parse the cart request, and possibly redirect, so it happens on `template_redirect`.
290
  *
310
  *
311
  * @since 5.1.9
312
  *
313
+ * @param int $ticket_id the attendee id being deleted.
314
+ * @param int $post_id the post or event id for the attendee.
315
+ * @param int $product_id the ticket-product id in Tribe Commerce.
316
  */
317
  public function update_stock_after_deletion( $ticket_id, $post_id, $product_id ) {
318
  $this->container->make( Ticket::class )->update_stock_after_deletion( $ticket_id, $post_id, $product_id );
332
  *
333
  * @since 5.1.94
334
  *
335
+ * @param int $post_id WP_Post ID.
336
  */
337
  public function maybe_redirect_to_attendees_report( $post_id ) {
338
  $this->container->make( Attendee::class )->maybe_redirect_to_attendees_report( $post_id );
358
  * @param array $attendee_data Information that we are trying to save.
359
  * @param int $attendee_id The attendee ID.
360
  * @param int $post_id The event/post ID.
 
361
  */
362
  public function update_attendee_data( $attendee_data, $attendee_id, $post_id ) {
363
  $this->container->make( Attendee::class )->update_attendee_data( $attendee_data, $attendee_id, $post_id );
369
  * @since 5.1.9
370
  *
371
  * @param int $event_id Which ID we are triggering changes to.
 
372
  */
373
  public function maybe_send_tickets_after_status_change( $event_id ) {
374
  $this->container->make( Attendee::class )->maybe_send_tickets_after_status_change( $event_id );
524
  */
525
  $ticket_handler = tribe( 'tickets.handler' );
526
 
527
+ add_filter(
528
+ "sanitize_post_meta_{$ticket_handler->key_provider_field}",
529
+ [
530
+ $this,
531
+ 'filter_modify_sanitization_provider_meta',
532
+ ]
533
+ );
534
  }
535
 
536
  /**
538
  *
539
  * @since 5.1.10
540
  *
541
+ * @param mixed $meta_value Metadata value.
542
  *
543
  * @return string
544
  */
545
  public function filter_modify_sanitization_provider_meta( $meta_value ) {
546
  return tribe( Settings::class )->skip_sanitization( $meta_value );
547
  }
548
+
549
+ /**
550
+ * If an event is using Tickets Commerce, use the new Attendees View URL
551
+ *
552
+ * @since 5.2.0
553
+ *
554
+ * @param string $url the current Attendees View url.
555
+ * @param int $post_id the event id.
556
+ *
557
+ * @return string
558
+ */
559
+ public function filter_attendee_report_link( $url, $post_id ) {
560
+
561
+ if ( Module::class !== Module::get_event_ticket_provider( $post_id ) ) {
562
+ return $url;
563
+ }
564
+
565
+ return add_query_arg( [ 'page' => 'tickets-commerce-attendees' ], $url );
566
+ }
567
+
568
+ /**
569
+ * Filters the ticket editor order link for Tickets Commerce Module orders.
570
+ *
571
+ * @since 5.2.0
572
+ *
573
+ * @param string $url Url for the order page for ticketed event/post.
574
+ * @param int $post_id The post ID for the current event/post.
575
+ *
576
+ * @return string
577
+ */
578
+ public function filter_editor_orders_link( $url, $post_id ) {
579
+ return $this->container->make( Orders::class )->filter_editor_orders_link( $url, $post_id );
580
+ }
581
+
582
+ /**
583
+ * Hide the 'save and view cart` button from AR Modal depending on Cart type.
584
+ *
585
+ * @since 5.2.0
586
+ *
587
+ * @param array $args Context arraay for the modal template.
588
+ *
589
+ * @return array
590
+ */
591
+ public function filter_showing_cart_button( $args ) {
592
+ if ( ! isset( $args['has_tpp'] ) || ! isset( $args['provider'] ) ) {
593
+ return $args;
594
+ }
595
+
596
+ if ( Module::class !== $args['provider']->class_name ) {
597
+ return $args;
598
+ }
599
+
600
+ $args['has_tpp'] = 'redirect' === $this->container->make( Cart::class )->get_mode();
601
+
602
+ return $args;
603
+ }
604
+
605
+ /**
606
+ * Filters to add Tickets Commerce into the "tickets in cart" array.
607
+ *
608
+ * @since 5.2.0
609
+ *
610
+ * @param array<int> $tickets Tickets in cart. Format: [ ticket_id => quantity ].
611
+ * @param string $provider Commerce provider.
612
+ *
613
+ * @return array
614
+ */
615
+ public function filter_tickets_in_cart( $tickets, $provider ) {
616
+ if ( \TEC\Tickets\Commerce::PROVIDER !== $provider ) {
617
+ return $tickets;
618
+ }
619
+
620
+ $tickets = [];
621
+ $items = tribe( Cart::class )->get_items_in_cart();
622
+
623
+ foreach ( $items as $data ) {
624
+ $tickets[ $data['ticket_id'] ] = $data['quantity'];
625
+ }
626
+
627
+ return $tickets;
628
+ }
629
+
630
+
631
+ /**
632
+ * Modify the cart contents for the Rest call around TTickets Commerce cart.
633
+ *
634
+ * @since 5.2.0
635
+ *
636
+ * @param array $tickets
637
+ *
638
+ * @return array
639
+ */
640
+ public function filter_rest_get_tickets_in_cart( $tickets ) {
641
+ $cookie = tribe_get_request_var( Cart::$cookie_query_arg );
642
+ if ( empty( $cookie ) ) {
643
+ return $tickets;
644
+ }
645
+
646
+ // We reset the tickets passed.
647
+ $tickets = [];
648
+ /* @var Cart $cart */
649
+ $cart = tribe( Cart::class );
650
+ $cookie = tribe_get_request_var( Cart::$cookie_query_arg );
651
+ $cart->set_cart_hash( $cookie );
652
+ $items = $cart->get_items_in_cart( true );
653
+
654
+ foreach ( $items as $data ) {
655
+ $tickets[] = [
656
+ 'ticket_id' => $data['ticket_id'],
657
+ 'quantity' => $data['quantity'],
658
+ 'post_id' => $data['event_id'],
659
+ 'optout' => $data['extra']['optout'],
660
+ 'iac' => $data['extra']['iac'],
661
+ 'provider' => \TEC\Tickets\Commerce::PROVIDER,
662
+ ];
663
+ }
664
+
665
+ return $tickets;
666
+ }
667
+
668
+ /**
669
+ * Modify the Rest URL for the cart to include the TC Cookie.
670
+ *
671
+ * @since 5.2.0
672
+ *
673
+ * @param string $url
674
+ * @param string $path
675
+ * @param int $blog_id
676
+ * @param string $scheme
677
+ *
678
+ * @return string
679
+ */
680
+ public function filter_rest_cart_url( $url, $path, $blog_id, $scheme ) {
681
+ if ( '/cart/' !== $path ) {
682
+ return $url;
683
+ }
684
+
685
+ $cookie = tribe_get_request_var( Cart::$cookie_query_arg );
686
+ if ( empty( $cookie ) ) {
687
+ return $url;
688
+ }
689
+
690
+ return add_query_arg( [ Cart::$cookie_query_arg => $cookie ], $url );
691
+ }
692
+
693
+ /**
694
+ * Hooks for Compatibility with The Events Calendar
695
+ *
696
+ * @since 5.2.0
697
+ */
698
+ public function register_event_compatibility_hooks() {
699
+
700
+ if ( ! tribe( \Tribe__Dependency::class )->is_plugin_active( 'Tribe__Events__Main' ) ) {
701
+ return;
702
+ }
703
+
704
+ add_filter( 'wp_redirect', [ tribe( Compatibility\Events::class ), 'prevent_filter_redirect_canonical' ], 1, 2 );
705
+ }
706
+
707
+ /**
708
+ * Includes the Assets to the checkout page shortcode.
709
+ *
710
+ * @since 5.2.0
711
+ */
712
+ public function include_assets_checkout_shortcode() {
713
+ Shortcodes\Checkout_Shortcode::enqueue_assets();
714
+ }
715
+ }
src/Tickets/Commerce/Legacy_Compat.php CHANGED
@@ -46,9 +46,6 @@ class Legacy_Compat extends tad_DI52_ServiceProvider {
46
  */
47
  protected function add_filters() {
48
  add_filter( 'tribe_events_tickets_module_name', [ $this, 'set_legacy_module_name' ] );
49
-
50
- // Disable TribeCommerce for new installations.
51
- add_filter( 'tribe_tickets_commerce_paypal_is_active', 'tec_tribe_commerce_is_available' );
52
  }
53
 
54
  /**
46
  */
47
  protected function add_filters() {
48
  add_filter( 'tribe_events_tickets_module_name', [ $this, 'set_legacy_module_name' ] );
 
 
 
49
  }
50
 
51
  /**
src/Tickets/Commerce/Models/Attendee_Model.php CHANGED
@@ -9,16 +9,9 @@
9
 
10
  namespace TEC\Tickets\Commerce\Models;
11
 
12
- use DateInterval;
13
- use DatePeriod;
14
- use DateTimeZone;
15
- use TEC\Tickets\Commerce\Module;
16
  use Tribe\Models\Post_Types\Base;
17
  use TEC\Tickets\Commerce\Attendee;
18
- use Tribe\Utils\Lazy_Collection;
19
- use Tribe\Utils\Lazy_String;
20
- use Tribe\Utils\Post_Thumbnail;
21
- use Tribe__Date_Utils as Dates;
22
  use Tribe__Utils__Array as Arr;
23
 
24
  /**
@@ -53,12 +46,10 @@ class Attendee_Model extends Base {
53
  $checked_in = Arr::get( $post_meta, [ Attendee::$checked_in_meta_key, 0 ] );
54
  $security = Arr::get( $post_meta, [ Attendee::$security_code_meta_key, 0 ] );
55
  $opt_out = tribe_is_truthy( Arr::get( $post_meta, [ Attendee::$optout_meta_key, 0 ] ) );
56
- $status = Arr::get( $post_meta, [ Attendee::$status_meta_key, 0 ] );
57
  $ticket_sent = (int) Arr::get( $post_meta, [ Attendee::$ticket_sent_meta_key, 0 ] );
58
  $deleted_ticket_title = Arr::get( $post_meta, [ Attendee::$deleted_ticket_meta_key, 0 ] );
59
- $first_name = Arr::get( $post_meta, [ Attendee::$first_name_meta_key, 0 ] );
60
- $last_name = Arr::get( $post_meta, [ Attendee::$last_name_meta_key, 0 ] );
61
- $full_name = $first_name . ' ' . $last_name;
62
  $email = Arr::get( $post_meta, [ Attendee::$email_meta_key, 0 ] );
63
  $price_paid = Arr::get( $post_meta, [ Attendee::$price_paid_meta_key, 0 ] );
64
  $currency = Arr::get( $post_meta, [ Attendee::$currency_meta_key, 0 ] );
@@ -68,39 +59,45 @@ class Attendee_Model extends Base {
68
  $ticket_unique_id = Arr::get( $post_meta, [ '_unique_id', 0 ] );
69
  $ticket_unique_id = empty( $ticket_unique_id ) ? $post_id : $ticket_unique_id;
70
 
71
- $ticket_title = ( $is_product_deleted ? $ticket->post_title : $deleted_ticket_title . ' ' . __( '(deleted)', 'event-tickets' ) );
72
 
73
  $is_purchaser = $email === $order->purchaser_email;
74
 
75
  $properties = [
76
- 'order_id' => $this->post->post_parent,
77
- 'optout' => $opt_out,
78
- 'ticket' => $ticket_title,
79
- 'attendee_id' => $post_id,
80
- 'security' => $security,
81
- 'product_id' => $ticket_id,
82
- 'check_in' => $checked_in,
83
- 'order_status' => $status,
84
- 'user_id' => $user_id,
85
- 'ticket_sent' => $ticket_sent,
86
- 'price_paid' => $price_paid,
87
- 'currency' => $currency,
 
 
 
 
 
 
 
 
88
 
89
  // Fields for Email Tickets.
90
- 'event_id' => $event_id,
91
- 'ticket_name' => $ticket_title,
92
- 'holder_name' => $full_name,
93
- 'holder_email' => $email,
94
- 'ticket_id' => $ticket_unique_id,
95
- 'qr_ticket_id' => $post_id,
96
- 'security_code' => $security,
97
-
98
- // Attendee Meta, should be populated later by ET+
99
- 'attendee_meta' => [],
100
 
101
  // Handle initial Attendee flags.
102
- 'is_subscribed' => $is_subscribed,
103
- 'is_purchaser' => $is_purchaser,
104
  ];
105
  } catch ( \Exception $e ) {
106
  return [];
9
 
10
  namespace TEC\Tickets\Commerce\Models;
11
 
 
 
 
 
12
  use Tribe\Models\Post_Types\Base;
13
  use TEC\Tickets\Commerce\Attendee;
14
+ use Tribe\Tickets\Plus\Attendee_Registration\IAC;
 
 
 
15
  use Tribe__Utils__Array as Arr;
16
 
17
  /**
46
  $checked_in = Arr::get( $post_meta, [ Attendee::$checked_in_meta_key, 0 ] );
47
  $security = Arr::get( $post_meta, [ Attendee::$security_code_meta_key, 0 ] );
48
  $opt_out = tribe_is_truthy( Arr::get( $post_meta, [ Attendee::$optout_meta_key, 0 ] ) );
49
+ $status = $order->status_name;
50
  $ticket_sent = (int) Arr::get( $post_meta, [ Attendee::$ticket_sent_meta_key, 0 ] );
51
  $deleted_ticket_title = Arr::get( $post_meta, [ Attendee::$deleted_ticket_meta_key, 0 ] );
52
+ $full_name = Arr::get( $post_meta, [ Attendee::$full_name_meta_key, 0 ] );
 
 
53
  $email = Arr::get( $post_meta, [ Attendee::$email_meta_key, 0 ] );
54
  $price_paid = Arr::get( $post_meta, [ Attendee::$price_paid_meta_key, 0 ] );
55
  $currency = Arr::get( $post_meta, [ Attendee::$currency_meta_key, 0 ] );
59
  $ticket_unique_id = Arr::get( $post_meta, [ '_unique_id', 0 ] );
60
  $ticket_unique_id = empty( $ticket_unique_id ) ? $post_id : $ticket_unique_id;
61
 
62
+ $ticket_title = ( ! $is_product_deleted ? $ticket->post_title : $deleted_ticket_title . ' ' . __( '(deleted)', 'event-tickets' ) );
63
 
64
  $is_purchaser = $email === $order->purchaser_email;
65
 
66
  $properties = [
67
+ 'order_id' => $this->post->post_parent,
68
+ 'order_status' => $status,
69
+ 'optout' => $opt_out,
70
+ 'ticket' => $ticket_title,
71
+ 'attendee_id' => $post_id,
72
+ 'security' => $security,
73
+ 'product_id' => $ticket_id,
74
+ 'check_in' => $checked_in,
75
+ 'ticket_sent' => $ticket_sent,
76
+ 'price_paid' => $price_paid,
77
+ 'currency' => $currency,
78
+
79
+ // Provider.
80
+ 'provider' => $order->provider,
81
+ 'provider_slug' => $order->provider_slug,
82
+
83
+ // Purchaser.
84
+ 'purchaser_id' => $order->purchaser['user_id'],
85
+ 'purchaser_name' => $order->purchaser['full_name'],
86
+ 'purchaser_email' => $order->purchaser['email'],
87
 
88
  // Fields for Email Tickets.
89
+ 'event_id' => $event_id,
90
+ 'ticket_name' => $ticket_title,
91
+ 'user_id' => $user_id,
92
+ 'holder_name' => $full_name,
93
+ 'holder_email' => $email,
94
+ 'ticket_id' => $ticket_id,
95
+ 'qr_ticket_id' => $post_id,
96
+ 'security_code' => $security,
 
 
97
 
98
  // Handle initial Attendee flags.
99
+ 'is_subscribed' => $is_subscribed,
100
+ 'is_purchaser' => $is_purchaser,
101
  ];
102
  } catch ( \Exception $e ) {
103
  return [];
src/Tickets/Commerce/Models/Order_Model.php CHANGED
@@ -12,10 +12,8 @@ namespace TEC\Tickets\Commerce\Models;
12
  use TEC\Tickets\Commerce;
13
  use TEC\Tickets\Commerce\Module;
14
  use TEC\Tickets\Commerce\Order;
 
15
  use Tribe\Models\Post_Types\Base;
16
- use Tribe\Utils\Lazy_Collection;
17
- use Tribe\Utils\Lazy_String;
18
- use Tribe\Utils\Post_Thumbnail;
19
  use Tribe__Date_Utils as Dates;
20
  use Tribe__Utils__Array as Arr;
21
 
@@ -39,43 +37,53 @@ class Order_Model extends Base {
39
 
40
  $post_meta = get_post_meta( $post_id );
41
 
42
- $cart_items = maybe_unserialize( Arr::get( $post_meta, [ Order::$cart_items_meta_key, 0 ] ) );
43
  $total_value = Arr::get( $post_meta, [ Order::$total_value_meta_key, 0 ] );
 
44
  $currency = Arr::get( $post_meta, [ Order::$currency_meta_key, 0 ], 'USD' );
45
  $gateway_slug = Arr::get( $post_meta, [ Order::$gateway_meta_key, 0 ] );
46
  $gateway_order_id = Arr::get( $post_meta, [ Order::$gateway_order_id_meta_key, 0 ] );
47
  $gateway_payload = $this->get_gateway_payloads( $post_meta );
48
  $status_log = $this->get_status_log( $post_meta );
 
49
  $flag_action_markers = $this->get_flag_action_markers( $post_meta );
50
 
 
51
  $purchaser_full_name = Arr::get( $post_meta, [ Order::$purchaser_full_name_meta_key, 0 ] );
52
  $purchaser_first_name = Arr::get( $post_meta, [ Order::$purchaser_first_name_meta_key, 0 ] );
53
  $purchaser_last_name = Arr::get( $post_meta, [ Order::$purchaser_last_name_meta_key, 0 ] );
54
  $purchaser_email = Arr::get( $post_meta, [ Order::$purchaser_email_meta_key, 0 ] );
55
 
56
- $events_in_order = Arr::get( $post_meta, [ Order::$events_in_order_meta_key ] );
57
- $tickets_in_order = Arr::get( $post_meta, [ Order::$tickets_in_order_meta_key ] );
58
 
59
  $properties = [
 
60
  'provider' => Module::class,
61
  'provider_slug' => Commerce::ABBR,
62
  'status_log' => $status_log,
 
63
  'gateway' => $gateway_slug,
64
  'gateway_order_id' => $gateway_order_id,
65
  'gateway_payload' => $gateway_payload,
66
  'total_value' => $total_value,
67
  'currency' => $currency,
68
  'purchaser' => [
69
- 'user_id' => $this->post->post_author,
70
  'first_name' => $purchaser_first_name,
71
  'last_name' => $purchaser_last_name,
72
  'full_name' => $purchaser_full_name,
73
  'email' => $purchaser_email,
74
  ],
75
- 'cart_items' => $cart_items,
 
 
 
 
76
  'events_in_order' => $events_in_order,
77
  'tickets_in_order' => $tickets_in_order,
78
  'flag_action_markers' => $flag_action_markers,
 
79
  ];
80
  } catch ( \Exception $e ) {
81
  return [];
12
  use TEC\Tickets\Commerce;
13
  use TEC\Tickets\Commerce\Module;
14
  use TEC\Tickets\Commerce\Order;
15
+ use TEC\Tickets\Commerce\Status\Status_Handler;
16
  use Tribe\Models\Post_Types\Base;
 
 
 
17
  use Tribe__Date_Utils as Dates;
18
  use Tribe__Utils__Array as Arr;
19
 
37
 
38
  $post_meta = get_post_meta( $post_id );
39
 
40
+ $items = maybe_unserialize( Arr::get( $post_meta, [ Order::$items_meta_key, 0 ] ) );
41
  $total_value = Arr::get( $post_meta, [ Order::$total_value_meta_key, 0 ] );
42
+ $hash = Arr::get( $post_meta, [ Order::$hash_meta_key, 0 ] );
43
  $currency = Arr::get( $post_meta, [ Order::$currency_meta_key, 0 ], 'USD' );
44
  $gateway_slug = Arr::get( $post_meta, [ Order::$gateway_meta_key, 0 ] );
45
  $gateway_order_id = Arr::get( $post_meta, [ Order::$gateway_order_id_meta_key, 0 ] );
46
  $gateway_payload = $this->get_gateway_payloads( $post_meta );
47
  $status_log = $this->get_status_log( $post_meta );
48
+ $status = tribe( Status_Handler::class )->get_by_wp_slug( $this->post->post_status );
49
  $flag_action_markers = $this->get_flag_action_markers( $post_meta );
50
 
51
+ $purchaser_user_id = Arr::get( $post_meta, [ Order::$purchaser_user_id_meta_key, 0 ] );
52
  $purchaser_full_name = Arr::get( $post_meta, [ Order::$purchaser_full_name_meta_key, 0 ] );
53
  $purchaser_first_name = Arr::get( $post_meta, [ Order::$purchaser_first_name_meta_key, 0 ] );
54
  $purchaser_last_name = Arr::get( $post_meta, [ Order::$purchaser_last_name_meta_key, 0 ] );
55
  $purchaser_email = Arr::get( $post_meta, [ Order::$purchaser_email_meta_key, 0 ] );
56
 
57
+ $events_in_order = (array) Arr::get( $post_meta, [ Order::$events_in_order_meta_key ] );
58
+ $tickets_in_order = (array) Arr::get( $post_meta, [ Order::$tickets_in_order_meta_key ] );
59
 
60
  $properties = [
61
+ 'order_id' => $post_id,
62
  'provider' => Module::class,
63
  'provider_slug' => Commerce::ABBR,
64
  'status_log' => $status_log,
65
+ 'status_name' => $status->get_name(),
66
  'gateway' => $gateway_slug,
67
  'gateway_order_id' => $gateway_order_id,
68
  'gateway_payload' => $gateway_payload,
69
  'total_value' => $total_value,
70
  'currency' => $currency,
71
  'purchaser' => [
72
+ 'user_id' => (int) $purchaser_user_id,
73
  'first_name' => $purchaser_first_name,
74
  'last_name' => $purchaser_last_name,
75
  'full_name' => $purchaser_full_name,
76
  'email' => $purchaser_email,
77
  ],
78
+ 'purchaser_name' => $purchaser_full_name,
79
+ 'purchaser_email' => $purchaser_email,
80
+ 'purchase_time' => get_post_time( \Tribe__Date_Utils::DBDATETIMEFORMAT, false, $this->post ),
81
+ 'items' => $items,
82
+ 'hash' => $hash,
83
  'events_in_order' => $events_in_order,
84
  'tickets_in_order' => $tickets_in_order,
85
  'flag_action_markers' => $flag_action_markers,
86
+ 'formatted_total' => tribe_format_currency( $total_value ),
87
  ];
88
  } catch ( \Exception $e ) {
89
  return [];
src/Tickets/Commerce/Module.php CHANGED
@@ -4,6 +4,7 @@ namespace TEC\Tickets\Commerce;
4
 
5
  use TEC\Tickets\Commerce;
6
  use TEC\Tickets\Commerce\Status\Completed;
 
7
 
8
  /**
9
  * Class Tickets Provider class for Tickets Commerce
@@ -214,12 +215,12 @@ class Module extends \Tribe__Tickets__Tickets {
214
  * This method is required for the module to properly load.
215
  *
216
  * @since 5.1.9
217
-
218
  * @return static
219
  */
220
  public static function get_instance() {
221
  return tribe( static::class );
222
  }
 
223
  /**
224
  * Registers all actions/filters
225
  *
@@ -353,6 +354,38 @@ class Module extends \Tribe__Tickets__Tickets {
353
 
354
  }
355
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  /**
357
  * Returns the value of a key defined by the class.
358
  *
@@ -496,16 +529,28 @@ class Module extends \Tribe__Tickets__Tickets {
496
  return tribe( Cart::class )->get_url();
497
  }
498
 
 
 
 
 
 
 
 
 
 
 
 
499
  /**
500
  * Generate and store all the attendees information for a new order.
501
  *
502
- * @since 5.1.9
 
503
  *
504
  * @param string $payment_status The tickets payment status, defaults to completed.
505
  * @param bool $redirect Whether the client should be redirected or not.
506
  */
507
  public function generate_tickets( $payment_status = 'completed', $redirect = true ) {
508
- tribe( Order::class )->generate_order( $payment_status, $redirect );
509
  }
510
 
511
  /**
@@ -527,9 +572,9 @@ class Module extends \Tribe__Tickets__Tickets {
527
  *
528
  * @since 5.1.9
529
  *
530
- * @param int $post_id Post ID.
531
  * @param \Tribe__Tickets__Ticket_Object $ticket Ticket object.
532
- * @param array $raw_data Ticket data.
533
  *
534
  * @return int|false The updated/created ticket post ID or false if no ticket ID.
535
  */
@@ -593,7 +638,7 @@ class Module extends \Tribe__Tickets__Tickets {
593
  * @return string
594
  */
595
  public function get_event_reports_link( $event_id, $url_only = false ) {
596
- return tribe( Commerce\Reports\Event::class )->get_link( $event_id, $url_only );
597
  }
598
 
599
  /**
@@ -607,6 +652,138 @@ class Module extends \Tribe__Tickets__Tickets {
607
  * @return string
608
  */
609
  public function get_ticket_reports_link( $event_id, $ticket_id ) {
610
- return tribe( Commerce\Reports\Event::class )->get_link( $event_id, $ticket_id );
611
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
612
  }
4
 
5
  use TEC\Tickets\Commerce;
6
  use TEC\Tickets\Commerce\Status\Completed;
7
+ use Tribe__Utils__Array as Arr;
8
 
9
  /**
10
  * Class Tickets Provider class for Tickets Commerce
215
  * This method is required for the module to properly load.
216
  *
217
  * @since 5.1.9
 
218
  * @return static
219
  */
220
  public static function get_instance() {
221
  return tribe( static::class );
222
  }
223
+
224
  /**
225
  * Registers all actions/filters
226
  *
354
 
355
  }
356
 
357
+ /**
358
+ * Get attendees for a ticket by order ID, optionally by ticket ID.
359
+ *
360
+ * This overrides the parent method because Tickets Commerce stores the order ID in the post_parent.
361
+ *
362
+ * @since 5.2.0
363
+ *
364
+ * @param int|string $order_id Order ID.
365
+ * @param null|int $ticket_id (optional) Ticket ID.
366
+ *
367
+ * @return array List of attendees.
368
+ */
369
+ public function get_attendees_by_order_id( $order_id ) {
370
+ $ticket_id = null;
371
+
372
+ // Support an optional second argument while not causing warnings from other ticket provider classes.
373
+ if ( 1 < func_num_args() ) {
374
+ $ticket_id = func_get_arg( 1 );
375
+ }
376
+
377
+ /** @var Tribe__Tickets__Attendee_Repository $repository */
378
+ $repository = tribe_attendees( $this->orm_provider );
379
+
380
+ $repository->by( 'parent', $order_id );
381
+
382
+ if ( $ticket_id ) {
383
+ $repository->by( 'ticket', $ticket_id );
384
+ }
385
+
386
+ return $this->get_attendees_from_module( $repository->all() );
387
+ }
388
+
389
  /**
390
  * Returns the value of a key defined by the class.
391
  *
529
  return tribe( Cart::class )->get_url();
530
  }
531
 
532
+ /**
533
+ * Maps to the Checkout Class method to get the checkout.
534
+ *
535
+ * @since 5.2.0
536
+ *
537
+ * @return string
538
+ */
539
+ public function get_checkout_url() {
540
+ return tribe( Checkout::class )->get_url();
541
+ }
542
+
543
  /**
544
  * Generate and store all the attendees information for a new order.
545
  *
546
+ * @since 5.1.9
547
+ * @deprecated 5.2.0
548
  *
549
  * @param string $payment_status The tickets payment status, defaults to completed.
550
  * @param bool $redirect Whether the client should be redirected or not.
551
  */
552
  public function generate_tickets( $payment_status = 'completed', $redirect = true ) {
553
+ _deprecated_function( __METHOD__, '5.2.0' );
554
  }
555
 
556
  /**
572
  *
573
  * @since 5.1.9
574
  *
575
+ * @param int $post_id Post ID.
576
  * @param \Tribe__Tickets__Ticket_Object $ticket Ticket object.
577
+ * @param array $raw_data Ticket data.
578
  *
579
  * @return int|false The updated/created ticket post ID or false if no ticket ID.
580
  */
638
  * @return string
639
  */
640
  public function get_event_reports_link( $event_id, $url_only = false ) {
641
+ return tribe( Commerce\Reports\Orders::class )->get_event_link( $event_id, $url_only );
642
  }
643
 
644
  /**
652
  * @return string
653
  */
654
  public function get_ticket_reports_link( $event_id, $ticket_id ) {
655
+ return tribe( Commerce\Reports\Orders::class )->get_ticket_link( $event_id, $ticket_id );
656
  }
657
+
658
+ /**
659
+ * Create an attendee for the Commerce provider from a ticket.
660
+ *
661
+ * @since 5.1.0
662
+ *
663
+ * @param \Tribe__Tickets__Ticket_Object|int $ticket Ticket object or ID to create the attendee for.
664
+ * @param array $attendee_data Attendee data to create from.
665
+ *
666
+ * @return \WP_Post|\WP_Error|false The new post object or false if we can't resolve to a Ticket object. WP_Error if modifying status fails
667
+ */
668
+ public function create_attendee( $ticket, $attendee_data ) {
669
+ // Get the ticket object from the ID.
670
+ if ( is_numeric( $ticket ) ) {
671
+ $ticket = $this->get_ticket( 0, (int) $ticket );
672
+ }
673
+
674
+ // If the ticket is not valid, stop creating the attendee.
675
+ if ( ! $ticket instanceof \Tribe__Tickets__Ticket_Object ) {
676
+ return false;
677
+ }
678
+
679
+ $extra = [];
680
+ $extra['attendees'] = [
681
+ 1 => [
682
+ 'meta' => Arr::get( $attendee_data, 'attendee_meta', [] )
683
+ ]
684
+ ];
685
+ $extra['optout'] = ! Arr::get( $attendee_data, 'send_ticket_email', true );
686
+ $extra['iac'] = false;
687
+
688
+ // The Manual Order takes the same format as the cart items.
689
+ $items = [
690
+ $ticket->ID => [
691
+ 'ticket_id' => $ticket->ID,
692
+ 'quantity' => 1,
693
+ 'extra' => $extra,
694
+ ]
695
+ ];
696
+
697
+ $purchaser = [
698
+ 'full_name' => $attendee_data['full_name'],
699
+ 'email' => $attendee_data['email'],
700
+
701
+ // By default user ID is zero here.
702
+ 'user_id' => 0,
703
+ ];
704
+
705
+ $order = tribe( Gateways\Manual\Order::class )->create( $items, $purchaser );
706
+
707
+ /**
708
+ * For now we need to make sure we move to pending before completed.
709
+ *
710
+ * @todo @backend when an order is moved into completed they need to update to pending first.
711
+ * likely we should have this be developed by implementing a dependent status.
712
+ */
713
+ $updated = tribe( Order::class )->modify_status( $order->ID, 'pending' );
714
+ if ( is_wp_error( $updated ) ) {
715
+ return $updated;
716
+ }
717
+
718
+ $updated = tribe( Order::class )->modify_status( $order->ID, 'completed' );
719
+ if ( is_wp_error( $updated ) ) {
720
+ return $updated;
721
+ }
722
+
723
+ $attendee = tec_tc_attendees()->by( 'order_id', $order->ID )->first();
724
+
725
+ return $attendee;
726
+ }
727
+
728
+ /**
729
+ * Update an attendee for the Commerce provider.
730
+ *
731
+ * @since 5.2.0
732
+ *
733
+ * @todo TribeLegacyCommerce We need to move this into the Attendee class.
734
+ *
735
+ * @param array|int $attendee The attendee data or ID for the attendee to update.
736
+ * @param array $attendee_data The attendee data to update to.
737
+ *
738
+ * @return \WP_Post|false The updated post object or false if unsuccessful.
739
+ */
740
+ public function update_attendee( $attendee, $attendee_data ) {
741
+ if ( is_numeric( $attendee ) ) {
742
+ $attendee_id = (int) $attendee;
743
+ } elseif ( is_array( $attendee ) && isset( $attendee['attendee_id'] ) ) {
744
+ $attendee_id = (int) $attendee['attendee_id'];
745
+ } else {
746
+ return false;
747
+ }
748
+
749
+ $attendee = tec_tc_attendees( $this->orm_provider )
750
+ ->where( 'ID', $attendee_id );
751
+
752
+ try {
753
+ if ( ! empty( $attendee_data['attendee_meta'] ) ) {
754
+ $attendee->set( 'fields', $attendee_data['attendee_meta'] );
755
+ }
756
+
757
+ if ( ! empty( $attendee_data['full_name'] ) ) {
758
+ $attendee->set( 'full_name', $attendee_data['full_name'] );
759
+ }
760
+
761
+ if ( ! empty( $attendee_data['email'] ) && filter_var( $attendee_data['email'], FILTER_VALIDATE_EMAIL ) ) {
762
+ $attendee->set( 'email', $attendee_data['email'] );
763
+ }
764
+
765
+ $attendee->save();
766
+
767
+ // Send attendee email.
768
+ $send_ticket_email = (bool) Arr::get( $attendee_data, 'send_ticket_email', false );
769
+ $send_ticket_email_args = (array) Arr::get( $attendee_data, 'send_ticket_email_args', [] );
770
+
771
+ // Check if we need to send the ticket email.
772
+ if ( $send_ticket_email ) {
773
+ $attendee_tickets = [
774
+ $attendee_id,
775
+ ];
776
+
777
+ // Maybe send the attendee email.
778
+ $this->send_tickets_email_for_attendees( $attendee_tickets, $send_ticket_email_args );
779
+ }
780
+ } catch ( \Tribe__Repository__Usage_Error $e ) {
781
+ do_action( 'tribe_log', 'error', __CLASS__, [ 'message' => $e->getMessage() ] );
782
+
783
+ return false;
784
+ }
785
+
786
+ return $attendee;
787
+ }
788
+
789
  }
src/Tickets/Commerce/Notice_Handler.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce;
4
+
5
+ /**
6
+ * Notice Handler for managing Admin view notices.
7
+ *
8
+ * @since 5.2.0
9
+ *
10
+ * @package TEC\Tickets\Commerce
11
+ */
12
+ class Notice_Handler {
13
+ /**
14
+ * Resets the cache with the key from `\Tribe_Admin_Notices->get_transients()` so that
15
+ * we can display a given notice on the same page that we are triggering it.
16
+ *
17
+ * This is here because of a possible bug in common.
18
+ *
19
+ * @since 5.2.0
20
+ */
21
+ private function clear_request_cache() {
22
+ // Clear the existing notices cache.
23
+ $cache = tribe( 'cache' );
24
+ unset( $cache['transient_admin_notices'] );
25
+ }
26
+
27
+ /**
28
+ * Fetches the expiration in seconds for the transient notice.
29
+ *
30
+ * @see tribe_transient_notice()
31
+ *
32
+ * @since 5.2.0
33
+ *
34
+ * @param string $slug Slug for the notice.
35
+ *
36
+ * @return int
37
+ */
38
+ protected function get_expiration( $slug ) {
39
+ /**
40
+ * Filters the available notice messages.
41
+ *
42
+ * @since 5.2.0
43
+ *
44
+ * @param int $duration Duration in seconds to expire.
45
+ * @param string $slug Slug for the notice to display.
46
+ */
47
+ return (int) apply_filters( 'tec_tickets_commerce_notice_expiration', 10, $slug );
48
+ }
49
+
50
+ /**
51
+ * Fetches the array of all messages available to display.
52
+ *
53
+ * @since 5.2.0
54
+ *
55
+ * @return array[]
56
+ */
57
+ public function get_messages() {
58
+ $messages = [];
59
+
60
+ /**
61
+ * Filters the available notice messages.
62
+ *
63
+ * @since 5.2.0
64
+ *
65
+ * @param array $messages Array of notice messages.
66
+ */
67
+ return (array) apply_filters( 'tec_tickets_commerce_notice_messages', $messages );
68
+ }
69
+
70
+ /**
71
+ * Determines if a message exists with a given slug.
72
+ *
73
+ * @since 5.2.0
74
+ *
75
+ * @param string $slug
76
+ *
77
+ * @return bool
78
+ */
79
+ public function message_slug_exists( $slug ) {
80
+ $messages = $this->get_messages();
81
+ $messages = wp_list_filter( $messages, [ 'slug' => $slug ] );
82
+ $messages = array_values( $messages );
83
+
84
+ return ! empty( $messages[0] );
85
+ }
86
+
87
+ /**
88
+ * Gets a given message data by it's slug.
89
+ *
90
+ * @since 5.2.0
91
+ *
92
+ * @param string $slug Slug to retrieve the message data.
93
+ *
94
+ * @return array
95
+ */
96
+ public function get_message_data( $slug, $overrides = [] ) {
97
+
98
+ $default_args = [
99
+ 'slug' => $slug,
100
+ 'expire' => true,
101
+ 'wrap' => 'p',
102
+ 'type' => 'error',
103
+ 'content' => '',
104
+ 'priority' => 10,
105
+ ];
106
+
107
+ // If not found in message array, return with defaults.
108
+ if ( ! $this->message_slug_exists( $slug ) ) {
109
+ return array_merge( $default_args, $overrides );
110
+ }
111
+
112
+ $message = array_values( wp_list_filter( $this->get_messages(), [ 'slug' => $slug ] ) )[0];
113
+
114
+ return array_merge( $default_args, $message, $overrides );
115
+ }
116
+
117
+ /**
118
+ * Merges the content of a given set of Notice slugs.
119
+ *
120
+ * @since 5.2.0
121
+ *
122
+ * @param array $slugs Array of slugs that will be merged.
123
+ *
124
+ * @return string $html List with message content from each slug.
125
+ */
126
+ public function merge_contents( array $slugs ) {
127
+ $messages = array_map( [ $this, 'get_message_data' ], $slugs );
128
+
129
+ $html[] = '<ul>';
130
+ foreach ( $messages as $message ) {
131
+ $list_class = sanitize_html_class( 'tec-tickets-commerce-notice-item-' . $message['slug'] );
132
+ $html[] = "<li class='{$list_class}'>";
133
+ $html[] = $message['content'];
134
+ $html[] = '</li>';
135
+ }
136
+ $html[] = '</ul>';
137
+
138
+ return implode( "\n", $html );
139
+ }
140
+
141
+ /**
142
+ * Add an admin notice that should only show once.
143
+ *
144
+ * @since 5.2.0
145
+ *
146
+ * @param string $slug Slug to store the notice.
147
+ * @param array $args Arguments to set up a notice.
148
+ *
149
+ * @see Tribe__Admin__Notices::register for available $args options.
150
+ */
151
+ public function trigger_admin( $slug, $args = [] ) {
152
+
153
+ $message = $this->get_message_data( $slug, $args );
154
+
155
+ tribe_transient_notice( $slug, $message['content'], $message, $this->get_expiration( $slug ) );
156
+
157
+ // This is here because of a possible bug in common.
158
+ $this->clear_request_cache();
159
+ }
160
+ }
src/Tickets/Commerce/Order.php CHANGED
@@ -2,11 +2,11 @@
2
 
3
  namespace TEC\Tickets\Commerce;
4
 
5
- use TEC\Tickets\Commerce;
 
6
  use TEC\Tickets\Commerce\Utils\Price;
7
  use Tribe__Date_Utils as Dates;
8
 
9
-
10
  /**
11
  * Class Order
12
  *
@@ -15,6 +15,7 @@ use Tribe__Date_Utils as Dates;
15
  * @package TEC\Tickets\Commerce
16
  */
17
  class Order {
 
18
  /**
19
  * Tickets Commerce Order Post Type slug.
20
  *
@@ -53,13 +54,14 @@ class Order {
53
  public static $gateway_payload_meta_key = '_tec_tc_order_gateway_payload';
54
 
55
  /**
56
- * Which meta holds the cart items used to setup this order.
57
  *
58
  * @since 5.1.9
 
59
  *
60
  * @var string
61
  */
62
- public static $cart_items_meta_key = '_tec_tc_order_cart_items';
63
 
64
  /**
65
  * Which meta holds the tickets in a given order, they are added as individual meta items, allowing them to be
@@ -135,6 +137,15 @@ class Order {
135
  */
136
  public static $purchaser_email_meta_key = '_tec_tc_order_purchaser_email';
137
 
 
 
 
 
 
 
 
 
 
138
  /**
139
  * Prefix for the log of when a given status was applied.
140
  *
@@ -153,6 +164,24 @@ class Order {
153
  */
154
  public static $flag_action_status_marker_meta_key_prefix = '_tec_tc_order_fa_marker';
155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  /**
157
  * Register this Class post type into WP.
158
  *
@@ -175,10 +204,10 @@ class Order {
175
  * Filter the arguments that craft the order post type.
176
  *
177
  * @see register_post_type
178
- *
179
  * @since 5.1.9
180
  *
181
  * @param array $post_type_args Post type arguments, passed to register_post_type()
 
182
  */
183
  $post_type_args = apply_filters( 'tec_tickets_commerce_order_post_type_args', $post_type_args );
184
 
@@ -194,7 +223,7 @@ class Order {
194
  *
195
  * @return string
196
  */
197
- public static function get_status_log_meta_key( Commerce\Status\Status_Interface $status ) {
198
  return static::$status_log_meta_key_prefix . '_' . $status->get_slug();
199
  }
200
 
@@ -207,7 +236,7 @@ class Order {
207
  *
208
  * @return string
209
  */
210
- public static function get_gateway_payload_meta_key( Commerce\Status\Status_Interface $status ) {
211
  return static::$gateway_payload_meta_key . '_' . $status->get_slug();
212
  }
213
 
@@ -221,7 +250,7 @@ class Order {
221
  *
222
  * @return string
223
  */
224
- public static function get_flag_action_marker_meta_key( $flag, Commerce\Status\Status_Interface $status ) {
225
  $prefix = static::$flag_action_status_marker_meta_key_prefix;
226
 
227
  return "{$prefix}:{$status->get_slug()}:{$flag}";
@@ -241,7 +270,7 @@ class Order {
241
  * @return bool|\WP_Error
242
  */
243
  public function modify_status( $order_id, $status_slug, array $extra_args = [] ) {
244
- $status = tribe( Commerce\Status\Status_Handler::class )->get_by_slug( $status_slug );
245
 
246
  if ( ! $status ) {
247
  return false;
@@ -254,10 +283,12 @@ class Order {
254
 
255
  $args = array_merge( $extra_args, [ 'status' => $status->get_wp_slug() ] );
256
 
257
- $updated = tec_tc_orders()->by_args( [
258
- 'status' => 'any',
259
- 'id' => $order_id,
260
- ] )->set_args( $args )->save();
 
 
261
 
262
  // After modifying the status we add a meta to flag when it was modified.
263
  if ( $updated ) {
@@ -277,42 +308,52 @@ class Order {
277
  *
278
  * @return false|\WP_Post
279
  */
280
- public function create_from_cart( Commerce\Gateways\Interface_Gateway $gateway, $purchaser = null ) {
281
  $cart = tribe( Cart::class );
282
 
283
  $items = $cart->get_items_in_cart();
284
- $items = array_map( static function ( $item ) {
285
- $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
286
- if ( null === $ticket ) {
287
- return null;
288
- }
 
289
 
290
- $item['sub_total'] = Price::sub_total( $ticket->price, $item['quantity'] );
291
- $item['price'] = $ticket->price;
292
 
293
- return $item;
294
- }, $items );
 
 
295
  $items = array_filter( $items );
296
  $sub_totals = array_filter( wp_list_pluck( $items, 'sub_total' ) );
297
  $total = Price::total( $sub_totals );
298
 
299
  $order_args = [
300
  'title' => $this->generate_order_title( $items, $cart->get_cart_hash() ),
301
- 'total_value' => $total,
302
- 'cart_items' => $items,
303
  'gateway' => $gateway::get_key(),
 
304
  ];
305
 
306
  // When purchaser data-set is not passed we pull from the current user.
307
  if ( empty( $purchaser ) && is_user_logged_in() && $user = wp_get_current_user() ) {
308
- $order_args['author'] = $user->ID;
309
  $order_args['purchaser_full_name'] = $user->first_name . ' ' . $user->last_name;
310
  $order_args['purchaser_first_name'] = $user->first_name;
311
  $order_args['purchaser_last_name'] = $user->last_name;
312
  $order_args['purchaser_email'] = $user->user_email;
 
 
 
 
 
 
313
  }
314
 
315
- $order = tec_tc_orders()->set_args( $order_args )->create();
316
 
317
  // We were unable to create the order bail from here.
318
  if ( ! $order ) {
@@ -322,19 +363,57 @@ class Order {
322
  return $order;
323
  }
324
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  /**
326
  * Generates a title based on Cart Hash, items in the cart.
327
  *
328
  * @since 5.1.9
329
  *
330
- * @param array $items List of events form
331
  *
332
  * @return string
333
  */
334
  public function generate_order_title( $items, $hash = null ) {
335
  $title = [ 'TEC-TC' ];
336
  if ( $hash ) {
337
- $title[] = $hash;
338
  }
339
  $title[] = 'T';
340
 
@@ -344,20 +423,44 @@ class Order {
344
  return implode( '-', $title );
345
  }
346
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
  /**
348
  * Redirects to the source post after a recoverable (logic) error.
349
  *
350
  * @todo Determine if redirecting should be something relegated to some other method, and here we just actually
351
- * generate the order/Attendees.
 
 
352
  *
353
  * @see \Tribe__Tickets__Commerce__PayPal__Errors for error codes translations.
354
  * @since 5.1.9
355
  *
356
- * @param bool $redirect Whether to really redirect or not.
357
- * @param int $post_id A post ID
358
- *
359
- * @param int $error_code The current error code
360
  *
 
 
361
  */
362
  protected function redirect_after_error( $error_code, $redirect, $post_id ) {
363
  $url = add_query_arg( 'tpp_error', $error_code, get_permalink( $post_id ) );
@@ -368,323 +471,59 @@ class Order {
368
  }
369
 
370
  /**
371
- * Generate and store all the attendees information for a new order.
372
  *
373
- * @since 5.1.9
374
  *
375
- * @param string $payment_status The tickets payment status, defaults to completed.
376
- * @param bool $redirect Whether the client should be redirected or not.
377
  *
 
378
  */
379
- public function generate_order( $payment_status = 'completed', $redirect = true ) {
380
- /*
381
- * This method might run during a POST (IPN) PayPal request hence the
382
- * purchasing user ID, if any, will be stored in a custom PayPal var.
383
- * Let's fallback on the current user ID for GET requests (PDT); it will be always `0`
384
- * during a PayPal POST (IPN) request.
385
- */
386
- $attendee_user_id = ! isset( $custom['user_id'] ) ? get_current_user_id() : absint( $custom['user_id'] );
387
-
388
- $attendee_full_name = empty( $transaction_data['first_name'] ) && empty( $transaction_data['last_name'] )
389
- ? ''
390
- : sanitize_text_field( "{$transaction_data['first_name']} {$transaction_data['last_name']}" );
391
-
392
- $attendee_email = empty( $transaction_data['payer_email'] ) ? null : sanitize_email( $transaction_data['payer_email'] );
393
- $attendee_email = is_email( $attendee_email ) ? $attendee_email : null;
394
 
395
- if ( ! empty( $attendee_user_id ) ) {
396
- $attendee = get_user_by( 'id', $attendee_user_id );
 
 
 
397
 
398
- // Check if the user was found.
399
- if ( $attendee ) {
400
- // Check if the user has an email address.
401
- if ( $attendee->user_email ) {
402
- $attendee_email = $attendee->user_email;
403
- }
404
-
405
- $user_full_name = trim( "{$attendee->first_name} {$attendee->last_name}" );
406
-
407
- // Check if the user has first/last name.
408
- if ( ! empty( $user_full_name ) ) {
409
- $attendee_full_name = $user_full_name;
410
- }
411
- }
412
  }
413
 
414
- /**
415
- * This is an array of tickets IDs for which the user decided to opt-out.
416
- *
417
- * @see \Tribe__Tickets_Plus__Commerce__PayPal__Attendees::register_optout_choice()
418
- */
419
- $attendee_optouts = \Tribe__Utils__Array::get( $custom, 'oo', [] );
420
-
421
- if ( ! $attendee_email || ! $attendee_full_name ) {
422
- $this->redirect_after_error( 101, $redirect, $post_id );
423
-
424
- return;
425
- }
426
-
427
- // Iterate over each product
428
- foreach ( (array) $transaction_data['items'] as $item ) {
429
- $order_attendee_id = 0;
430
-
431
- if ( empty( $item['ticket'] ) ) {
432
- continue;
433
- }
434
-
435
- /** @var \Tribe__Tickets__Ticket_Object $ticket_type */
436
- $ticket_type = $item['ticket'];
437
- $product_id = $ticket_type->ID;
438
-
439
- // Get the event this tickets is for
440
- $post = $ticket_type->get_event();
441
-
442
- if ( empty( $post ) ) {
443
- continue;
444
- }
445
-
446
- $post_id = $post->ID;
447
-
448
- // if there were no PayPal tickets for the product added to the cart, continue
449
- if ( empty( $item['quantity'] ) ) {
450
- continue;
451
- }
452
-
453
- // get the PayPal status `decrease_stock_by` value
454
- $status_stock_size = 1;
455
-
456
- $ticket_qty = (int) $item['quantity'];
457
-
458
- // to avoid tickets from not being created on a status stock size of 0
459
- // let's take the status stock size into account and create a number of tickets
460
- // at least equal to the number of tickets the user requested
461
- $ticket_qty = $status_stock_size < 1 ? $ticket_qty : $status_stock_size * $ticket_qty;
462
-
463
- $qty = max( $ticket_qty, 0 );
464
-
465
- // Throw an error if Qty is bigger then Remaining
466
- if ( $payment_status === tribe( Commerce\Status\Completed::class )->get_wp_slug() && $ticket_type->managing_stock() ) {
467
- add_action( 'tec_tickets_commerce_pending_stock_ignore', '__return_true' );
468
- $inventory = (int) $ticket_type->inventory();
469
- remove_action( 'tec_tickets_commerce_pending_stock_ignore', '__return_true' );
470
-
471
- $inventory_is_not_unlimited = - 1 !== $inventory;
472
-
473
- if ( $inventory_is_not_unlimited && $qty > $inventory ) {
474
- if ( ! $order->was_pending() ) {
475
- $this->redirect_after_error( 102, $redirect, $post_id );
476
-
477
- return;
478
- }
479
-
480
- /** @var \Tribe__Tickets__Commerce__PayPal__Oversell__Policies $oversell_policies */
481
- $oversell_policies = tribe( 'tickets.commerce.paypal.oversell.policies' );
482
- $oversell_policy = $oversell_policies->for_post_ticket_order( $post_id, $ticket_type->ID, $order_id );
483
-
484
- $qty = $oversell_policy->modify_quantity( $qty, $inventory );
485
-
486
- if ( ! $oversell_policy->allows_overselling() ) {
487
- $oversold_attendees = tribe( Module::class )->get_attendees_by_order_id( $order_id );
488
- $oversell_policy->handle_oversold_attendees( $oversold_attendees );
489
- $this->redirect_after_error( 102, $redirect, $post_id );
490
-
491
- return;
492
- }
493
- }
494
- }
495
-
496
- if ( $qty === 0 ) {
497
- $this->redirect_after_error( 103, $redirect, $post_id );
498
-
499
- return;
500
- }
501
-
502
- $has_tickets = true;
503
-
504
- /**
505
- * PayPal specific action fired just before a PayPal-driven attendee ticket for an event is generated
506
- *
507
- * @since 4.7
508
- *
509
- * @param int $post_id ID of event
510
- * @param string $ticket_type Ticket Type object for the product
511
- * @param array $data Parsed PayPal transaction data
512
- */
513
- do_action( 'tribe_tickets_tpp_before_attendee_ticket_creation', $post_id, $ticket_type, $transaction_data );
514
-
515
- $existing_attendees = tribe( Module::class )->get_attendees_by_order_id( $order_id );
516
-
517
- $has_generated_new_tickets = false;
518
-
519
- /** @var \Tribe__Tickets__Commerce__Currency $currency */
520
- $currency = tribe( 'tickets.commerce.currency' );
521
- $currency_symbol = $currency->get_currency_symbol( $product_id, true );
522
-
523
- // Iterate over all the amount of tickets purchased (for this product)
524
- for ( $i = 0; $i < $qty; $i ++ ) {
525
- $attendee_id = null;
526
- $updating_attendee = false;
527
-
528
- /**
529
- * Allow filtering the individual attendee name used when creating a new attendee.
530
- *
531
- * @since 5.0.3
532
- *
533
- * @param string $individual_attendee_name The attendee full name.
534
- * @param int|null $attendee_number The attendee number index value from the order, starting with zero.
535
- * @param int $order_id The order ID.
536
- * @param int $ticket_id The ticket ID.
537
- * @param int $post_id The ID of the post associated to the ticket.
538
- * @param \Tribe__Tickets__Tickets $provider The current ticket provider object.
539
- */
540
- $individual_attendee_name = apply_filters( 'tribe_tickets_attendee_create_individual_name', $attendee_full_name, $i, $order_id, $product_id, $post_id, $this );
541
-
542
- /**
543
- * Allow filtering the individual attendee email used when creating a new attendee.
544
- *
545
- * @since 5.0.3
546
- *
547
- * @param string $individual_attendee_email The attendee email.
548
- * @param int|null $attendee_number The attendee number index value from the order, starting with zero.
549
- * @param int $order_id The order ID.
550
- * @param int $ticket_id The ticket ID.
551
- * @param int $post_id The ID of the post associated to the ticket.
552
- * @param \Tribe__Tickets__Tickets $provider The current ticket provider object.
553
- */
554
- $individual_attendee_email = apply_filters( 'tribe_tickets_attendee_create_individual_email', $attendee_email, $i, $order_id, $product_id, $post_id, $this );
555
-
556
- // check if we already have an attendee or not
557
- $post_title = $individual_attendee_name . ' | ' . ( $i + 1 );
558
- $criteria = [ 'post_title' => $post_title, 'product_id' => $product_id, 'event_id' => $post_id ];
559
- $existing_attendee = wp_list_filter( $existing_attendees, $criteria );
560
-
561
- if ( ! empty( $existing_attendee ) ) {
562
- $existing_attendee = reset( $existing_attendee );
563
- $updating_attendee = true;
564
- $attendee_id = $existing_attendee['attendee_id'];
565
- $attendee = [];
566
- } else {
567
- $attendee = [
568
- 'post_title' => $post_title,
569
- ];
570
-
571
- // since we are creating at least one
572
- $has_generated_new_tickets = true;
573
- }
574
-
575
- $attendee_order_status = trim( strtolower( $payment_status ) );
576
-
577
- $repository = tribe_attendees( $this->orm_provider );
578
-
579
- $data = $attendee;
580
-
581
- $data['order_attendee_id'] = $order_attendee_id;
582
- $data['attendee_status'] = $attendee_order_status;
583
-
584
- if ( Order_Statuses::$refunded === $payment_status ) {
585
- $refund_order_id = \Tribe__Utils__Array::get( $transaction_data, 'txn_id', '' );
586
-
587
- $data['refund_order_id'] = $refund_order_id;
588
- }
589
 
590
- if ( ! $updating_attendee ) {
591
- $optout = \Tribe__Utils__Array::get( $attendee_optouts, 'ticket_' . $product_id, false );
592
- $optout = filter_var( $optout, FILTER_VALIDATE_BOOLEAN );
593
- $optout = $optout ? 'yes' : 'no';
594
-
595
- $data['ticket_id'] = $product_id;
596
- $data['post_id'] = $post_id;
597
- $data['order_id'] = $order_id;
598
- $data['optout'] = $optout;
599
- $data['full_name'] = $individual_attendee_name;
600
- $data['email'] = $individual_attendee_email;
601
- $data['price_paid'] = get_post_meta( $product_id, '_price', true );
602
- $data['price_currency'] = $currency_symbol;
603
-
604
- if ( 0 < $attendee_user_id ) {
605
- $data['user_id'] = $attendee_user_id;
606
- }
607
-
608
- $attendee_object = tribe( Module::class )->create_attendee( $ticket_type, $data );
609
- $attendee_id = $attendee_object->ID;
610
-
611
- } else {
612
- // Update attendee.
613
- tribe( Module::class )->update_attendee( $attendee_id, $data );
614
- }
615
 
616
- $order->add_attendee( $attendee_id );
 
 
 
 
 
 
 
 
 
 
 
617
 
618
- $order_attendee_id ++;
 
 
 
 
 
 
 
 
 
 
619
 
620
- if ( ! empty( $existing_attendee ) ) {
621
- $existing_attendees = wp_list_filter( $existing_attendees, array( 'attendee_id' => $existing_attendee['attendee_id'] ), 'NOT' );
622
- }
623
- }
624
-
625
- if ( ! ( empty( $existing_attendees ) || empty( $oversell_policy ) ) ) {
626
- // an oversell policy applied: what to do with existing oversold attendees?
627
- $oversell_policy->handle_oversold_attendees( $existing_attendees );
628
- }
629
-
630
- if ( $has_generated_new_tickets ) {
631
- /**
632
- * Action fired when a PayPal has had attendee tickets generated for it.
633
- *
634
- * @since 4.7
635
- *
636
- * @param int $product_id PayPal ticket post ID
637
- * @param string $order_id ID of the PayPal order
638
- * @param int $qty Quantity ordered
639
- */
640
- do_action( 'event_tickets_tpp_tickets_generated_for_product', $product_id, $order_id, $qty );
641
- }
642
-
643
- /**
644
- * Action fired when a PayPal has had attendee tickets updated for it.
645
- *
646
- * This will fire even when tickets are initially created; if you need to hook on the
647
- * creation process only use the 'event_tickets_tpp_tickets_generated_for_product' action.
648
- *
649
- * @since 4.7
650
- *
651
- * @param int $product_id PayPal ticket post ID
652
- * @param string $order_id ID of the PayPal order
653
- * @param int $qty Quantity ordered
654
- */
655
- do_action( 'event_tickets_tpp_tickets_generated_for_product', $product_id, $order_id, $qty );
656
-
657
- // After Adding the Values we Update the Transient
658
- \Tribe__Post_Transient::instance()->delete( $post_id, \Tribe__Tickets__Tickets::ATTENDEES_CACHE );
659
  }
660
 
661
- /**
662
- * Fires when an PayPal attendee tickets have been generated.
663
- *
664
- * @since 4.7
665
- *
666
- * @param string $order_id ID of the PayPal order
667
- * @param int $post_id ID of the post the order was placed for
668
- */
669
- do_action( 'event_tickets_tpp_tickets_generated', $order_id, $post_id );
670
-
671
- /**
672
- * Filters whether a confirmation email should be sent or not for PayPal tickets.
673
- *
674
- * This applies to attendance and non attendance emails.
675
- *
676
- * @since 4.7
677
- *
678
- * @param bool $send_mail Defaults to `true`.
679
- */
680
- $send_mail = apply_filters( 'tribe_tickets_tpp_send_mail', true );
681
-
682
- if (
683
- $send_mail
684
- && $has_tickets
685
- && $attendee_order_status === Order_Statuses::$completed
686
- ) {
687
- $this->send_tickets_email( $order_id, $post_id );
688
- }
689
  }
690
- }
2
 
3
  namespace TEC\Tickets\Commerce;
4
 
5
+ use TEC\Tickets\Commerce\Gateways\Abstract_Gateway;
6
+ use TEC\Tickets\Commerce\Gateways\Interface_Gateway;
7
  use TEC\Tickets\Commerce\Utils\Price;
8
  use Tribe__Date_Utils as Dates;
9
 
 
10
  /**
11
  * Class Order
12
  *
15
  * @package TEC\Tickets\Commerce
16
  */
17
  class Order {
18
+
19
  /**
20
  * Tickets Commerce Order Post Type slug.
21
  *
54
  public static $gateway_payload_meta_key = '_tec_tc_order_gateway_payload';
55
 
56
  /**
57
+ * Which meta holds the items used to setup this order.
58
  *
59
  * @since 5.1.9
60
+ * @since 5.2.0 Updated to use `_tec_tc_order_items` instead of `_tec_tc_order_items`.
61
  *
62
  * @var string
63
  */
64
+ public static $items_meta_key = '_tec_tc_order_items';
65
 
66
  /**
67
  * Which meta holds the tickets in a given order, they are added as individual meta items, allowing them to be
137
  */
138
  public static $purchaser_email_meta_key = '_tec_tc_order_purchaser_email';
139
 
140
+ /**
141
+ * Which meta holds the purchaser user id.
142
+ *
143
+ * @since 5.1.9
144
+ *
145
+ * @var string
146
+ */
147
+ public static $purchaser_user_id_meta_key = '_tec_tc_order_purchaser_user_id';
148
+
149
  /**
150
  * Prefix for the log of when a given status was applied.
151
  *
164
  */
165
  public static $flag_action_status_marker_meta_key_prefix = '_tec_tc_order_fa_marker';
166
 
167
+ /**
168
+ * Meta that holds the hash for this order, which at the time of purchase was unique.
169
+ *
170
+ * @since 5.2.0
171
+ *
172
+ * @var string
173
+ */
174
+ public static $hash_meta_key = '_tec_tc_order_hash';
175
+
176
+ /**
177
+ * Meta value for placeholder names.
178
+ *
179
+ * @since 5.2.0
180
+ *
181
+ * @var string
182
+ */
183
+ public static $placeholder_name = 'Unknown';
184
+
185
  /**
186
  * Register this Class post type into WP.
187
  *
204
  * Filter the arguments that craft the order post type.
205
  *
206
  * @see register_post_type
 
207
  * @since 5.1.9
208
  *
209
  * @param array $post_type_args Post type arguments, passed to register_post_type()
210
+ *
211
  */
212
  $post_type_args = apply_filters( 'tec_tickets_commerce_order_post_type_args', $post_type_args );
213
 
223
  *
224
  * @return string
225
  */
226
+ public static function get_status_log_meta_key( Status\Status_Interface $status ) {
227
  return static::$status_log_meta_key_prefix . '_' . $status->get_slug();
228
  }
229
 
236
  *
237
  * @return string
238
  */
239
+ public static function get_gateway_payload_meta_key( Status\Status_Interface $status ) {
240
  return static::$gateway_payload_meta_key . '_' . $status->get_slug();
241
  }
242
 
250
  *
251
  * @return string
252
  */
253
+ public static function get_flag_action_marker_meta_key( $flag, Status\Status_Interface $status ) {
254
  $prefix = static::$flag_action_status_marker_meta_key_prefix;
255
 
256
  return "{$prefix}:{$status->get_slug()}:{$flag}";
270
  * @return bool|\WP_Error
271
  */
272
  public function modify_status( $order_id, $status_slug, array $extra_args = [] ) {
273
+ $status = tribe( Status\Status_Handler::class )->get_by_slug( $status_slug );
274
 
275
  if ( ! $status ) {
276
  return false;
283
 
284
  $args = array_merge( $extra_args, [ 'status' => $status->get_wp_slug() ] );
285
 
286
+ $updated = tec_tc_orders()->by_args(
287
+ [
288
+ 'status' => 'any',
289
+ 'id' => $order_id,
290
+ ]
291
+ )->set_args( $args )->save();
292
 
293
  // After modifying the status we add a meta to flag when it was modified.
294
  if ( $updated ) {
308
  *
309
  * @return false|\WP_Post
310
  */
311
+ public function create_from_cart( Interface_Gateway $gateway, $purchaser = null ) {
312
  $cart = tribe( Cart::class );
313
 
314
  $items = $cart->get_items_in_cart();
315
+ $items = array_map(
316
+ static function ( $item ) {
317
+ $ticket = \Tribe__Tickets__Tickets::load_ticket_object( $item['ticket_id'] );
318
+ if ( null === $ticket ) {
319
+ return null;
320
+ }
321
 
322
+ $item['sub_total'] = Price::sub_total( $ticket->price, $item['quantity'] );
323
+ $item['price'] = $ticket->price;
324
 
325
+ return $item;
326
+ },
327
+ $items
328
+ );
329
  $items = array_filter( $items );
330
  $sub_totals = array_filter( wp_list_pluck( $items, 'sub_total' ) );
331
  $total = Price::total( $sub_totals );
332
 
333
  $order_args = [
334
  'title' => $this->generate_order_title( $items, $cart->get_cart_hash() ),
335
+ 'total_value' => Price::to_numeric( $total ),
336
+ 'items' => $items,
337
  'gateway' => $gateway::get_key(),
338
+ 'hash' => $cart->get_cart_hash(),
339
  ];
340
 
341
  // When purchaser data-set is not passed we pull from the current user.
342
  if ( empty( $purchaser ) && is_user_logged_in() && $user = wp_get_current_user() ) {
343
+ $order_args['purchaser_user_id'] = $user->ID;
344
  $order_args['purchaser_full_name'] = $user->first_name . ' ' . $user->last_name;
345
  $order_args['purchaser_first_name'] = $user->first_name;
346
  $order_args['purchaser_last_name'] = $user->last_name;
347
  $order_args['purchaser_email'] = $user->user_email;
348
+ } elseif ( empty( $purchaser ) ) {
349
+ $order_args['purchaser_user_id'] = 0;
350
+ $order_args['purchaser_full_name'] = static::$placeholder_name;
351
+ $order_args['purchaser_first_name'] = static::$placeholder_name;
352
+ $order_args['purchaser_last_name'] = static::$placeholder_name;
353
+ $order_args['purchaser_email'] = '';
354
  }
355
 
356
+ $order = $this->create( $gateway, $order_args );
357
 
358
  // We were unable to create the order bail from here.
359
  if ( ! $order ) {
363
  return $order;
364
  }
365
 
366
+ /**
367
+ * Filters the values and creates a new Order with Tickets Commerce.
368
+ *
369
+ * @since 5.2.0
370
+ *
371
+ * @throws \Tribe__Repository__Usage_Error
372
+ *
373
+ * @param Interface_Gateway $gateway
374
+ * @param array $args
375
+ *
376
+ * @return false|\WP_Post
377
+ */
378
+ public function create( Interface_Gateway $gateway, $args ) {
379
+ $gateway_key = $gateway::get_key();
380
+
381
+ /**
382
+ * Allows filtering of the order creation arguments for all orders created via Tickets Commerce.
383
+ *
384
+ * @since 5.2.0
385
+ *
386
+ * @param array $args
387
+ * @param Interface_Gateway $gateway
388
+ */
389
+ $args = apply_filters( "tec_tickets_commerce_order_{$gateway_key}_create_args", $args, $gateway );
390
+
391
+ /**
392
+ * Allows filtering of the order creation arguments for all orders created via Tickets Commerce.
393
+ *
394
+ * @since 5.2.0
395
+ *
396
+ * @param array $args
397
+ * @param Interface_Gateway $gateway
398
+ */
399
+ $args = apply_filters( 'tec_tickets_commerce_order_create_args', $args, $gateway );
400
+
401
+ return tec_tc_orders()->set_args( $args )->create();
402
+ }
403
+
404
  /**
405
  * Generates a title based on Cart Hash, items in the cart.
406
  *
407
  * @since 5.1.9
408
  *
409
+ * @param array $items List of events form.
410
  *
411
  * @return string
412
  */
413
  public function generate_order_title( $items, $hash = null ) {
414
  $title = [ 'TEC-TC' ];
415
  if ( $hash ) {
416
+ $title[] = implode( '-', (array) $hash );
417
  }
418
  $title[] = 'T';
419
 
423
  return implode( '-', $title );
424
  }
425
 
426
+ /**
427
+ * Return payment method label for the order.
428
+ *
429
+ * @since 5.2.0
430
+ *
431
+ * @param int|\WP_Post $order Order Object.
432
+ *
433
+ * @return string
434
+ */
435
+ public function get_gateway_label( $order ) {
436
+ if ( is_numeric( $order ) ) {
437
+ $order = tec_tc_get_order( $order );
438
+ }
439
+
440
+ if ( ! $order instanceof \WP_Post ) {
441
+ return null;
442
+ }
443
+
444
+ $gateway = tribe( Gateways\Manager::class )->get_gateway_by_key( $order->gateway );
445
+
446
+ return $gateway ? $gateway::get_label() : null;
447
+ }
448
+
449
  /**
450
  * Redirects to the source post after a recoverable (logic) error.
451
  *
452
  * @todo Determine if redirecting should be something relegated to some other method, and here we just actually
453
+ * generate the order/Attendees.
454
+ *
455
+ * @todo Deprecate tpp_error
456
  *
457
  * @see \Tribe__Tickets__Commerce__PayPal__Errors for error codes translations.
458
  * @since 5.1.9
459
  *
460
+ * @param int $post_id A post ID.
 
 
 
461
  *
462
+ * @param int $error_code The current error code.
463
+ * @param bool $redirect Whether to really redirect or not.
464
  */
465
  protected function redirect_after_error( $error_code, $redirect, $post_id ) {
466
  $url = add_query_arg( 'tpp_error', $error_code, get_permalink( $post_id ) );
471
  }
472
 
473
  /**
474
+ * Loads an order object with information about its attendees
475
  *
476
+ * @since 5.2.0
477
  *
478
+ * @param \WP_Post $order the order object.
 
479
  *
480
+ * @return \WP_Post|\WP_Post[]
481
  */
482
+ public function get_attendees( \WP_Post $order ) {
483
+ $order->attendees = tribe( Module::class )->get_attendees_by_order_id( $order->ID );
 
 
 
 
 
 
 
 
 
 
 
 
 
484
 
485
+ if ( empty( $order->attendees ) ) {
486
+ $order->attendees = [
487
+ 'name' => get_post_meta( $order->ID, static::$purchaser_full_name_meta_key, true ),
488
+ 'email' => get_post_meta( $order->ID, static::$purchaser_email_meta_key, true ),
489
+ ];
490
 
491
+ return [ $order ];
 
 
 
 
 
 
 
 
 
 
 
 
 
492
  }
493
 
494
+ return $order;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
 
496
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
497
 
498
+ /**
499
+ * Returns the Ticket ID that is associated with the attendee
500
+ *
501
+ * @since 5.2.0
502
+ *
503
+ * @param \WP_Post $attendee the attendee object.
504
+ *
505
+ * @return mixed
506
+ */
507
+ public function get_ticket_id( \WP_Post $attendee ) {
508
+ return get_post_meta( $attendee->ID, static::$tickets_in_order_meta_key, true );
509
+ }
510
 
511
+ /**
512
+ * Check if the order is of valid type.
513
+ *
514
+ * @since 5.2.0
515
+ *
516
+ * @param int|\WP_Post $order The Order object to check.
517
+ *
518
+ * @return bool
519
+ */
520
+ public static function is_valid( $order ) {
521
+ $order = get_post( $order );
522
 
523
+ if ( ! $order ) {
524
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
  }
526
 
527
+ return static::POSTTYPE === $order->post_type;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
  }
529
+ }
src/Tickets/Commerce/Payments_Tab.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce;
4
+
5
+ use TEC\Tickets\Settings as Tickets_Settings;
6
+ use \tad_DI52_ServiceProvider;
7
+
8
+ /**
9
+ * Class Payments_Tab
10
+ *
11
+ * @since 5.2.0
12
+ *
13
+ * @package TEC\Tickets\Commerce
14
+ */
15
+ class Payments_Tab extends tad_DI52_ServiceProvider {
16
+
17
+ /**
18
+ * @inheritdoc
19
+ */
20
+ public function register() {
21
+ $this->container->singleton( static::class, $this );
22
+ }
23
+
24
+ /**
25
+ * Create the Tickets Commerce Payments Settings Tab.
26
+ *
27
+ * @since 5.2.0
28
+ */
29
+ public function register_tab() {
30
+ $tab_settings = [
31
+ 'priority' => 25,
32
+ 'fields' => $this->get_top_level_settings(),
33
+ 'show_save' => true,
34
+ ];
35
+
36
+ $tab_settings = apply_filters( 'tec_tickets_commerce_payments_tab_settings', $tab_settings );
37
+
38
+ new \Tribe__Settings_Tab( 'payments', esc_html__( 'Payments', 'event-tickets' ), $tab_settings );
39
+ }
40
+
41
+
42
+ /**
43
+ * Gets the top level settings for Tickets Commerce.
44
+ *
45
+ * @since 5.2.0
46
+ *
47
+ * @return array[]
48
+ */
49
+ public function get_top_level_settings() {
50
+
51
+ $plus_link = sprintf(
52
+ '<a href="https://evnt.is/19zl" target="_blank" rel="noopener noreferrer">%s</a>',
53
+ esc_html__( 'Event Tickets Plus', 'event-tickets' )
54
+ );
55
+ $plus_link_2 = sprintf(
56
+ '<a href="https://evnt.is/19zl" target="_blank" rel="noopener noreferrer">%s</a>',
57
+ esc_html__( 'Check it out!', 'event-tickets' )
58
+ );
59
+ $plus_message = sprintf(
60
+ // Translators: %1$s: The Event Tickets Plus link, %2$s: The word "ticket" in lowercase, %3$s: The "Check it out!" link.
61
+ esc_html_x( 'Tickets Commerce is a light implementation of a commerce gateway using PayPal and simplified stock handling. If you need more advanced features, take a look at %1$s. In addition to integrating with your favorite ecommerce provider, Event Tickets Plus includes options to collect custom information for attendees, check attendees in via QR codes, and share stock between %2$s. %3$s', 'about Tickets Commerce', 'event-tickets' ),
62
+ $plus_link,
63
+ esc_html( tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_about_tribe_commerce' ) ),
64
+ $plus_link_2
65
+ );
66
+
67
+ $is_tickets_commerce_enabled = tec_tickets_commerce_is_enabled();
68
+
69
+ $top_level_settings = [
70
+ 'tribe-form-content-start' => [
71
+ 'type' => 'html',
72
+ 'html' => '<div class="tribe-settings-form-wrap">',
73
+ ],
74
+ 'tickets-commerce-header' => [
75
+ 'type' => 'html',
76
+ 'html' => '<div class="tec-tickets__admin-settings-tickets-commerce-toggle-wrapper">
77
+ <label class="tec-tickets__admin-settings-tickets-commerce-toggle">
78
+ <input
79
+ type="checkbox"
80
+ name="' . Tickets_Settings::$tickets_commerce_enabled . '"
81
+ ' . checked( $is_tickets_commerce_enabled, true, false ) . '
82
+ id="tickets-commerce-enable-input"
83
+ class="tec-tickets__admin-settings-tickets-commerce-toggle-checkbox tribe-dependency tribe-dependency-verified">
84
+ <span class="tec-tickets__admin-settings-tickets-commerce-toggle-switch"></span>
85
+ <span class="tec-tickets__admin-settings-tickets-commerce-toggle-label">' . esc_html__( 'Enable Tickets Commerce', 'event-tickets' ) . '</span>
86
+ </label>
87
+ </div>',
88
+
89
+ ],
90
+ 'tickets-commerce-description' => [
91
+ 'type' => 'html',
92
+ 'html' => '<div class="tec-tickets__admin-settings-tickets-commerce-description">' . $plus_message . '</div>',
93
+ ],
94
+ Tickets_Settings::$tickets_commerce_enabled => [
95
+ 'type' => 'hidden',
96
+ 'validation_type' => 'boolean',
97
+ ],
98
+ ];
99
+
100
+ /**
101
+ * Hook to modify the top level settings for Tickets Commerce.
102
+ *
103
+ * @since 5.2.0
104
+ *
105
+ * @param array[] $top_level_settings Top level settings.
106
+ */
107
+ return apply_filters( 'tec_tickets_commerce_settings_top_level', $top_level_settings );
108
+ }
109
+ }
src/Tickets/Commerce/Provider.php CHANGED
@@ -28,13 +28,15 @@ class Provider extends tad_DI52_ServiceProvider {
28
  */
29
  public function register() {
30
 
 
 
 
31
  // Specifically prevents anything else from loading.
32
  if ( ! tec_tickets_commerce_is_enabled() ) {
33
  return;
34
  }
35
 
36
  $this->register_hooks();
37
- $this->register_assets();
38
 
39
  $this->load_functions();
40
 
@@ -48,10 +50,13 @@ class Provider extends tad_DI52_ServiceProvider {
48
  $this->container->singleton( Gateways\Manager::class, Gateways\Manager::class );
49
 
50
  $this->container->singleton( Reports\Attendance_Totals::class );
51
- $this->container->singleton( Reports\Event::class );
52
- $this->container->singleton( Reports\Ticket::class );
 
 
53
 
54
  $this->container->singleton( Editor\Metabox::class );
 
55
 
56
  $this->container->singleton( Module::class );
57
  $this->container->singleton( Attendee::class );
@@ -67,8 +72,15 @@ class Provider extends tad_DI52_ServiceProvider {
67
  $this->container->register( Status\Status_Handler::class );
68
  $this->container->register( Flag_Actions\Flag_Action_Handler::class );
69
 
 
 
 
70
  // Load any external SPs we might need.
71
  $this->container->register( Gateways\PayPal\Provider::class );
 
 
 
 
72
  }
73
 
74
  /**
28
  */
29
  public function register() {
30
 
31
+ $this->container->register( Payments_Tab::class );
32
+ $this->register_assets();
33
+
34
  // Specifically prevents anything else from loading.
35
  if ( ! tec_tickets_commerce_is_enabled() ) {
36
  return;
37
  }
38
 
39
  $this->register_hooks();
 
40
 
41
  $this->load_functions();
42
 
50
  $this->container->singleton( Gateways\Manager::class, Gateways\Manager::class );
51
 
52
  $this->container->singleton( Reports\Attendance_Totals::class );
53
+ $this->container->singleton( Reports\Attendees::class );
54
+ $this->container->singleton( Reports\Orders::class );
55
+ $this->container->singleton( Admin_Tables\Orders::class );
56
+ $this->container->singleton( Admin_Tables\Attendees::class );
57
 
58
  $this->container->singleton( Editor\Metabox::class );
59
+ $this->container->singleton( Notice_Handler::class );
60
 
61
  $this->container->singleton( Module::class );
62
  $this->container->singleton( Attendee::class );
72
  $this->container->register( Status\Status_Handler::class );
73
  $this->container->register( Flag_Actions\Flag_Action_Handler::class );
74
 
75
+ // Register Compatibility Classes
76
+ $this->container->singleton( Compatibility\Events::class );
77
+
78
  // Load any external SPs we might need.
79
  $this->container->register( Gateways\PayPal\Provider::class );
80
+ $this->container->register( Gateways\Manual\Provider::class );
81
+
82
+ // Register and add hooks for admin notices.
83
+ $this->container->register( Admin\Notices::class );
84
  }
85
 
86
  /**
src/Tickets/Commerce/Reports/Attendees.php ADDED
@@ -0,0 +1,588 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Attendees Report
4
+ *
5
+ * @package TEC\Tickets
6
+ */
7
+
8
+ namespace TEC\Tickets\Commerce\Reports;
9
+
10
+ use TEC\Tickets\Commerce;
11
+ use TEC\Tickets\Commerce\Admin_Tables;
12
+ use TEC\Tickets\Commerce\Module;
13
+ use TEC\Tickets\Commerce\Utils\Price;
14
+
15
+ /**
16
+ * Class Reports for Attendees
17
+ *
18
+ * @since 5.2.0
19
+ */
20
+ class Attendees extends Report_Abstract {
21
+
22
+ /**
23
+ * Slug of the admin page for attendees
24
+ *
25
+ * @since 5.2.0
26
+ *
27
+ * @var string
28
+ */
29
+ public static $page_slug = 'tickets-commerce-attendees';
30
+
31
+ /**
32
+ * Order Pages ID on the menu.
33
+ *
34
+ * @since 5.2.0
35
+ *
36
+ * @var string The menu slug of the orders page
37
+ */
38
+ public $attendees_page;
39
+
40
+ /**
41
+ * Gets the Orders Report.
42
+ *
43
+ * @since 5.2.0
44
+ * @return string
45
+ */
46
+ public function get_title() {
47
+ $post_id = tribe_get_request_var( 'event_id' );
48
+
49
+ // translators: The title of an event's Attendee List page in the dashboard. %1$s is the name of the event. %2$d is numeric the event ID.
50
+ return sprintf( __( 'Attendees for: %1$s [#%2$d]', 'event-tickets' ), esc_html( get_the_title( $post_id ) ), (int) $post_id );
51
+ }
52
+
53
+ /**
54
+ * Hooks the actions and filter required by the class.
55
+ *
56
+ * @since 5.2.0
57
+ */
58
+ public function hook() {
59
+ add_action( 'admin_menu', [ $this, 'register_attendees_page' ] );
60
+ }
61
+
62
+ /**
63
+ * Registers the Tickets Commerce orders page as a plugin options page.
64
+ *
65
+ * @since 5.2.0
66
+ */
67
+ public function register_attendees_page() {
68
+ $candidate_post_id = tribe_get_request_var( 'post_id', 0 );
69
+ $candidate_post_id = tribe_get_request_var( 'event_id', $candidate_post_id );
70
+ $post_id = absint( $candidate_post_id );
71
+
72
+ if ( $post_id !== (int) $candidate_post_id ) {
73
+ return;
74
+ }
75
+
76
+ $cap = 'edit_posts';
77
+ if ( ! current_user_can( 'edit_posts' ) && $post_id ) {
78
+ $post = get_post( $post_id );
79
+
80
+ if ( $post instanceof WP_Post && get_current_user_id() === (int) $post->post_author ) {
81
+ $cap = 'read';
82
+ }
83
+ }
84
+
85
+ $page_title = __( 'Tickets Commerce Attendees', 'event-tickets' );
86
+ $this->attendees_page = add_submenu_page(
87
+ null,
88
+ $page_title,
89
+ $page_title,
90
+ $cap,
91
+ static::$page_slug,
92
+ [ $this, 'render_page' ]
93
+ );
94
+
95
+ $attendees = tribe( Commerce\Admin_Tables\Attendees::class );
96
+
97
+ add_filter( 'tribe_filter_attendee_page_slug', [ $this, 'add_attendee_resources_page_slug' ] );
98
+ add_action( 'admin_enqueue_scripts', [ $attendees, 'enqueue_assets' ] );
99
+ add_action( 'admin_enqueue_scripts', [ $attendees, 'load_pointers' ] );
100
+ add_action( 'load-' . $this->attendees_page, [ $this, 'attendees_page_screen_setup' ] );
101
+ }
102
+
103
+ /**
104
+ * Sets the browser title for the Attendees admin page.
105
+ * Uses the event title.
106
+ *
107
+ * @since 5.2.0
108
+ *
109
+ * @param string $admin_title The page title in the admin.
110
+ *
111
+ * @return string
112
+ */
113
+ public function filter_admin_title( $admin_title ) {
114
+ if ( ! empty( (int) $_GET['event_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
115
+ $event = get_post( (int) $_GET['event_id'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
116
+ // translators: The title of an event's Attendee List page in the dashboard. %1$s is the name of the event.
117
+ $admin_title = sprintf( __( '%1$s - Attendee list', 'event-tickets' ), $event->post_title );
118
+ }
119
+
120
+ return $admin_title;
121
+ }
122
+
123
+ /**
124
+ * Filter the page slugs that the attendee resources will load to add the order page
125
+ *
126
+ * @since 5.2.0
127
+ *
128
+ * @param array $slugs an array of admin slugs.
129
+ *
130
+ * @return array
131
+ */
132
+ public function add_attendee_resources_page_slug( $slugs ) {
133
+ $slugs[] = $this->attendees_page;
134
+
135
+ return $slugs;
136
+ }
137
+
138
+ /**
139
+ * Sets up the attendees page screen.
140
+ *
141
+ * @since 5.2.0
142
+ */
143
+ public function attendees_page_screen_setup() {
144
+ $action = tribe_get_request_var( 'tribe-send-email', false );
145
+
146
+ $orders_table = tribe( Commerce\Admin_Tables\Attendees::class );
147
+ $orders_table->prepare_items();
148
+
149
+ wp_enqueue_script( 'jquery-ui-dialog' );
150
+
151
+ add_filter( 'admin_title', [ $this, 'filter_admin_title' ] );
152
+
153
+ if ( $action ) {
154
+ define( 'IFRAME_REQUEST', true );
155
+
156
+ // Use iFrame Header -- WP Method.
157
+ iframe_header();
158
+
159
+ // Check if we need to send an Email!
160
+ $status = false;
161
+ if ( isset( $_POST['tribe-send-email'] ) && $_POST['tribe-send-email'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
162
+ $status = tribe( \Tribe__Tickets__Attendees::class )->send_mail_list();
163
+ }
164
+
165
+ tribe( 'tickets.admin.views' )->template( 'attendees-email', [ 'status' => $status ] );
166
+
167
+ // Use iFrame Footer -- WP Method.
168
+ iframe_footer();
169
+
170
+ // We need nothing else here.
171
+ exit;
172
+ } else {
173
+ $this->maybe_generate_csv();
174
+
175
+ add_filter( 'admin_title', [ $this, 'filter_admin_title' ], 10, 2 );
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Renders the order page
181
+ *
182
+ * @since 5.2.0
183
+ */
184
+ public function render_page() {
185
+
186
+ do_action( 'tribe_tickets_attendees_page_inside', tribe( \Tribe__Tickets__Attendees::class ) );
187
+
188
+ $this->get_template()->template( 'attendees', $this->get_template_vars() );
189
+ }
190
+
191
+ /**
192
+ * @inheritDoc
193
+ *
194
+ * @since 5.2.0
195
+ */
196
+ public function setup_template_vars() {
197
+ $post_id = tribe_get_request_var( 'post_id' );
198
+ $post_id = tribe_get_request_var( 'event_id', $post_id );
199
+ $post = get_post( $post_id );
200
+
201
+ $post_type_object = get_post_type_object( $post->post_type );
202
+ $post_singular_label = $post_type_object->labels->singular_name;
203
+
204
+ $tickets = \Tribe__Tickets__Tickets::get_event_tickets( $post_id );
205
+ $ticket_ids = tribe_get_request_var( 'product_ids', false );
206
+
207
+ if ( false !== $ticket_ids ) {
208
+ $ticket_ids = array_map( 'absint', explode( ',', $ticket_ids ) );
209
+ $ticket_ids = array_filter(
210
+ $ticket_ids,
211
+ static function ( $ticket_id ) {
212
+ return get_post_type( $ticket_id ) === Commerce\Ticket::POSTTYPE;
213
+ }
214
+ );
215
+ $tickets = array_map( [ tribe( Commerce\Ticket::class ), 'get_ticket' ], $ticket_ids );
216
+ }
217
+
218
+ $event_data = [];
219
+ $tickets_data = [];
220
+
221
+ foreach ( $tickets as $ticket ) {
222
+ $quantities = tribe( Commerce\Ticket::class )->get_status_quantity( $ticket->ID );
223
+ $total_by_status = [];
224
+ foreach ( $quantities as $status_slug => $status_count ) {
225
+ if ( ! isset( $event_data['qty_by_status'][ $status_slug ] ) ) {
226
+ $event_data['qty_by_status'][ $status_slug ] = 0;
227
+ }
228
+ if ( ! isset( $event_data['total_by_status'][ $status_slug ] ) ) {
229
+ $event_data['total_by_status'][ $status_slug ] = [];
230
+ }
231
+
232
+ $total_by_status[ $status_slug ] = Price::sub_total( $ticket->price, $status_count );
233
+ $event_data['total_by_status'][ $status_slug ][] = $total_by_status[ $status_slug ];
234
+
235
+ $event_data['qty_by_status'][ $status_slug ] += (int) $status_count;
236
+ }
237
+ $tickets_data[ $ticket->ID ] = [
238
+ 'total_by_status' => $total_by_status,
239
+ 'qty_by_status' => $quantities,
240
+ ];
241
+ }
242
+
243
+ $event_data['total_by_status'] = array_map(
244
+ static function ( $sub_totals ) {
245
+ return Price::total( $sub_totals );
246
+ },
247
+ $event_data['total_by_status']
248
+ );
249
+
250
+ $this->template_vars = [
251
+ 'event_data' => $event_data,
252
+ 'export_url' => '',
253
+ 'post' => $post,
254
+ 'post_id' => $post_id,
255
+ 'post_singular_label' => $post_singular_label,
256
+ 'post_type_object' => $post_type_object,
257
+ 'report' => tribe( $this ),
258
+ 'table' => tribe( Admin_Tables\Attendees::class ),
259
+ 'tickets' => $tickets,
260
+ 'tickets_data' => $tickets_data,
261
+ 'title' => $this->get_title(),
262
+ 'tooltip' => tribe( 'tooltip.view' ),
263
+ ];
264
+
265
+ return $this->template_vars;
266
+ }
267
+
268
+ /**
269
+ * Determines if the "export" button will be displayed by the the title
270
+ *
271
+ * @since 5.2.0
272
+ *
273
+ * @param int $event_id The event whose attendees may be exported.
274
+ *
275
+ * @return bool
276
+ */
277
+ public function can_export_attendees( $event_id ) {
278
+
279
+ if ( tribe_get_request_var( 'page' ) !== static::$page_slug ) {
280
+ return false;
281
+ }
282
+
283
+ if ( ! tribe( Admin_Tables\Attendees::class )->has_items() ) {
284
+ return false;
285
+ }
286
+
287
+ if ( ! $this->user_can_manage_attendees( \get_current_user_id(), $event_id ) ) {
288
+ return false;
289
+ }
290
+
291
+ return true;
292
+ }
293
+
294
+ /**
295
+ * Determines if the current user (or an ID-specified one) is allowed to delete, check-in, and
296
+ * undo check-in attendees.
297
+ *
298
+ * @param int $user_id Optional. The ID of the user whose access we're checking.
299
+ * @param string $event_id Optional. The ID of the event the user is managing.
300
+ *
301
+ * @return boolean
302
+ * @since 5.2.0
303
+ */
304
+ public function user_can_manage_attendees( $user_id = 0, $event_id = '' ) {
305
+ $user_id = 0 === $user_id ? get_current_user_id() : $user_id;
306
+ $user_can = true;
307
+
308
+ // bail quickly here as we don't have a user to check.
309
+ if ( empty( $user_id ) ) {
310
+ return false;
311
+ }
312
+
313
+ /**
314
+ * Allows customizing the caps a user must have to be allowed to manage attendees.
315
+ *
316
+ * @since 5.2.0
317
+ *
318
+ * @param int $user_id The ID of the user whose capabilities are being checked.
319
+ *
320
+ * @param array $default_caps The caps a user must have to be allowed to manage attendees.
321
+ */
322
+ $required_caps = apply_filters(
323
+ 'tribe_tickets_caps_can_manage_attendees',
324
+ [
325
+ 'edit_others_posts',
326
+ ],
327
+ $user_id
328
+ );
329
+
330
+ // Next make sure the user has proper caps in their role.
331
+ foreach ( $required_caps as $cap ) {
332
+ if ( ! user_can( $user_id, $cap ) ) {
333
+ $user_can = false;
334
+ // break on first fail.
335
+ break;
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Filter our return value to let other plugins hook in and alter things
341
+ *
342
+ * @since 5.2.0
343
+ *
344
+ * @param bool $user_can return value, user can or can't
345
+ * @param int $user_id id of the user we're checking
346
+ * @param int $event_id id of the event we're checking (matter for checks on event authorship)
347
+ */
348
+ $user_can = apply_filters( 'tribe_tickets_user_can_manage_attendees', $user_can, $user_id, $event_id );
349
+
350
+ return $user_can;
351
+ }
352
+
353
+ /**
354
+ * Checks if the user requested a CSV export from the attendees list.
355
+ * If so, generates the download and finishes the execution.
356
+ *
357
+ * @since 5.2.0
358
+ */
359
+ public function maybe_generate_csv() {
360
+ if ( empty( $_GET['attendees_csv'] ) || empty( $_GET['attendees_csv_nonce'] ) || empty( $_GET['event_id'] ) ) {
361
+ return;
362
+ }
363
+
364
+ $event_id = absint( $_GET['event_id'] );
365
+
366
+ // Verify event ID is a valid integer and the nonce is accepted.
367
+ if ( empty( $event_id ) || ! wp_verify_nonce( $_GET['attendees_csv_nonce'], 'attendees_csv_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
368
+ return;
369
+ }
370
+
371
+ $event = get_post( $event_id );
372
+
373
+ // Verify event exists and current user has access to it.
374
+ if (
375
+ ! $event instanceof \WP_Post
376
+ || ! current_user_can( 'edit_posts', $event_id )
377
+ ) {
378
+ return;
379
+ }
380
+
381
+ // Generate filtered list of attendees.
382
+ $items = $this->generate_filtered_list( $event_id );
383
+
384
+ // Sanitize items for CSV usage.
385
+ $items = $this->sanitize_csv_rows( $items );
386
+
387
+ /**
388
+ * Allow for filtering and modifying the list of attendees that will be exported via CSV for a given event.
389
+ *
390
+ * @since 5.2.0
391
+ *
392
+ * @param array $items The array of attendees that will be exported in this CSV file.
393
+ * @param int $event_id The ID of the event these attendees are associated with.
394
+ */
395
+ $items = apply_filters( 'tribe_events_tickets_attendees_csv_items', $items, $event_id );
396
+
397
+ if ( ! empty( $items ) ) {
398
+ $charset = get_option( 'blog_charset' );
399
+ $filename = sanitize_file_name( $event->post_title . '-' . __( 'attendees', 'event-tickets' ) );
400
+
401
+ // Output headers so that the file is downloaded rather than displayed.
402
+ header( "Content-Type: text/csv; charset=$charset" );
403
+ header( "Content-Disposition: attachment; filename=$filename.csv" );
404
+
405
+ // Create the file pointer connected to the output stream.
406
+ $output = fopen( 'php://output', 'w' );
407
+
408
+ /**
409
+ * Allow filtering the field delimiter used in the CSV export file.
410
+ *
411
+ * @since 5.1.3
412
+ *
413
+ * @param string $delimiter The field delimiter used in the CSV export file.
414
+ */
415
+ $delimiter = apply_filters( 'tribe_tickets_attendees_csv_export_delimiter', ',' );
416
+
417
+ // Output the lines into the file.
418
+ foreach ( $items as $item ) {
419
+ fputcsv( $output, $item, $delimiter ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fputcsv
420
+ }
421
+
422
+ fclose( $output );
423
+ exit;
424
+ }
425
+ }
426
+
427
+ /**
428
+ * Generates a list of attendees taking into account the Screen Options.
429
+ * It's used both for the Email functionality, as well as the CSV export.
430
+ *
431
+ * @since 5.2.0
432
+ *
433
+ * @param int $event_id The Event ID.
434
+ *
435
+ * @return array
436
+ */
437
+ private function generate_filtered_list( $event_id ) {
438
+ $this->attendees_table = tribe( Admin_Tables\Attendees::class );
439
+ /**
440
+ * Fire immediately prior to the generation of a filtered (exportable) attendee list.
441
+ *
442
+ * @since 5.2.0
443
+ *
444
+ * @param int $event_id
445
+ */
446
+ do_action( 'tribe_events_tickets_generate_filtered_attendees_list', $event_id );
447
+
448
+ if ( empty( $this->page_id ) ) {
449
+ $this->page_id = 'tribe_events_page_tickets-attendees';
450
+ }
451
+
452
+ // Add in Columns or get_column_headers() returns nothing.
453
+ $filter_name = "manage_{$this->page_id}_columns";
454
+ add_filter( $filter_name, [ $this->attendees_table, 'get_columns' ], 15 );
455
+
456
+ $tickets_class = tribe( \Tribe__Tickets__Tickets::class );
457
+ $items = $tickets_class::get_event_attendees( $event_id );
458
+
459
+ // Add Handler for Community Tickets to Prevent Notices in Exports.
460
+ if ( ! is_admin() ) {
461
+ $columns = apply_filters( $filter_name, [] );
462
+ } else {
463
+ $columns = array_filter( (array) get_column_headers( get_current_screen() ) );
464
+ $columns = array_map( 'wp_strip_all_tags', $columns );
465
+ }
466
+
467
+ // We dont want HTML inputs, private data or other columns that are superfluous in a CSV export.
468
+ $hidden = array_merge(
469
+ get_hidden_columns( $this->page_id ),
470
+ [
471
+ 'cb',
472
+ 'meta_details',
473
+ 'primary_info',
474
+ 'provider',
475
+ 'purchaser',
476
+ 'status',
477
+ ]
478
+ );
479
+
480
+ $hidden = array_flip( $hidden );
481
+ $export_columns = array_diff_key( $columns, $hidden );
482
+
483
+ // Add additional expected columns.
484
+ $export_columns['order_id'] = esc_html_x( 'Order ID', 'attendee export', 'event-tickets' );
485
+ $export_columns['order_status_label'] = esc_html_x( 'Order Status', 'attendee export', 'event-tickets' );
486
+ $export_columns['attendee_id'] = esc_html( sprintf( _x( '%s ID', 'attendee export', 'event-tickets' ), tribe_get_ticket_label_singular( 'attendee_export_ticket_id' ) ) );
487
+ $export_columns['holder_name'] = esc_html_x( 'Ticket Holder Name', 'attendee export', 'event-tickets' );
488
+ $export_columns['holder_email'] = esc_html_x( 'Ticket Holder Email Address', 'attendee export', 'event-tickets' );
489
+ $export_columns['purchaser_name'] = esc_html_x( 'Purchaser Name', 'attendee export', 'event-tickets' );
490
+ $export_columns['purchaser_email'] = esc_html_x( 'Purchaser Email Address', 'attendee export', 'event-tickets' );
491
+
492
+ /**
493
+ * Used to modify what columns should be shown on the CSV export
494
+ * The column name should be the Array Index and the Header is the array Value
495
+ *
496
+ * @since 5.2.0
497
+ *
498
+ * @param array Columns, associative array
499
+ * @param array Items to be exported
500
+ * @param int Event ID
501
+ */
502
+ $export_columns = apply_filters( 'tribe_events_tickets_attendees_csv_export_columns', $export_columns, $items, $event_id );
503
+
504
+ // Add the export column headers as the first row.
505
+ $rows = [
506
+ array_values( $export_columns ),
507
+ ];
508
+
509
+ foreach ( $items as $single_item ) {
510
+ // Fresh row!
511
+ $row = [];
512
+ $attendee = tribe( Commerce\Attendee::class )->load_attendee_data( new \WP_Post( (object) $single_item ) );
513
+ $single_item = (array) $attendee;
514
+
515
+ foreach ( $export_columns as $column_id => $column_name ) {
516
+ // If additional columns have been added to the attendee list table we can obtain the
517
+ // values by calling the table object's column_default() method - any other values
518
+ // should simply be passed back unmodified.
519
+ $row[ $column_id ] = $this->attendees_table->column_default( $attendee, $column_id );
520
+
521
+ // Special handling for the check_in column.
522
+ if ( 'check_in' === $column_id && 1 == $single_item[ $column_id ] ) {
523
+ $row[ $column_id ] = esc_html__( 'Yes', 'event-tickets' );
524
+ }
525
+
526
+ // Special handling for new human readable id.
527
+ if ( 'attendee_id' === $column_id ) {
528
+ if ( isset( $single_item[ $column_id ] ) ) {
529
+ $ticket_unique_id = get_post_meta( $single_item[ $column_id ], '_unique_id', true );
530
+ $ticket_unique_id = '' === $ticket_unique_id ? $single_item[ $column_id ] : $ticket_unique_id;
531
+ $row[ $column_id ] = esc_html( $ticket_unique_id );
532
+ }
533
+ }
534
+
535
+ // Handle custom columns that might have names containing HTML tags.
536
+ $row[ $column_id ] = wp_strip_all_tags( $row[ $column_id ] );
537
+ // Decode HTML Entities.
538
+ $row[ $column_id ] = html_entity_decode( $row[ $column_id ], ENT_QUOTES | ENT_XML1, 'UTF-8' );
539
+ // Remove line breaks (e.g. from multi-line text field) for valid CSV format. Double quotes necessary here.
540
+ $row[ $column_id ] = str_replace( [ "\r", "\n" ], ' ', $row[ $column_id ] );
541
+ }
542
+
543
+ $rows[] = array_values( $row );
544
+ }
545
+
546
+ return array_filter( $rows );
547
+ }
548
+
549
+ /**
550
+ * Sanitize rows for CSV usage.
551
+ *
552
+ * @since 5.2.0
553
+ *
554
+ * @param array $rows Rows to be sanitized.
555
+ *
556
+ * @return array Sanitized rows.
557
+ */
558
+ public function sanitize_csv_rows( array $rows ) {
559
+ foreach ( $rows as &$row ) {
560
+ $row = array_map( [ $this, 'sanitize_csv_value' ], $row );
561
+ }
562
+
563
+ return $rows;
564
+ }
565
+
566
+ /**
567
+ * Sanitize a value for CSV usage.
568
+ *
569
+ * @since 5.2.0
570
+ *
571
+ * @param mixed $value Value to be sanitized.
572
+ *
573
+ * @return string Sanitized value.
574
+ */
575
+ public function sanitize_csv_value( $value ) {
576
+ if (
577
+ 0 === tribe_strpos( $value, '=' )
578
+ || 0 === tribe_strpos( $value, '+' )
579
+ || 0 === tribe_strpos( $value, '-' )
580
+ || 0 === tribe_strpos( $value, '@' )
581
+ ) {
582
+ // Prefix the value with a single quote to prevent formula from being processed.
583
+ $value = '\'' . $value;
584
+ }
585
+
586
+ return $value;
587
+ }
588
+ }
src/Tickets/Commerce/Reports/Event.php DELETED
@@ -1,55 +0,0 @@
1
- <?php
2
-
3
- namespace TEC\Tickets\Commerce\Reports;
4
-
5
- use TEC\Tickets\Commerce\Module;
6
-
7
- /**
8
- * Class Event Report management.
9
- *
10
- * @since 5.1.9
11
- *
12
- * @package TEC\Tickets\Commerce\Reports
13
- */
14
- class Event {
15
-
16
-
17
- /**
18
- * Links to sales report for all tickets for this event.
19
- *
20
- * @since 5.1.9
21
- *
22
- * @param int $event_id
23
- * @param bool $url_only
24
- *
25
- * @return string
26
- */
27
- public function get_link( $event_id, $url_only = false ) {
28
- $ticket_ids = (array) tribe( Module::class )->get_tickets_ids( $event_id );
29
- if ( empty( $ticket_ids ) ) {
30
- return '';
31
- }
32
-
33
- $query = array(
34
- 'page' => 'tpp-orders',
35
- 'post_id' => $event_id,
36
- );
37
-
38
- $report_url = add_query_arg( $query, admin_url( 'admin.php' ) );
39
-
40
- /**
41
- * Filter the PayPal Ticket Orders (Sales) Report URL
42
- *
43
- * @var string $report_url Report URL
44
- * @var int $event_id The post ID
45
- * @var array $ticket_ids An array of ticket IDs
46
- *
47
- * @return string
48
- */
49
- $report_url = apply_filters( 'tribe_tickets_paypal_report_url', $report_url, $event_id, $ticket_ids );
50
-
51
- return $url_only
52
- ? $report_url
53
- : '<small> <a href="' . esc_url( $report_url ) . '">' . esc_html__( 'Sales report', 'event-tickets' ) . '</a> </small>';
54
- }
55
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Tickets/Commerce/Reports/Orders.php ADDED
@@ -0,0 +1,408 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Reports;
4
+
5
+ use TEC\Tickets\Commerce;
6
+ use TEC\Tickets\Commerce\Module;
7
+ use TEC\Tickets\Commerce\Utils\Price;
8
+ use WP_Post;
9
+
10
+ use Tribe__Tickets__Main as Plugin;
11
+ use Tribe__Utils__Array as Arr;
12
+
13
+
14
+ /**
15
+ * Class Orders Report.
16
+ *
17
+ * @since 5.2.0
18
+ *
19
+ * @package TEC\Tickets\Commerce\Reports
20
+ */
21
+ class Orders extends Report_Abstract {
22
+ /**
23
+ * Slug of the admin page for orders
24
+ *
25
+ * @since 5.2.0
26
+ *
27
+ * @var string
28
+ */
29
+ public static $page_slug = 'tickets-commerce-orders';
30
+
31
+ /**
32
+ * Order Pages ID on the menu.
33
+ *
34
+ * @since 5.2.0
35
+ *
36
+ * @var string The menu slug of the orders page
37
+ */
38
+ public $orders_page;
39
+
40
+ /**
41
+ * Gets the Orders Report.
42
+ *
43
+ * @since 5.2.0
44
+ *
45
+ * @return string
46
+ */
47
+ public function get_title() {
48
+ return __( 'Orders Report', 'event-tickets' );
49
+ }
50
+
51
+ /**
52
+ * Links to sales report for all tickets in Tickets Commerce for this event.
53
+ *
54
+ * @since 5.2.0
55
+ *
56
+ * @param int $event_id
57
+ * @param bool $url_only
58
+ *
59
+ * @return string
60
+ */
61
+ public function get_event_link( $event_id, $url_only = false ) {
62
+ $ticket_ids = (array) tribe( Module::class )->get_tickets_ids( $event_id );
63
+ if ( empty( $ticket_ids ) ) {
64
+ return '';
65
+ }
66
+
67
+ $post = get_post( $event_id );
68
+
69
+ $query = [
70
+ 'post_type' => $post->post_type,
71
+ 'page' => static::$page_slug,
72
+ 'post_id' => $event_id,
73
+ ];
74
+
75
+ $report_url = add_query_arg( $query, admin_url( 'admin.php' ) );
76
+
77
+ /**
78
+ * Filter the Reports Events Orders Report URL.
79
+ *
80
+ * @since 5.2.0
81
+ *
82
+ * @var string $report_url Report URL
83
+ * @var int $event_id The post ID
84
+ * @var array $ticket_ids An array of ticket IDs
85
+ *
86
+ * @return string
87
+ */
88
+ $report_url = apply_filters( 'tec_tickets_commerce_reports_orders_event_link', $report_url, $event_id, $ticket_ids );
89
+
90
+ return $url_only
91
+ ? $report_url
92
+ : '<small> <a href="' . esc_url( $report_url ) . '">' . esc_html__( 'Sales report', 'event-tickets' ) . '</a> </small>';
93
+ }
94
+
95
+ /**
96
+ * Links to the sales report for a given ticket.
97
+ *
98
+ * @since 5.2.0
99
+ *
100
+ * @param int|string $event_id
101
+ * @param int|string $ticket_id
102
+ *
103
+ * @return string
104
+ */
105
+ public function get_ticket_link( $event_id, $ticket_id ) {
106
+ if ( empty( $ticket_id ) ) {
107
+ return '';
108
+ }
109
+ $post = get_post( $event_id );
110
+
111
+ $query = [
112
+ 'post_type' => $post->post_type,
113
+ 'page' => static::$page_slug,
114
+ 'product_ids' => $ticket_id,
115
+ 'post_id' => $event_id,
116
+ ];
117
+
118
+ $report_url = add_query_arg( $query, admin_url( 'admin.php' ) );
119
+
120
+ /**
121
+ * Filter the Reports Tickets Orders Report URL.
122
+ *
123
+ * @since 5.2.0
124
+ *
125
+ * @var string $report_url Report URL
126
+ * @var int $event_id The post ID
127
+ * @var array $ticket_ids An array of ticket IDs
128
+ *
129
+ * @return string
130
+ */
131
+ $report_url = apply_filters( 'tec_tickets_commerce_reports_orders_ticket_link', $report_url, $event_id, $ticket_ids );
132
+
133
+ return '<span><a href="' . esc_url( $report_url ) . '">' . esc_html__( 'Report', 'event-tickets' ) . '</a></span>';
134
+ }
135
+
136
+ /**
137
+ * Returns the link to the "Orders" report for this post.
138
+ *
139
+ * @since 5.2.0
140
+ *
141
+ * @param WP_Post $post
142
+ *
143
+ * @return string The absolute URL.
144
+ */
145
+ public static function get_tickets_report_link( $post ) {
146
+ $url = add_query_arg(
147
+ [
148
+ 'post_type' => $post->post_type,
149
+ 'page' => static::$page_slug,
150
+ 'post_id' => $post->ID,
151
+ ],
152
+ admin_url( 'edit.php' )
153
+ );
154
+
155
+ return $url;
156
+ }
157
+
158
+ /**
159
+ * Hooks the actions and filter required by the class.
160
+ *
161
+ * @since 5.2.0
162
+ */
163
+ public function hook() {
164
+ add_filter( 'post_row_actions', [ $this, 'add_orders_row_action' ], 10, 2 );
165
+ add_action( 'admin_menu', [ $this, 'register_orders_page' ] );
166
+ }
167
+
168
+ /**
169
+ * Adds order related actions to the available row actions for the post.
170
+ *
171
+ * @since 5.2.0
172
+ *
173
+ * @param array $actions
174
+ * @param $post
175
+ *
176
+ * @return array
177
+ */
178
+ public function add_orders_row_action( array $actions, $post ) {
179
+ $post_id = \Tribe__Main::post_id_helper( $post );
180
+ $post = get_post( $post_id );
181
+
182
+ // only if tickets are active on this post type
183
+ if ( ! in_array( $post->post_type, Plugin::instance()->post_types(), true ) ) {
184
+ return $actions;
185
+ }
186
+ $commerce = tribe( Module::class );
187
+
188
+ if ( ! $commerce->post_has_tickets( $post ) ) {
189
+ return $actions;
190
+ }
191
+
192
+ $url = $commerce->get_event_reports_link( $post->ID, true );
193
+ $post_labels = get_post_type_labels( get_post_type_object( $post->post_type ) );
194
+ $post_type = strtolower( $post_labels->singular_name );
195
+
196
+ $actions['tickets_orders'] = sprintf(
197
+ '<a title="%s" href="%s">%s</a>',
198
+ sprintf( esc_html__( 'See Tickets Commerce purchases for this %s', 'event-tickets' ), $post_type ),
199
+ esc_url( $url ),
200
+ esc_html__( 'Orders', 'event-tickets' )
201
+ );
202
+
203
+ return $actions;
204
+ }
205
+
206
+ /**
207
+ * Registers the Tickets Commerce orders page as a plugin options page.
208
+ *
209
+ * @since 5.2.0
210
+ */
211
+ public function register_orders_page() {
212
+ $candidate_post_id = tribe_get_request_var( 'post_id', 0 );
213
+ $candidate_post_id = tribe_get_request_var( 'event_id', $candidate_post_id );
214
+
215
+ if ( ( $post_id = absint( $candidate_post_id ) ) != $candidate_post_id ) {
216
+ return;
217
+ }
218
+
219
+ $cap = 'edit_posts';
220
+ if ( ! current_user_can( 'edit_posts' ) && $post_id ) {
221
+ $post = get_post( $post_id );
222
+
223
+ if ( $post instanceof WP_Post && get_current_user_id() === (int) $post->post_author ) {
224
+ $cap = 'read';
225
+ }
226
+ }
227
+
228
+ $page_title = __( 'Tickets Commerce Orders', 'event-tickets' );
229
+ $this->orders_page = add_submenu_page(
230
+ null,
231
+ $page_title,
232
+ $page_title,
233
+ $cap,
234
+ static::$page_slug,
235
+ [ $this, 'render_page' ]
236
+ );
237
+
238
+ /** @var Commerce\Admin_Tables\Attendees $attendees */
239
+ $attendees = tribe( Commerce\Admin_Tables\Attendees::class );
240
+
241
+ add_filter( 'tribe_filter_attendee_page_slug', [ $this, 'add_attendee_resources_page_slug' ] );
242
+ add_action( 'admin_enqueue_scripts', [ $attendees, 'enqueue_assets' ] );
243
+ add_action( 'admin_enqueue_scripts', [ $attendees, 'load_pointers' ] );
244
+ add_action( 'load-' . $this->orders_page, [ $this, 'attendees_page_screen_setup' ] );
245
+ }
246
+
247
+ /**
248
+ * Filter the page slugs that the attendee resources will load to add the order page
249
+ *
250
+ * @since 5.2.0
251
+ *
252
+ * @param $slugs
253
+ *
254
+ * @return array
255
+ */
256
+ public function add_attendee_resources_page_slug( $slugs ) {
257
+ $slugs[] = $this->orders_page;
258
+
259
+ return $slugs;
260
+ }
261
+
262
+ /**
263
+ * Sets up the attendees page screen.
264
+ *
265
+ * @since 5.2.0
266
+ */
267
+ public function attendees_page_screen_setup() {
268
+ $orders_table = tribe( Commerce\Admin_Tables\Orders::class );
269
+ $orders_table->prepare_items();
270
+
271
+ wp_enqueue_script( 'jquery-ui-dialog' );
272
+
273
+ add_filter( 'admin_title', [ $this, 'filter_admin_title' ] );
274
+ }
275
+
276
+ /**
277
+ * Sets the browser title for the Orders admin page.
278
+ *
279
+ * @since 5.2.0
280
+ *
281
+ * @param string $admin_title
282
+ *
283
+ * @return string
284
+ */
285
+ public function filter_admin_title( $admin_title ) {
286
+ if ( ! empty( $_GET['post_id'] ) ) {
287
+ $event = get_post( $_GET['post_id'] );
288
+ $admin_title = sprintf( esc_html_x( '%s - Tickets Commerce Orders', 'Browser title', 'event-tickets' ), $event->post_title );
289
+ }
290
+
291
+ return $admin_title;
292
+ }
293
+
294
+ /**
295
+ * Renders the order page
296
+ *
297
+ * @since 5.2.0
298
+ */
299
+ public function render_page() {
300
+ $this->get_template()->template( 'orders', $this->get_template_vars() );
301
+ }
302
+
303
+ /**
304
+ * Sets up the template variables used to render the Orders Report Page.
305
+ *
306
+ * @since 5.2.0
307
+ *
308
+ * @return array
309
+ */
310
+ public function setup_template_vars() {
311
+ $post_id = tribe_get_request_var( 'post_id' );
312
+ $post_id = tribe_get_request_var( 'event_id', $post_id );
313
+ $post = get_post( $post_id );
314
+
315
+ $post_type_object = get_post_type_object( $post->post_type );
316
+ $post_singular_label = $post_type_object->labels->singular_name;
317
+
318
+ $tickets = \Tribe__Tickets__Tickets::get_event_tickets( $post_id );
319
+ $ticket_ids = tribe_get_request_var( 'product_ids', false );
320
+
321
+ if ( false !== $ticket_ids ) {
322
+ $ticket_ids = array_map( 'absint', explode( ',', $ticket_ids ) );
323
+ $ticket_ids = array_filter(
324
+ $ticket_ids,
325
+ static function ( $ticket_id ) {
326
+ return get_post_type( $ticket_id ) === Commerce\Ticket::POSTTYPE;
327
+ }
328
+ );
329
+ $tickets = array_map( [ tribe( Commerce\Ticket::class ), 'get_ticket' ], $ticket_ids );
330
+ }
331
+
332
+ $tickets = array_filter(
333
+ $tickets,
334
+ static function ( $ticket ) {
335
+ return Module::class === $ticket->provider_class;
336
+ }
337
+ );
338
+
339
+ $event_data = [];
340
+ $tickets_data = [];
341
+ $thousands_sep = tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'thousands_sep' );
342
+
343
+ foreach ( $tickets as $ticket ) {
344
+ $quantities = tribe( Commerce\Ticket::class )->get_status_quantity( $ticket->ID );
345
+ $total_by_status = [];
346
+ foreach ( $quantities as $status_slug => $status_count ) {
347
+ if ( ! isset( $event_data['qty_by_status'][ $status_slug ] ) ) {
348
+ $event_data['qty_by_status'][ $status_slug ] = 0;
349
+ }
350
+ if ( ! isset( $event_data['total_by_status'][ $status_slug ] ) ) {
351
+ $event_data['total_by_status'][ $status_slug ] = [];
352
+ }
353
+
354
+ $event_data['total_by_status'][ $status_slug ][] = $total_by_status[ $status_slug ] = str_replace( $thousands_sep, '', Price::sub_total( $ticket->price, $status_count ) );
355
+
356
+ $event_data['qty_by_status'][ $status_slug ] += (int) $status_count;
357
+ }
358
+ $tickets_data[ $ticket->ID ] = [
359
+ 'total_by_status' => $total_by_status,
360
+ 'qty_by_status' => $quantities,
361
+ ];
362
+ }
363
+
364
+ $event_data['total_by_status'] = array_map(
365
+ static function ( $sub_totals ) use ( $thousands_sep ) {
366
+ return str_replace( $thousands_sep, '', Price::total( $sub_totals ) );
367
+ },
368
+ $event_data['total_by_status']
369
+ );
370
+
371
+
372
+ $this->template_vars = [
373
+ 'title' => $this->get_title(),
374
+ 'orders_table' => tribe( Commerce\Admin_Tables\Orders::class ),
375
+ 'post' => $post,
376
+ 'post_id' => $post_id,
377
+ 'post_type_object' => $post_type_object,
378
+ 'post_singular_label' => $post_singular_label,
379
+ 'tickets' => $tickets,
380
+ 'tickets_data' => $tickets_data,
381
+ 'event_data' => $event_data,
382
+ 'tooltip' => tribe( 'tooltip.view' ),
383
+ 'thousands_sep' => $thousands_sep,
384
+ ];
385
+
386
+ return $this->template_vars;
387
+ }
388
+
389
+ /**
390
+ * Filters the Order Link to Ticket Orders in the ticket editor.
391
+ *
392
+ * @since 5.2.0
393
+ *
394
+ * @param string $url Url for the order page for ticketed event/post.
395
+ * @param int $post_id The post ID for the current event/post.
396
+ *
397
+ * @return string
398
+ */
399
+ public function filter_editor_orders_link( $url, $post_id ) {
400
+ $provider = \Tribe__Tickets__Tickets::get_event_ticket_provider( $post_id );
401
+
402
+ if ( Module::class !== $provider ) {
403
+ return $url;
404
+ }
405
+
406
+ return add_query_arg( [ 'page' => static::get_page_slug() ], $url );
407
+ }
408
+ }
src/Tickets/Commerce/Reports/Report_Abstract.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace TEC\Tickets\Commerce\Reports;
4
+
5
+ use Tribe__Template;
6
+
7
+ /**
8
+ * Class Report_Abstract
9
+ *
10
+ * @since 5.2.0
11
+ *
12
+ * @package TEC\Tickets\Commerce\Reports
13
+ */
14
+ abstract class Report_Abstract {
15
+ /**
16
+ * The Shortcode Slug inside of WordPress.
17
+ *
18
+ * @since 5.2.0
19
+ *
20
+ * @return string
21
+ */
22
+ public static function get_page_wp_slug() {
23
+ return 'tec-tickets-' . static::get_page_slug();
24
+ }
25
+
26
+ /**
27
+ * Fetches the Page slug
28
+ *
29
+ * @since 5.2.0
30
+ *
31
+ *
32
+ * @return string
33
+ */
34
+ public static function get_page_slug() {
35
+ return static::$page_slug;
36
+ }
37
+
38
+ /**
39
+ * Set of template variable used to generate this shortcode.
40
+ *
41
+ * @since 5.2.0
42
+ *
43
+ * @var array
44
+ */
45
+ protected $template_vars = [];
46
+
47
+ /**
48
+ * Stores the instance of the template engine that we will use for rendering the page.
49
+ *
50
+ * @since 5.2.0
51
+ *
52
+ * @var Tribe__Template
53
+ */
54
+ protected $template;
55
+
56
+ /**
57
+ * Gets the template instance used to setup the rendering of the page.
58
+ *
59
+ * @since 5.2.0
60
+ *
61
+ * @return Tribe__Template
62
+ */
63
+ public function get_template() {
64
+ if ( empty( $this->template ) ) {
65
+ $this->template = new Tribe__Template();
66
+ $this->template->set_template_origin( \Tribe__Tickets__Main::instance() );
67
+ $this->template->set_template_folder( 'src/admin-views/commerce/reports' );
68
+ $this->template->set_template_context_extract( true );
69
+ }
70
+
71
+ return $this->template;
72
+ }
73
+
74
+ /**
75
+ * Method used to save the template vars for this instance of shortcode.
76
+ *
77
+ * @since 5.2.0
78
+ *
79
+ * @return void
80
+ */
81
+ abstract public function setup_template_vars();
82
+
83
+ /**
84
+ * Calls the template vars setup and returns after filtering.
85
+ *
86
+ * @since 5.2.0
87
+ *
88
+ * @return array
89
+ */
90
+ public function get_template_vars() {
91
+ $this->setup_template_vars();
92
+
93
+ return (array) $this->filter_template_vars( $this->template_vars );
94
+ }
95
+
96
+ /**
97
+ * Enables filtering of the template variables.
98
+ *
99
+ * @since 5.2.0
100
+ *
101
+ * @param array $template_vars Which set of variables we are passing to the filters.
102
+ *
103
+ * @return array
104
+ */
105
+ public function filter_template_vars( array $template_vars = [] ) {
106
+ /**
107
+ * Applies a filter to template vars for this shortcode.
108
+ *
109
+ * @since 5.2.0
110
+ *
111
+ * @param array $template_vars Current set of callbacks for arguments.
112
+ * @param static $instance Which instance of shortcode we are dealing with.
113
+ */
114
+ $template_vars = apply_filters( 'tec_tickets_commerce_reports_template_vars', $template_vars, $this );
115
+
116
+ $page_slug = static::get_page_slug();
117
+
118
+ /**
119
+ * Applies a filter to template vars for this shortcode, using ID and gateway.
120
+ *
121
+ * @since 5.2.0
122
+ *
123
+ * @param array $template_vars Current set of callbacks for arguments.
124
+ * @param static $instance Which instance of shortcode we are dealing with.
125
+ */
126
+ return (array) apply_filters( "tec_tickets_commerce_reports_{$page_slug}_template_vars", $template_vars, $this );
127
+ }
128
+
129
+ }
src/Tickets/Commerce/Reports/Ticket.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
-
3
- namespace TEC\Tickets\Commerce\Reports;
4
-
5
- /**
6
- * Class Ticket Report management.
7
- *
8
- * @since 5.1.9
9
- *
10
- * @package TEC\Tickets\Commerce\Reports
11
- */
12
- class Ticket {
13
-
14
-
15
- /**
16
- * Links to the sales report for this product.
17
- *
18
- * @since 5.1.9
19
- *
20
- * @param $event_id
21
- * @param $ticket_id
22
- *
23
- * @return string
24
- */
25
- public function get_link( $event_id, $ticket_id ) {
26
- if ( empty( $ticket_id ) ) {
27
- return '';
28
- }
29
-
30
- $query = array(
31
- 'page' => 'tpp-orders',
32
- 'product_ids' => $ticket_id,
33
- 'post_id' => $event_id,
34
- );
35
-
36
- $report_url = add_query_arg( $query, admin_url( 'admin.php' ) );
37
-
38
- return '<span><a href="' . esc_url( $report_url ) . '">' . esc_html__( 'Report', 'event-tickets' ) . '</a></span>';
39
- }
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Tickets/Commerce/Repositories/Attendees_Repository.php CHANGED
@@ -50,25 +50,36 @@ class Attendees_Repository extends Tribe__Repository {
50
  $this->create_args['post_status'] = 'publish';
51
  $this->create_args['post_type'] = Attendee::POSTTYPE;
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  // Add event specific aliases.
54
  $this->update_fields_aliases = array_merge(
55
  $this->update_fields_aliases,
56
- [
57
- 'order_id' => 'post_parent',
58
- 'ticket_id' => Attendee::$ticket_relation_meta_key,
59
- 'event_id' => Attendee::$event_relation_meta_key,
60
- 'security_code' => Attendee::$security_code_meta_key,
61
- 'opt_out' => Attendee::$optout_meta_key,
62
- 'checked_in' => Attendee::$checked_in_meta_key,
63
- 'price_paid' => Attendee::$price_paid_meta_key,
64
- 'currency' => Attendee::$currency_meta_key,
65
- 'first_name' => Attendee::$first_name_meta_key,
66
- 'last_name' => Attendee::$last_name_meta_key,
67
- 'email' => Attendee::$email_meta_key,
68
- 'is_deleted_ticket' => Attendee::$deleted_ticket_meta_key,
69
- 'ticket_sent' => Attendee::$ticket_sent_meta_key,
70
- 'is_subscribed' => Attendee::$subscribed_meta_key,
71
- ]
72
  );
73
  }
74
 
50
  $this->create_args['post_status'] = 'publish';
51
  $this->create_args['post_type'] = Attendee::POSTTYPE;
52
 
53
+ $aliases = [
54
+ 'order_id' => 'post_parent',
55
+ 'ticket_id' => Attendee::$ticket_relation_meta_key,
56
+ 'event_id' => Attendee::$event_relation_meta_key,
57
+ 'user_id' => Attendee::$user_relation_meta_key,
58
+ 'security_code' => Attendee::$security_code_meta_key,
59
+ 'opt_out' => Attendee::$optout_meta_key,
60
+ 'checked_in' => Attendee::$checked_in_meta_key,
61
+ 'price_paid' => Attendee::$price_paid_meta_key,
62
+ 'currency' => Attendee::$currency_meta_key,
63
+ 'full_name' => Attendee::$full_name_meta_key,
64
+ 'email' => Attendee::$email_meta_key,
65
+ 'is_deleted_ticket' => Attendee::$deleted_ticket_meta_key,
66
+ 'ticket_sent' => Attendee::$ticket_sent_meta_key,
67
+ 'is_subscribed' => Attendee::$subscribed_meta_key,
68
+ ];
69
+
70
+ /**
71
+ * Allows for filtering the repository aliases.
72
+ *
73
+ * @since 5.2.0
74
+ *
75
+ * @param array $aliases Repository aliases.
76
+ */
77
+ $aliases = apply_filters( 'tec_tickets_commerce_attendees_repository_aliases', $aliases );
78
+
79
  // Add event specific aliases.
80
  $this->update_fields_aliases = array_merge(
81
  $this->update_fields_aliases,
82
+ $aliases
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  );
84
  }
85
 
src/Tickets/Commerce/Repositories/Order_Repository.php CHANGED
@@ -56,13 +56,15 @@ class Order_Repository extends Tribe__Repository {
56
  [
57
  'gateway' => Order::$gateway_meta_key,
58
  'gateway_order_id' => Order::$gateway_order_id_meta_key,
59
- 'cart_items' => Order::$cart_items_meta_key,
60
  'total_value' => Order::$total_value_meta_key,
61
  'currency' => Order::$currency_meta_key,
 
62
  'purchaser_full_name' => Order::$purchaser_full_name_meta_key,
63
  'purchaser_first_name' => Order::$purchaser_first_name_meta_key,
64
  'purchaser_last_name' => Order::$purchaser_last_name_meta_key,
65
  'purchaser_email' => Order::$purchaser_email_meta_key,
 
66
  ]
67
  );
68
 
@@ -83,6 +85,7 @@ class Order_Repository extends Tribe__Repository {
83
  $this->add_simple_meta_schema_entry( 'purchaser_first_name', Order::$purchaser_first_name_meta_key, 'meta_equals' );
84
  $this->add_simple_meta_schema_entry( 'purchaser_last_name', Order::$purchaser_last_name_meta_key, 'meta_equals' );
85
  $this->add_simple_meta_schema_entry( 'purchaser_email', Order::$purchaser_email_meta_key, 'meta_equals' );
 
86
  }
87
 
88
  /**
@@ -264,9 +267,9 @@ class Order_Repository extends Tribe__Repository {
264
  *
265
  * @return array
266
  */
267
- protected function filter_cart_items_input( $postarr, $post_id = null ) {
268
  $meta = Arr::get( $postarr, 'meta_input', [] );
269
- $items = Arr::get( $meta, Order::$cart_items_meta_key, [] );
270
 
271
  if ( ! empty( $items ) ) {
272
  $ticket_ids = array_unique( array_filter( array_values( wp_list_pluck( $items, 'ticket_id' ) ) ) );
@@ -353,8 +356,8 @@ class Order_Repository extends Tribe__Repository {
353
  $postarr = $this->filter_gateway_payload( $postarr, $post_id );
354
  }
355
 
356
- if ( ! empty( $postarr['meta_input'][ Order::$cart_items_meta_key ] ) ) {
357
- $postarr = $this->filter_cart_items_input( $postarr, $post_id );
358
  }
359
 
360
  return $postarr;
56
  [
57
  'gateway' => Order::$gateway_meta_key,
58
  'gateway_order_id' => Order::$gateway_order_id_meta_key,
59
+ 'items' => Order::$items_meta_key,
60
  'total_value' => Order::$total_value_meta_key,
61
  'currency' => Order::$currency_meta_key,
62
+ 'purchaser_user_id' => Order::$purchaser_user_id_meta_key,
63
  'purchaser_full_name' => Order::$purchaser_full_name_meta_key,
64
  'purchaser_first_name' => Order::$purchaser_first_name_meta_key,
65
  'purchaser_last_name' => Order::$purchaser_last_name_meta_key,
66
  'purchaser_email' => Order::$purchaser_email_meta_key,
67
+ 'hash' => Order::$hash_meta_key,
68
  ]
69
  );
70
 
85
  $this->add_simple_meta_schema_entry( 'purchaser_first_name', Order::$purchaser_first_name_meta_key, 'meta_equals' );
86
  $this->add_simple_meta_schema_entry( 'purchaser_last_name', Order::$purchaser_last_name_meta_key, 'meta_equals' );
87
  $this->add_simple_meta_schema_entry( 'purchaser_email', Order::$purchaser_email_meta_key, 'meta_equals' );
88
+ $this->add_simple_meta_schema_entry( 'hash', Order::$hash_meta_key, 'meta_equals' );
89
  }
90
 
91
  /**
267
  *
268
  * @return array
269
  */
270
+ protected function filter_items_input( $postarr, $post_id = null ) {
271
  $meta = Arr::get( $postarr, 'meta_input', [] );
272
+ $items = Arr::get( $meta, Order::$items_meta_key, [] );
273
 
274
  if ( ! empty( $items ) ) {
275
  $ticket_ids = array_unique( array_filter( array_values( wp_list_pluck( $items, 'ticket_id' ) ) ) );
356
  $postarr = $this->filter_gateway_payload( $postarr, $post_id );
357
  }
358
 
359
+ if ( ! empty( $postarr['meta_input'][ Order::$items_meta_key ] ) ) {
360
+ $postarr = $this->filter_items_input( $postarr, $post_id );
361
  }
362
 
363
  return $postarr;
src/Tickets/Commerce/Settings.php CHANGED
@@ -12,7 +12,10 @@ use TEC\Tickets\Commerce\Gateways\Abstract_Gateway;
12
  use TEC\Tickets\Commerce\Gateways\Manager;
13
  use TEC\Tickets\Commerce\Status\Completed;
14
  use TEC\Tickets\Commerce\Status\Pending;
 
 
15
  use Tribe__Field_Conditional;
 
16
 
17
  /**
18
  * The Tickets Commerce settings.
@@ -24,15 +27,7 @@ use Tribe__Field_Conditional;
24
  * @package Tribe\Tickets\Commerce\Tickets_Commerce
25
  */
26
  class Settings extends Abstract_Settings {
27
-
28
- /**
29
- * The option key for enable.
30
- *
31
- * @since 5.1.6
32
- *
33
- * @var string
34
- */
35
- public static $option_enable = 'tickets-commerce-enable';
36
 
37
  /**
38
  * The option key for sandbox.
@@ -107,77 +102,50 @@ class Settings extends Abstract_Settings {
107
  public static $option_confirmation_email_subject = 'tickets-commerce-confirmation-email-subject';
108
 
109
  /**
110
- * Create the Tickets Commerce Payments Settings Tab.
111
  *
112
- * @since 5.1.9
113
  */
114
- public function register_tab() {
115
- $tab_settings = [
116
- 'priority' => 25,
117
- 'fields' => $this->get_settings(),
118
- 'show_save' => true,
119
- ];
120
-
121
- new \Tribe__Settings_Tab( 'payments', esc_html__( 'Payments', 'event-tickets' ), $tab_settings );
122
  }
123
 
124
  /**
125
- * Gets the top level settings for Tickets Commerce.
126
  *
127
- * @since 5.1.9
128
  *
 
129
  *
130
- * @return array[]
131
  */
132
- public function get_top_level_settings() {
133
-
134
- $plus_link = sprintf(
135
- '<a href="https://evnt.is/19zl" target="_blank" rel="noopener noreferrer">%s</a>',
136
- esc_html__( 'Event Tickets Plus', 'event-tickets' )
137
- );
138
- $plus_link_2 = sprintf(
139
- '<a href="https://evnt.is/19zl" target="_blank" rel="noopener noreferrer">%s</a>',
140
- esc_html__( 'Check it out!', 'event-tickets' )
141
- );
142
- $plus_message = sprintf(
143
- // Translators: %1$s: The Event Tickets Plus link, %2$s: The word "ticket" in lowercase, %3$s: The "Check it out!" link.
144
- esc_html_x( 'Tickets Commerce is a light implementation of a commerce gateway using PayPal and simplified stock handling. If you need more advanced features, take a look at %1$s. In addition to integrating with your favorite ecommerce provider, Event Tickets Plus includes options to collect custom information for attendees, check users in via QR codes, and share stock between %2$s. %3$s', 'about Tickets Commerce', 'event-tickets' ),
145
- $plus_link,
146
- esc_html( tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_about_tribe_commerce' ) ),
147
- $plus_link_2
 
 
 
 
148
  );
149
 
150
- // @todo Fill this out and make it check if PayPal Legacy was previously active.
151
- $is_tickets_commerce_enabled = tec_tickets_commerce_is_enabled();
152
 
153
- $top_level_settings = [
154
- 'tribe-form-content-start' => [
155
- 'type' => 'html',
156
- 'html' => '<div class="tribe-settings-form-wrap">',
157
- ],
158
- 'tickets-commerce-header' => [
159
- 'type' => 'html',
160
- 'html' => '<div class="tec-tickets__admin-settings-tickets-commerce-toggle-wrapper"><label class="tec-tickets__admin-settings-tickets-commerce-toggle"><input type="checkbox" name="' . static::$option_enable . '" value="' . $is_tickets_commerce_enabled . '" ' . checked( $is_tickets_commerce_enabled, true, false ) . ' id="tickets-commerce-enable-input" class="tec-tickets__admin-settings-tickets-commerce-toggle-checkbox tribe-dependency tribe-dependency-verified"><span class="tec-tickets__admin-settings-tickets-commerce-toggle-switch"></span><span class="tec-tickets__admin-settings-tickets-commerce-toggle-label">' . esc_html__( 'Enable Tickets Commerce', 'event-tickets' ) . '</span></label></div>',
161
-
162
- ],
163
- 'tickets-commerce-description' => [
164
- 'type' => 'html',
165
- 'html' => '<div class="tec-tickets__admin-settings-tickets-commerce-description">' . $plus_message . '</div>',
166
- ],
167
- static::$option_enable => [
168
- 'type' => 'hidden',
169
- 'validation_type' => 'boolean',
170
- ],
171
- ];
172
-
173
- /**
174
- * Hook to modify the top level settings for Tickets Commerce.
175
- *
176
- * @since 5.1.9
177
- *
178
- * @param array[] $top_level_settings Top level settings.
179
- */
180
- return apply_filters( 'tec_tickets_commerce_settings_top_level', $top_level_settings );
181
  }
182
 
183
  /**
@@ -217,8 +185,8 @@ class Settings extends Abstract_Settings {
217
 
218
  $settings = [
219
  'tickets-commerce-general-settings-heading' => [
220
- 'type' => 'html',
221
- 'html' => '<h3 class="my-awesome-class tribe-dependent" data-depends="#' . static::$option_enable . '-input" data-condition-is-checked>' . __( 'Tickets Commerce Settings', 'event-tickets' ) . '</h3><div class="clear"></div>',
222
  ],
223
  static::$option_sandbox => [
224
  'type' => 'checkbox_bool',
@@ -240,7 +208,7 @@ class Settings extends Abstract_Settings {
240
  'label' => esc_html__( 'Stock Handling', 'event-tickets' ),
241
  'tooltip' => esc_html(
242
  sprintf(
243
- // Translators: %s: The word "ticket" in lowercase.
244
  _x( 'When a customer purchases a %s, the payment gateway might flag the order as Pending. The order will be Complete once payment is confirmed by the payment gateway.', 'tickets fields settings paypal stock handling', 'event-tickets' ),
245
  tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_stock_handling' )
246
  )
@@ -248,15 +216,15 @@ class Settings extends Abstract_Settings {
248
  'default' => Pending::SLUG,
249
  'validation_type' => 'options',
250
  'options' => [
251
- Pending::SLUG => sprintf(
252
- // Translators: %1$s: The word "ticket" in lowercase. %2$s: `<strong>` opening tag. %3$s: `</strong>` closing tag.
253
  esc_html__( 'Decrease available %1$s stock as soon as a %2$sPending%3$s order is created.', 'event-tickets' ),
254
  tribe_get_ticket_label_singular_lowercase( 'stock_handling' ),
255
  '<strong>',
256
  '</strong>'
257
  ),
258
  Completed::SLUG => sprintf(
259
- // Translators: %1$s: The word "ticket" in lowercase. %2$s: `<strong>` opening tag. %3$s: `</strong>` closing tag.
260
  esc_html__( 'Only decrease available %1$s stock if an order is confirmed as %2$sCompleted%3$s by the payment gateway.', 'event-tickets' ),
261
  tribe_get_ticket_label_singular_lowercase( 'stock_handling' ),
262
  '<strong>',
@@ -270,7 +238,7 @@ class Settings extends Abstract_Settings {
270
  'label' => esc_html__( 'Checkout page', 'event-tickets' ),
271
  'tooltip' => esc_html(
272
  sprintf(
273
- // Translators: %s: The [shortcode] for the success page.
274
  __( 'This is the page where customers go to complete their purchase. Use the %s shortcode to display the checkout experience in the page content.', 'event-tickets' ),
275
  "[$checkout_shortcode]"
276
  )
@@ -285,7 +253,7 @@ class Settings extends Abstract_Settings {
285
  'label' => esc_html__( 'Success page', 'event-tickets' ),
286
  'tooltip' => esc_html(
287
  sprintf(
288
- // Translators: %s: The [shortcode] for the success page.
289
  __( 'After a successful order, users will be redirected to this page. Use the %s shortcode to display the order confirmation to the user in the page content.', 'event-tickets' ),
290
  "[$success_shortcode]"
291
  )
@@ -300,7 +268,7 @@ class Settings extends Abstract_Settings {
300
  'label' => esc_html__( 'Confirmation email sender address', 'event-tickets' ),
301
  'tooltip' => esc_html(
302
  sprintf(
303
- // Translators: %s: The word "tickets" in lowercase.
304
  _x( 'Email address that %s customers will receive confirmation from. Leave empty to use the default WordPress site email address.', 'tickets fields settings confirmation email', 'event-tickets' ),
305
  tribe_get_ticket_label_plural_lowercase( 'tickets_fields_settings_paypal_confirmation_email' )
306
  )
@@ -315,7 +283,7 @@ class Settings extends Abstract_Settings {
315
  'label' => esc_html__( 'Confirmation email sender name', 'event-tickets' ),
316
  'tooltip' => esc_html(
317
  sprintf(
318
- // Translators: %s: The word "ticket" in lowercase.
319
  _x( 'Sender name of the confirmation email sent to customers when confirming a %s purchase.', 'tickets fields settings paypal email sender', 'event-tickets' ),
320
  tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_email_sender' )
321
  )
@@ -330,7 +298,7 @@ class Settings extends Abstract_Settings {
330
  'label' => esc_html__( 'Confirmation email subject', 'event-tickets' ),
331
  'tooltip' => esc_html(
332
  sprintf(
333
- // Translators: %s: The word "ticket" in lowercase.
334
  _x( 'Subject of the confirmation email sent to customers when confirming a %s purchase.', 'tickets fields settings paypal email subject', 'event-tickets' ),
335
  tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_email_subject' )
336
  )
@@ -338,7 +306,7 @@ class Settings extends Abstract_Settings {
338
  'size' => 'large',
339
  'default' => esc_html(
340
  sprintf(
341
- // Translators: %s: The word "tickets" in lowercase.
342
  _x( 'You have %s!', 'tickets fields settings paypal email subject', 'event-tickets' ),
343
  tribe_get_ticket_label_plural_lowercase( 'tickets_fields_settings_paypal_email_subject' )
344
  )
@@ -359,7 +327,8 @@ class Settings extends Abstract_Settings {
359
  */
360
  $settings = apply_filters( 'tribe_tickets_commerce_settings', $settings );
361
 
362
- return array_merge( $this->get_top_level_settings(), $this->apply_commerce_enabled_conditional( $settings ) );
 
363
  }
364
 
365
  /**
@@ -372,9 +341,9 @@ class Settings extends Abstract_Settings {
372
  * @return array[]
373
  */
374
  public function apply_commerce_enabled_conditional( $settings ) {
375
- $validate_if = new Tribe__Field_Conditional( static::$option_enable, 'tribe_is_truthy' );
376
  $fieldset_attributes = [
377
- 'data-depends' => '#' . static::$option_enable . '-input',
378
  'data-condition-is-checked' => '',
379
  ];
380
 
12
  use TEC\Tickets\Commerce\Gateways\Manager;
13
  use TEC\Tickets\Commerce\Status\Completed;
14
  use TEC\Tickets\Commerce\Status\Pending;
15
+ use TEC\Tickets\Commerce\Traits\Has_Mode;
16
+ use TEC\Tickets\Settings as Tickets_Settings;
17
  use Tribe__Field_Conditional;
18
+ use WP_Admin_Bar;
19
 
20
  /**
21
  * The Tickets Commerce settings.
27
  * @package Tribe\Tickets\Commerce\Tickets_Commerce
28
  */
29
  class Settings extends Abstract_Settings {
30
+ use Has_Mode;
 
 
 
 
 
 
 
 
31
 
32
  /**
33
  * The option key for sandbox.
102
  public static $option_confirmation_email_subject = 'tickets-commerce-confirmation-email-subject';
103
 
104
  /**
105
+ * Settings constructor.
106
  *
107
+ * @since 5.2.0
108
  */
109
+ public function __construct() {
110
+ // Configure which mode we are in.
111
+ $this->set_mode( tec_tickets_commerce_is_sandbox_mode() ? 'sandbox' : 'live' );
 
 
 
 
 
112
  }
113
 
114
  /**
115
+ * Display admin bar when using the Test Mode for payments.
116
  *
117
+ * @since 5.2.0
118
  *
119
+ * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference.
120
  *
121
+ * @return bool
122
  */
123
+ public function include_admin_bar_test_mode( WP_Admin_Bar $wp_admin_bar ) {
124
+ if (
125
+ ! $this->is_sandbox() ||
126
+ ! current_user_can( 'manage_options' )
127
+ ) {
128
+ return false;
129
+ }
130
+ $url = \Tribe__Settings::instance()->get_url( [ 'tab' => 'payments' ] );
131
+
132
+ // Add the main site admin menu item.
133
+ $wp_admin_bar->add_menu(
134
+ [
135
+ 'id' => 'tec-tickets-commerce-sandbox-notice',
136
+ 'href' => $url,
137
+ 'parent' => 'top-secondary',
138
+ 'title' => __( 'Tickets Commerce Test Mode Active', 'event-tickets' ),
139
+ 'meta' => [
140
+ 'class' => 'tec-tickets-commerce-sandbox-mode-active',
141
+ ],
142
+ ]
143
  );
144
 
145
+ // Force this asset to load whn we add this to the menu.
146
+ tribe_asset_enqueue( 'tec-tickets-commerce-gateway-paypal-global-admin-styles' );
147
 
148
+ return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
 
151
  /**
185
 
186
  $settings = [
187
  'tickets-commerce-general-settings-heading' => [
188
+ 'type' => 'html',
189
+ 'html' => '<h3 class="tribe-dependent" data-depends="#' . Tickets_Settings::$tickets_commerce_enabled . '-input" data-condition-is-checked>' . __( 'Tickets Commerce Settings', 'event-tickets' ) . '</h3><div class="clear"></div>',
190
  ],
191
  static::$option_sandbox => [
192
  'type' => 'checkbox_bool',
208
  'label' => esc_html__( 'Stock Handling', 'event-tickets' ),
209
  'tooltip' => esc_html(
210
  sprintf(
211
+ // Translators: %s: The word "ticket" in lowercase.
212
  _x( 'When a customer purchases a %s, the payment gateway might flag the order as Pending. The order will be Complete once payment is confirmed by the payment gateway.', 'tickets fields settings paypal stock handling', 'event-tickets' ),
213
  tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_stock_handling' )
214
  )
216
  'default' => Pending::SLUG,
217
  'validation_type' => 'options',
218
  'options' => [
219
+ Pending::SLUG => sprintf(
220
+ // Translators: %1$s: The word "ticket" in lowercase. %2$s: `<strong>` opening tag. %3$s: `</strong>` closing tag.
221
  esc_html__( 'Decrease available %1$s stock as soon as a %2$sPending%3$s order is created.', 'event-tickets' ),
222
  tribe_get_ticket_label_singular_lowercase( 'stock_handling' ),
223
  '<strong>',
224
  '</strong>'
225
  ),
226
  Completed::SLUG => sprintf(
227
+ // Translators: %1$s: The word "ticket" in lowercase. %2$s: `<strong>` opening tag. %3$s: `</strong>` closing tag.
228
  esc_html__( 'Only decrease available %1$s stock if an order is confirmed as %2$sCompleted%3$s by the payment gateway.', 'event-tickets' ),
229
  tribe_get_ticket_label_singular_lowercase( 'stock_handling' ),
230
  '<strong>',
238
  'label' => esc_html__( 'Checkout page', 'event-tickets' ),
239
  'tooltip' => esc_html(
240
  sprintf(
241
+ // Translators: %s: The [shortcode] for the success page.
242
  __( 'This is the page where customers go to complete their purchase. Use the %s shortcode to display the checkout experience in the page content.', 'event-tickets' ),
243
  "[$checkout_shortcode]"
244
  )
253
  'label' => esc_html__( 'Success page', 'event-tickets' ),
254
  'tooltip' => esc_html(
255
  sprintf(
256
+ // Translators: %s: The [shortcode] for the success page.
257
  __( 'After a successful order, users will be redirected to this page. Use the %s shortcode to display the order confirmation to the user in the page content.', 'event-tickets' ),
258
  "[$success_shortcode]"
259
  )
268
  'label' => esc_html__( 'Confirmation email sender address', 'event-tickets' ),
269
  'tooltip' => esc_html(
270
  sprintf(
271
+ // Translators: %s: The word "tickets" in lowercase.
272
  _x( 'Email address that %s customers will receive confirmation from. Leave empty to use the default WordPress site email address.', 'tickets fields settings confirmation email', 'event-tickets' ),
273
  tribe_get_ticket_label_plural_lowercase( 'tickets_fields_settings_paypal_confirmation_email' )
274
  )
283
  'label' => esc_html__( 'Confirmation email sender name', 'event-tickets' ),
284
  'tooltip' => esc_html(
285
  sprintf(
286
+ // Translators: %s: The word "ticket" in lowercase.
287
  _x( 'Sender name of the confirmation email sent to customers when confirming a %s purchase.', 'tickets fields settings paypal email sender', 'event-tickets' ),
288
  tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_email_sender' )
289
  )
298
  'label' => esc_html__( 'Confirmation email subject', 'event-tickets' ),
299
  'tooltip' => esc_html(
300
  sprintf(
301
+ // Translators: %s: The word "ticket" in lowercase.
302
  _x( 'Subject of the confirmation email sent to customers when confirming a %s purchase.', 'tickets fields settings paypal email subject', 'event-tickets' ),
303
  tribe_get_ticket_label_singular_lowercase( 'tickets_fields_settings_paypal_email_subject' )
304
  )
306
  'size' => 'large',
307
  'default' => esc_html(
308
  sprintf(
309
+ // Translators: %s: The word "tickets" in lowercase.
310
  _x( 'You have %s!', 'tickets fields settings paypal email subject', 'event-tickets' ),
311
  tribe_get_ticket_label_plural_lowercase( 'tickets_fields_settings_paypal_email_subject' )
312
  )
327
  */
328
  $settings = apply_filters( 'tribe_tickets_commerce_settings', $settings );
329
 
330
+
331
+ return array_merge( tribe( Payments_Tab::class )->get_top_level_settings(), $this->apply_commerce_enabled_conditional( $settings ) );
332
  }
333
 
334
  /**
341
  * @return array[]
342
  */
343
  public function apply_commerce_enabled_conditional( $settings ) {
344
+ $validate_if = new Tribe__Field_Conditional( Tickets_Settings::$tickets_commerce_enabled, 'tribe_is_truthy' );
345
  $fieldset_attributes = [
346
+ 'data-depends' => '#' . Tickets_Settings::$tickets_commerce_enabled . '-input',
347
  'data-condition-is-checked' => '',
348
  ];
349
 
src/Tickets/Commerce/Shortcodes/Checkout_Shortcode.php CHANGED
@@ -46,17 +46,18 @@ class Checkout_Shortcode extends Shortcode_Abstract {
46
  $sub_totals = array_filter( wp_list_pluck( $items, 'sub_total' ) );
47
 
48
  $args = [
49
- 'provider_id' => Module::class,
50
- 'provider' => tribe( Module::class ),
51
- 'items' => $items,
52
- 'sections' => $sections,
53
- 'total_value' => tribe_format_currency( Price::total( $sub_totals ) ),
54
- 'must_login' => ! is_user_logged_in() && tribe( Module::class )->login_required(),
55
- 'login_url' => tribe( Checkout::class )->get_login_url(),
56
- 'registration_url' => tribe( Checkout::class )->get_registration_url(),
57
- 'is_tec_active' => defined( 'TRIBE_EVENTS_FILE' ) && class_exists( 'Tribe__Events__Main' ),
58
- 'gateways' => tribe( Manager::class )->get_gateways(),
59
- 'gateways_active' => $this->get_gateways_active(),
 
60
  ];
61
 
62
  $this->template_vars = $args;
@@ -77,12 +78,7 @@ class Checkout_Shortcode extends Shortcode_Abstract {
77
  // Add the rendering attributes into global context.
78
  $this->get_template()->add_template_globals( $args );
79
 
80
- $html = $this->get_template()->template( 'checkout', $args, false );
81
-
82
- // Enqueue assets.
83
- tribe_asset_enqueue_group( 'tribe-tickets-commerce-checkout' );
84
-
85
- return $html;
86
  }
87
 
88
  /**
@@ -94,14 +90,38 @@ class Checkout_Shortcode extends Shortcode_Abstract {
94
  */
95
  public function get_gateways_active() {
96
  $gateways = tribe( Manager::class )->get_gateways();
97
- $gateways_active = 0;
 
 
98
 
99
- // Get all of the gateways.
100
- foreach ( $gateways as $gateway_key => $gateway ) {
101
- $gateways_active += (int) $gateway->is_active();
102
- }
103
 
104
- return $gateways_active;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  }
106
 
107
  }
46
  $sub_totals = array_filter( wp_list_pluck( $items, 'sub_total' ) );
47
 
48
  $args = [
49
+ 'provider_id' => Module::class,
50
+ 'provider' => tribe( Module::class ),
51
+ 'items' => $items,
52
+ 'sections' => $sections,
53
+ 'total_value' => tribe_format_currency( Price::total( $sub_totals ) ),
54
+ 'must_login' => ! is_user_logged_in() && tribe( Module::class )->login_required(),
55
+ 'login_url' => tribe( Checkout::class )->get_login_url(),
56
+ 'registration_url' => tribe( Checkout::class )->get_registration_url(),
57
+ 'is_tec_active' => defined( 'TRIBE_EVENTS_FILE' ) && class_exists( 'Tribe__Events__Main' ),
58
+ 'gateways' => tribe( Manager::class )->get_gateways(),
59
+ 'gateways_active' => $this->get_gateways_active(),
60
+ 'gateways_connected' => $this->get_gateways_connected(),
61
  ];
62
 
63
  $this->template_vars = $args;
78
  // Add the rendering attributes into global context.
79
  $this->get_template()->add_template_globals( $args );
80
 
81
+ return $this->get_template()->template( 'checkout', $args, false );
 
 
 
 
 
82
  }
83
 
84
  /**
90
  */
91
  public function get_gateways_active() {
92
  $gateways = tribe( Manager::class )->get_gateways();
93
+ $gateways_active = array_filter( array_map( static function ( $gateway ) {
94
+ return $gateway::is_active() && $gateway::should_show() ? $gateway : null;
95
+ }, $gateways ) );
96
 
97
+ return count( $gateways_active );
98
+ }
 
 
99
 
100
+ /**
101
+ * Get the number of connected gateways.
102
+ *
103
+ * @since 5.2.0
104
+ *
105
+ * @return int The number of connected gateways.
106
+ */
107
+ public function get_gateways_connected() {
108
+ $gateways = tribe( Manager::class )->get_gateways();
109
+
110
+ $gateways_connected = array_filter( array_map( static function ( $gateway ) {
111
+ return $gateway::is_connected() && $gateway::should_show() ? $gateway : null;
112
+ }, $gateways ) );
113
+
114
+ return count( $gateways_connected );
115
+ }
116
+
117
+ /**
118
+ * Enqueue the assets related to this shortcode, static method to avoid having to generate a new instance.
119
+ *
120
+ * @since 5.2.0
121
+ */
122
+ public static function enqueue_assets() {
123
+ // Enqueue assets.
124
+ tribe_asset_enqueue_group( 'tribe-tickets-commerce-checkout' );
125
  }
126
 
127
  }
src/Tickets/Commerce/Shortcodes/Success_Shortcode.php CHANGED
@@ -9,6 +9,7 @@
9
  namespace TEC\Tickets\Commerce\Shortcodes;
10
 
11
  use TEC\Tickets\Commerce\Module;
 
12
  use TEC\Tickets\Commerce\Status\Completed;
13
  use TEC\Tickets\Commerce\Success;
14
 
@@ -40,11 +41,12 @@ class Success_Shortcode extends Shortcode_Abstract {
40
  ] )->first();
41
 
42
  $args = [
43
- 'provider_id' => Module::class,
44
- 'provider' => tribe( Module::class ),
45
- 'order_id' => $order_id,
46
- 'order' => $order,
47
- 'is_tec_active' => defined( 'TRIBE_EVENTS_FILE' ) && class_exists( 'Tribe__Events__Main' ),
 
48
  ];
49
 
50
  $this->template_vars = $args;
@@ -60,17 +62,38 @@ class Success_Shortcode extends Shortcode_Abstract {
60
  return '';
61
  }
62
 
 
 
 
 
 
63
  $args = $this->get_template_vars();
64
 
65
  // Add the rendering attributes into global context.
66
  $this->get_template()->add_template_globals( $args );
67
 
 
 
68
  $html = $this->get_template()->template( 'success', $args, false );
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  // Enqueue assets.
71
  tribe_asset_enqueue_group( 'tribe-tickets-commerce' );
72
-
73
- return $html;
74
  }
75
 
76
  }
9
  namespace TEC\Tickets\Commerce\Shortcodes;
10
 
11
  use TEC\Tickets\Commerce\Module;
12
+ use TEC\Tickets\Commerce\Order;
13
  use TEC\Tickets\Commerce\Status\Completed;
14
  use TEC\Tickets\Commerce\Success;
15
 
41
  ] )->first();
42
 
43
  $args = [
44
+ 'provider_id' => Module::class,
45
+ 'provider' => tribe( Module::class ),
46
+ 'order_id' => $order_id,
47
+ 'order' => $order,
48
+ 'is_tec_active' => defined( 'TRIBE_EVENTS_FILE' ) && class_exists( 'Tribe__Events__Main' ),
49
+ 'payment_method' => tribe( Order::class )->get_gateway_label( $order ),
50
  ];
51
 
52
  $this->template_vars = $args;
62
  return '';
63
  }
64
 
65
+ // Bail if we're in the blocks editor context.
66
+ if ( $context->doing_rest() ) {
67
+ return '';
68
+ }
69
+
70
  $args = $this->get_template_vars();
71
 
72
  // Add the rendering attributes into global context.
73
  $this->get_template()->add_template_globals( $args );
74
 
75
+ $this->enqueue_assets();
76
+
77
  $html = $this->get_template()->template( 'success', $args, false );
78
 
79
+ return $html;
80
+ }
81
+
82
+ /**
83
+ * Enqueue the assets related to this shortcode.
84
+ *
85
+ * @since 5.2.0
86
+ */
87
+ public static function enqueue_assets() {
88
+ $context = tribe_context();
89
+
90
+ // Bail if we're in the blocks editor context.
91
+ if ( $context->doing_rest() ) {
92
+ return;
93
+ }
94
+
95
  // Enqueue assets.
96
  tribe_asset_enqueue_group( 'tribe-tickets-commerce' );
 
 
97
  }
98
 
99
  }
src/Tickets/Commerce/Status/Action_Required.php CHANGED
@@ -35,11 +35,13 @@ class Action_Required extends Status_Abstract {
35
  protected $flags = [
36
  'incomplete',
37
  'trigger_option',
 
38
  'attendee_generation',
39
  'stock_reduced',
40
  'count_attendee',
41
  'count_incomplete',
42
  'count_sales',
 
43
  ];
44
 
45
  /**
35
  protected $flags = [
36
  'incomplete',
37
  'trigger_option',
38
+ 'backfill_purchaser',
39
  'attendee_generation',
40
  'stock_reduced',
41
  'count_attendee',
42
  'count_incomplete',
43
  'count_sales',
44
+ 'increase_sales',
45
  ];
46
 
47
  /**
src/Tickets/Commerce/Status/Approved.php CHANGED
@@ -35,11 +35,13 @@ class Approved extends Status_Abstract {
35
  protected $flags = [
36
  'incomplete',
37
  'trigger_option',
 
38
  'attendee_generation',
39
  'stock_reduced',
40
  'count_attendee',
41
  'count_incomplete',
42
  'count_sales',
 
43
  ];
44
 
45
  /**
35
  protected $flags = [
36
  'incomplete',
37
  'trigger_option',
38
+ 'backfill_purchaser',
39
  'attendee_generation',
40
  'stock_reduced',
41
  'count_attendee',
42
  'count_incomplete',
43
  'count_sales',
44
+ 'increase_sales',
45
  ];
46
 
47
  /**
src/Tickets/Commerce/Status/Completed.php CHANGED
@@ -2,7 +2,7 @@
2
  namespace TEC\Tickets\Commerce\Status;
3
 
4
  /**
5
- * Class Denied.
6
  *
7
  * This is the status we use to mark a given order as paid and delivered in our Tickets Commerce system.
8
  *
@@ -29,14 +29,20 @@ class Completed extends Status_Abstract {
29
 
30
  /**
31
  * {@inheritdoc}
 
 
32
  */
33
  protected $flags = [
34
  'complete',
 
35
  'attendee_dispatch',
36
  'stock_reduced',
 
37
  'count_attendee',
38
  'count_completed',
39
  'count_sales',
 
 
40
  ];
41
 
42
  /**
2
  namespace TEC\Tickets\Commerce\Status;
3
 
4
  /**
5
+ * Class Completed.
6
  *
7
  * This is the status we use to mark a given order as paid and delivered in our Tickets Commerce system.
8
  *
29
 
30
  /**
31
  * {@inheritdoc}
32
+ *
33
+ * Do not change the order arbitrarily. Flag actions are triggered in the order represented in this array.
34
  */
35
  protected $flags = [
36
  'complete',
37
+ 'backfill_purchaser',
38
  'attendee_dispatch',
39
  'stock_reduced',
40
+ 'send_email',
41
  'count_attendee',
42
  'count_completed',
43
  'count_sales',
44
+ 'increase_sales',
45
+ 'end_duplicated_pending_orders',
46
  ];
47
 
48
  /**
src/Tickets/Commerce/Status/Created.php CHANGED
@@ -35,6 +35,7 @@ class Created extends Status_Abstract {
35
  */
36
  protected $flags = [
37
  'incomplete',
 
38
  'trigger_option',
39
  ];
40
 
35
  */
36
  protected $flags = [
37
  'incomplete',
38
+ 'backfill_purchaser',
39
  'trigger_option',
40
  ];
41
 
src/Tickets/Commerce/Status/Denied.php CHANGED
@@ -34,6 +34,7 @@ class Denied extends Status_Abstract {
34
  protected $flags = [
35
  'incomplete',
36
  'warning',
 
37
  'count_canceled',
38
  ];
39
 
34
  protected $flags = [
35
  'incomplete',
36
  'warning',
37
+ 'backfill_purchaser',
38
  'count_canceled',
39
  ];
40
 
src/Tickets/Commerce/Status/Not_Completed.php CHANGED
@@ -34,8 +34,10 @@ class Not_Completed extends Status_Abstract {
34
  protected $flags = [
35
  'incomplete',
36
  'warning',
 
37
  'increase_stock',
38
- 'archive_attendees'
 
39
  ];
40
 
41
  /**
34
  protected $flags = [
35
  'incomplete',
36
  'warning',
37
+ 'backfill_purchaser',
38
  'increase_stock',
39
+ 'archive_attendees',
40
+ 'decrease_sales',
41
  ];
42
 
43
  /**
src/Tickets/Commerce/Status/Pending.php CHANGED
@@ -40,6 +40,7 @@ class Pending extends Status_Abstract {
40
  * {@inheritdoc}
41
  */
42
  protected $flags = [
 
43
  'count_attendee',
44
  'count_incomplete',
45
  'count_sales',
@@ -69,11 +70,11 @@ class Pending extends Status_Abstract {
69
  $order = tec_tc_get_order( $order );
70
 
71
  // Since there are no cart items we can do anything.
72
- if ( empty( $order->cart_items ) || ! is_array( $order->cart_items ) ) {
73
  return true;
74
  }
75
 
76
- foreach ( $order->cart_items as $item ) {
77
  // Skip if we dont have a ticket id.
78
  if ( empty( $item['ticket_id'] ) ) {
79
  continue;
40
  * {@inheritdoc}
41
  */
42
  protected $flags = [
43
+ 'backfill_purchaser',
44
  'count_attendee',
45
  'count_incomplete',
46
  'count_sales',
70
  $order = tec_tc_get_order( $order );
71
 
72
  // Since there are no cart items we can do anything.
73
+ if ( empty( $order->items ) || ! is_array( $order->items ) ) {
74
  return true;
75
  }
76
 
77
+ foreach ( $order->items as $item ) {
78
  // Skip if we dont have a ticket id.
79
  if ( empty( $item['ticket_id'] ) ) {
80
  continue;
src/Tickets/Commerce/Status/Refunded.php CHANGED
@@ -32,6 +32,7 @@ class Refunded extends Status_Abstract {
32
  */
33
  protected $flags = [
34
  'warning',
 
35
  'count_refunded',
36
  ];
37
 
32
  */
33
  protected $flags = [
34
  'warning',
35
+ 'backfill_purchaser',
36
  'count_refunded',
37
  ];
38
 
src/Tickets/Commerce/Status/Reversed.php CHANGED
@@ -32,6 +32,7 @@ class Reversed extends Status_Abstract {
32
  */
33
  protected $flags = [
34
  'warning',
 
35
  'count_refunded',
36
  ];
37
 
32
  */
33
  protected $flags = [
34
  'warning',
35
+ 'backfill_purchaser',
36
  'count_refunded',
37
  ];
38
 
src/Tickets/Commerce/Status/Undefined.php CHANGED
@@ -35,6 +35,7 @@ class Undefined extends Status_Abstract {
35
  'count_incomplete',
36
  'incomplete',
37
  'warning',
 
38
  ];
39
 
40
  /**
35
  'count_incomplete',
36
  'incomplete',
37
  'warning',
38
+ 'backfill_purchaser',
39
  ];
40
 
41
  /**
src/Tickets/Commerce/Status/Voided.php CHANGED
@@ -33,6 +33,7 @@ class Voided extends Status_Abstract {
33
  * {@inheritdoc}
34
  */
35
  protected $flags = [
 
36
  'count_refunded',
37
  'warning',
38
  ];
33
  * {@inheritdoc}
34
  */
35
  protected $flags = [
36
+ 'backfill_purchaser',
37
  'count_refunded',
38
  'warning',
39
  ];
src/Tickets/Commerce/Success.php CHANGED
@@ -141,4 +141,38 @@ class Success {
141
 
142
  return $post_states;
143
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  }
141
 
142
  return $post_states;
143
  }
144
+
145
+ /**
146
+ * Determines whether or not the success page option is set.
147
+ *
148
+ * @since 5.2.0
149
+ *
150
+ * @return bool
151
+ */
152
+ public function is_option_set() {
153
+ $page = $this->get_page_id();
154
+ return ! empty( $page );
155
+ }
156
+
157
+ /**
158
+ * Determines whether or not the success page has the appropriate shortcode in the content.
159
+ *
160
+ * @since 5.2.0
161
+ *
162
+ * @return bool
163
+ */
164
+ public function page_has_shortcode() {
165
+ if ( ! $this->is_option_set() ) {
166
+ return false;
167
+ }
168
+
169
+ $page = get_post( $this->get_page_id() );
170
+
171
+ if ( ! $page instanceof \WP_Post ) {
172
+ return false;
173
+ }
174
+
175
+ $shortcode = Shortcodes\Success_Shortcode::get_wp_slug();
176
+ return has_shortcode( $page->post_content, $shortcode );
177
+ }
178
  }
src/Tickets/Commerce/Ticket.php CHANGED
@@ -4,6 +4,9 @@ namespace TEC\Tickets\Commerce;
4
 
5
  use TEC\Tickets\Commerce\Status\Denied;
6
  use TEC\Tickets\Commerce\Status\Pending;
 
 
 
7
  use TEC\Tickets\Event;
8
 
9
  use Tribe__Utils__Array as Arr;
@@ -62,6 +65,15 @@ class Ticket {
62
  */
63
  public static $price_meta_key = '_price';
64
 
 
 
 
 
 
 
 
 
 
65
  /**
66
  * Which meta holds the data for the ticket stock mode.
67
  *
@@ -107,6 +119,15 @@ class Ticket {
107
  */
108
  public static $should_manage_stock_meta_key = '_manage_stock';
109
 
 
 
 
 
 
 
 
 
 
110
  /**
111
  * Register this Class post type into WP.
112
  *
@@ -144,6 +165,88 @@ class Ticket {
144
  register_post_type( static::POSTTYPE, $post_type_args );
145
  }
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  /**
148
  * Gets an individual ticket.
149
  *
@@ -162,12 +265,14 @@ class Ticket {
162
  return null;
163
  }
164
 
 
 
 
 
165
  $event_id = get_post_meta( $ticket_id, static::$event_relation_meta_key, true );
166
 
167
  $return = new \Tribe__Tickets__Ticket_Object();
168
 
169
- $qty_sold = get_post_meta( $ticket_id, 'total_sales', true );
170
-
171
  $return->description = $product->post_excerpt;
172
  $return->ID = $ticket_id;
173
  $return->name = $product->post_title;
@@ -183,6 +288,8 @@ class Ticket {
183
  $return->end_time = get_post_meta( $ticket_id, '_ticket_end_time', true );
184
  $return->sku = get_post_meta( $ticket_id, '_sku', true );
185
 
 
 
186
  // If the quantity sold wasn't set, default to zero
187
  $qty_sold = $qty_sold ? $qty_sold : 0;
188
 
@@ -527,7 +634,7 @@ class Ticket {
527
  /**
528
  * Generic action fired after saving a ticket (by type)
529
  *
530
- * @since 5.1.9
531
  *
532
  * @param int $post_id Post ID of post the ticket is tied to
533
  * @param \Tribe__Tickets__Ticket_Object $ticket Ticket that was just saved
@@ -537,9 +644,9 @@ class Ticket {
537
  do_action( "tec_tickets_commerce_after_{$save_type}_ticket", $post_id, $ticket, $raw_data, static::class );
538
 
539
  /**
540
- * Generic action fired after saving a ticket
541
  *
542
- * @since 4.7
543
  *
544
  * @param int $post_id Post ID of post the ticket is tied to
545
  * @param \Tribe__Tickets__Ticket_Object $ticket Ticket that was just saved
@@ -548,6 +655,34 @@ class Ticket {
548
  */
549
  do_action( 'tec_tickets_commerce_after_save_ticket', $post_id, $ticket, $raw_data, static::class );
550
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
  return $ticket->ID;
552
  }
553
 
@@ -663,11 +798,11 @@ class Ticket {
663
  */
664
  public function increase_ticket_sales_by( $ticket_id, $quantity = 1, $shared_capacity = false, $global_stock = null ) {
665
  // Adjust sales.
666
- $sales = (int) get_post_meta( $ticket_id, 'total_sales', true ) + $quantity;
667
 
668
- update_post_meta( $ticket_id, 'total_sales', $sales );
669
 
670
- if ( $shared_capacity && $global_stock instanceof \Tribe__Tickets__Global_Stock ) {
671
  $this->update_global_stock( $global_stock, $quantity );
672
  }
673
 
@@ -690,12 +825,12 @@ class Ticket {
690
  */
691
  public function decrease_ticket_sales_by( $ticket_id, $quantity = 1, $shared_capacity = false, $global_stock = null ) {
692
  // Adjust sales.
693
- $sales = (int) get_post_meta( $ticket_id, 'total_sales', true ) - $quantity;
694
 
695
  // Prevent negatives.
696
  $sales = max( $sales, 0 );
697
 
698
- update_post_meta( $ticket_id, 'total_sales', $sales );
699
 
700
  if ( $shared_capacity && $global_stock instanceof \Tribe__Tickets__Global_Stock ) {
701
  $this->update_global_stock( $global_stock, $quantity, true );
@@ -748,8 +883,7 @@ class Ticket {
748
  return '';
749
  }
750
 
751
- $price = $this->get_price_value( $product );
752
- $price = tribe( 'tickets.commerce.paypal.currency' )->format_currency( $price, $product_id );
753
 
754
  $price_html = '<span class="tribe-tickets-price-amount amount">' . esc_html( $price ) . '</span>';
755
 
4
 
5
  use TEC\Tickets\Commerce\Status\Denied;
6
  use TEC\Tickets\Commerce\Status\Pending;
7
+ use TEC\Tickets\Commerce\Status\Status_Handler;
8
+ use TEC\Tickets\Commerce\Status\Status_Interface;
9
+ use TEC\Tickets\Commerce\Utils\Price;
10
  use TEC\Tickets\Event;
11
 
12
  use Tribe__Utils__Array as Arr;
65
  */
66
  public static $price_meta_key = '_price';
67
 
68
+ /**
69
+ * Which meta holds the data for the ticket sales.
70
+ *
71
+ * @since 5.2.0
72
+ *
73
+ * @var string
74
+ */
75
+ public static $sales_meta_key = 'total_sales';
76
+
77
  /**
78
  * Which meta holds the data for the ticket stock mode.
79
  *
119
  */
120
  public static $should_manage_stock_meta_key = '_manage_stock';
121
 
122
+ /**
123
+ * Prefix for the counter for a given status..
124
+ *
125
+ * @since 5.2.0
126
+ *
127
+ * @var string
128
+ */
129
+ public static $status_count_meta_key_prefix = '_tec_tc_ticket_status_count';
130
+
131
  /**
132
  * Register this Class post type into WP.
133
  *
165
  register_post_type( static::POSTTYPE, $post_type_args );
166
  }
167
 
168
+ /**
169
+ * Gets the meta Key for a given status count on a ticket.
170
+ *
171
+ * @since 5.2.0
172
+ *
173
+ * @param Status_Interface $status
174
+ *
175
+ * @return string
176
+ */
177
+ public static function get_status_count_meta_key( Status_Interface $status ) {
178
+ return static::$status_count_meta_key_prefix . ':' . $status->get_slug();
179
+ }
180
+
181
+ /**
182
+ * Modify the counters for all the tickets involved on this particular order.
183
+ *
184
+ * @since 5.2.0
185
+ *
186
+ * @param Status_Interface $new_status New post status.
187
+ * @param Status_Interface|null $old_status Old post status.
188
+ * @param \WP_Post $post Post object.
189
+ */
190
+ public function modify_counters_by_status( $new_status, $old_status, $post ) {
191
+ $order = tec_tc_get_order( $post );
192
+
193
+ // This should never be the case, but lets be safe.
194
+ if ( empty( $order->items ) ) {
195
+ return;
196
+ }
197
+
198
+ foreach ( $order->items as $item ) {
199
+ $ticket_id = $item['ticket_id'];
200
+ $new_status_meta_key = static::get_status_count_meta_key( $new_status );
201
+ $current_new_status_qty = get_post_meta( $ticket_id, $new_status_meta_key, true );
202
+ if ( ! $current_new_status_qty ) {
203
+ $current_new_status_qty = 0;
204
+ }
205
+ update_post_meta( $ticket_id, $new_status_meta_key, (int) $current_new_status_qty + $item['quantity'] );
206
+
207
+ if ( $old_status ) {
208
+ $old_status_meta_key = static::get_status_count_meta_key( $old_status );
209
+ $current_old_status_qty = get_post_meta( $ticket_id, $old_status_meta_key, true );
210
+ if ( ! $current_old_status_qty ) {
211
+ $current_old_status_qty = 0;
212
+ }
213
+ update_post_meta( $ticket_id, $old_status_meta_key, max( 0, (int) $current_old_status_qty - $item['quantity'] ) );
214
+ }
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Given a valid ticket will fetch the quantity of orders on each one of the registered status based on the counting
220
+ * that is handled by the Order status transitions system.
221
+ *
222
+ * @since 5.2.0
223
+ *
224
+ * @param int|string|\WP_Post $ticket_id Which ticket we are fetching the count for.
225
+ *
226
+ * @return array<string,int>|\WP_Error
227
+ */
228
+ public function get_status_quantity( $ticket_id ) {
229
+ $ticket = get_post( $ticket_id );
230
+
231
+ if ( ! $ticket ) {
232
+ return new \WP_Error( 'tec-tickets-commerce-non-existent-ticket' );
233
+ }
234
+
235
+ $all_statuses = tribe( Status_Handler::class )->get_all();
236
+ $status_qty = [];
237
+
238
+ foreach ( $all_statuses as $status ) {
239
+ $value = get_post_meta( $ticket->ID, static::get_status_count_meta_key( $status ), true );
240
+ if ( empty( $value ) ) {
241
+ $value = 0;
242
+ }
243
+
244
+ $status_qty[ $status->get_slug() ] = (int) $value;
245
+ }
246
+
247
+ return $status_qty;
248
+ }
249
+
250
  /**
251
  * Gets an individual ticket.
252
  *
265
  return null;
266
  }
267
 
268
+ if ( static::POSTTYPE !== get_post_type( $product ) ) {
269
+ return null;
270
+ }
271
+
272
  $event_id = get_post_meta( $ticket_id, static::$event_relation_meta_key, true );
273
 
274
  $return = new \Tribe__Tickets__Ticket_Object();
275
 
 
 
276
  $return->description = $product->post_excerpt;
277
  $return->ID = $ticket_id;
278
  $return->name = $product->post_title;
288
  $return->end_time = get_post_meta( $ticket_id, '_ticket_end_time', true );
289
  $return->sku = get_post_meta( $ticket_id, '_sku', true );
290
 
291
+ $qty_sold = get_post_meta( $ticket_id, static::$sales_meta_key, true );
292
+
293
  // If the quantity sold wasn't set, default to zero
294
  $qty_sold = $qty_sold ? $qty_sold : 0;
295
 
634
  /**
635
  * Generic action fired after saving a ticket (by type)
636
  *
637
+ * @since 5.2.0
638
  *
639
  * @param int $post_id Post ID of post the ticket is tied to
640
  * @param \Tribe__Tickets__Ticket_Object $ticket Ticket that was just saved
644
  do_action( "tec_tickets_commerce_after_{$save_type}_ticket", $post_id, $ticket, $raw_data, static::class );
645
 
646
  /**
647
+ * Generic action fired after saving a ticket.
648
  *
649
+ * @since 5.2.0
650
  *
651
  * @param int $post_id Post ID of post the ticket is tied to
652
  * @param \Tribe__Tickets__Ticket_Object $ticket Ticket that was just saved
655
  */
656
  do_action( 'tec_tickets_commerce_after_save_ticket', $post_id, $ticket, $raw_data, static::class );
657
 
658
+ /**
659
+ * Generic action fired after saving a ticket (by type)
660
+ *
661
+ * @todo TribeCommerceLegacy
662
+ *
663
+ * @since 5.2.0
664
+ *
665
+ * @param int $post_id Post ID of post the ticket is tied to
666
+ * @param \Tribe__Tickets__Ticket_Object $ticket Ticket that was just saved
667
+ * @param array $raw_data Ticket data
668
+ * @param string $class Commerce engine class
669
+ */
670
+ do_action( "event_tickets_after_{$save_type}_ticket", $post_id, $ticket, $raw_data, static::class );
671
+
672
+ /**
673
+ * Generic action fired after saving a ticket.
674
+ *
675
+ * @todo TribeCommerceLegacy
676
+ *
677
+ * @since 5.2.0
678
+ *
679
+ * @param int $post_id Post ID of post the ticket is tied to
680
+ * @param \Tribe__Tickets__Ticket_Object $ticket Ticket that was just saved
681
+ * @param array $raw_data Ticket data
682
+ * @param string $class Commerce engine class
683
+ */
684
+ do_action( 'event_tickets_after_save_ticket', $post_id, $ticket, $raw_data, static::class );
685
+
686
  return $ticket->ID;
687
  }
688
 
798
  */
799
  public function increase_ticket_sales_by( $ticket_id, $quantity = 1, $shared_capacity = false, $global_stock = null ) {
800
  // Adjust sales.
801
+ $sales = (int) get_post_meta( $ticket_id, static::$sales_meta_key, true ) + $quantity;
802
 
803
+ update_post_meta( $ticket_id, static::$sales_meta_key, $sales );
804
 
805
+ if ( 'own' !== $shared_capacity && $global_stock instanceof \Tribe__Tickets__Global_Stock ) {
806
  $this->update_global_stock( $global_stock, $quantity );
807
  }
808
 
825
  */
826
  public function decrease_ticket_sales_by( $ticket_id, $quantity = 1, $shared_capacity = false, $global_stock = null ) {
827
  // Adjust sales.
828
+ $sales = (int) get_post_meta( $ticket_id, static::$sales_meta_key, true ) - $quantity;
829
 
830
  // Prevent negatives.
831
  $sales = max( $sales, 0 );
832
 
833
+ update_post_meta( $ticket_id, static::$sales_meta_key, $sales );
834
 
835
  if ( $shared_capacity && $global_stock instanceof \Tribe__Tickets__Global_Stock ) {
836
  $this->update_global_stock( $global_stock, $quantity, true );
883
  return '';
884
  }
885
 
886
+ $price = Price::to_currency( Price::to_string( $this->get_price_value( $product ) ) );
 
887
 
888
  $price_html = '<span class="tribe-tickets-price-amount amount">' . esc_html( $price ) . '</span>';
889
 
src/Tickets/Commerce/Utils/Price.php CHANGED
@@ -9,11 +9,25 @@ namespace TEC\Tickets\Commerce\Utils;
9
  *
10
  */
11
  class Price {
 
 
 
 
 
 
 
 
 
 
 
12
  /**
13
  * Taking a given numerical price it will multiply the by the quantity passed it will not convert the values into
14
  * float at any point, it will use full integers and strings to calculate, to avoid float point problems.
15
  *
16
- * We only allow two decimal points.
 
 
 
17
  *
18
  * @since 5.1.9
19
  *
@@ -25,13 +39,11 @@ class Price {
25
  * @return string
26
  */
27
  public static function sub_total( $value, $quantity, $decimal = null, $thousand_sep = null ) {
28
- $decimal = $decimal ?: tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'decimal_point' );
29
- $thousand_sep = $thousand_sep ?: tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'thousands_sep' );
30
- $number = number_format( $value, 2, $decimal, $thousand_sep );
31
- $number = (int) str_replace( [ $decimal, $thousand_sep ], '', $number );
32
 
33
- $sub_total = $number * $quantity;
34
- $sub_total = substr_replace( (string) $sub_total, $decimal, - 2, 0 );
35
 
36
  return number_format( $sub_total, 2, $decimal, $thousand_sep );
37
  }
@@ -40,6 +52,9 @@ class Price {
40
  * Taking an array of values it creates the sum of those values, it will not convert the values into float at any
41
  * point, it will use full integers and strings to calculate, to avoid float point problems.
42
  *
 
 
 
43
  * We only allow two decimal points.
44
  *
45
  * @since 5.1.9
@@ -51,19 +66,178 @@ class Price {
51
  * @return string
52
  */
53
  public static function total( array $values, $decimal = null, $thousand_sep = null ) {
54
- $decimal = $decimal ?: tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'decimal_point' );
55
- $thousand_sep = $thousand_sep ?: tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'thousands_sep' );
56
 
57
  $values = array_map( static function ( $value ) use ( $decimal, $thousand_sep ) {
58
- $number = number_format( $value, 2, $decimal, $thousand_sep );
59
-
60
- return (int) str_replace( [ $decimal, $thousand_sep ], '', $number );
61
  }, $values );
62
 
63
-
64
- $total = array_sum( array_filter( $values ) );
65
- $total = substr_replace( (string) $total, $decimal, - 2, 0 );
66
 
67
  return number_format( $total, 2, $decimal, $thousand_sep );
68
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  *
10
  */
11
  class Price {
12
+
13
+ /**
14
+ * The precision to use in decimal places. This is currently statically set to 2,
15
+ * but may become variable for supporting 3 digit decimals
16
+ *
17
+ * @since 5.2.0
18
+ *
19
+ * @var int
20
+ */
21
+ private static $precision = 2;
22
+
23
  /**
24
  * Taking a given numerical price it will multiply the by the quantity passed it will not convert the values into
25
  * float at any point, it will use full integers and strings to calculate, to avoid float point problems.
26
  *
27
+ * This function expects that the incoming value will be either an integer with decimals as the last 2 digits
28
+ * or a formatted string using the same decimal and thousands separators as set in the system.
29
+ *
30
+ * Currently, we only allow two decimal digits.
31
  *
32
  * @since 5.1.9
33
  *
39
  * @return string
40
  */
41
  public static function sub_total( $value, $quantity, $decimal = null, $thousand_sep = null ) {
42
+ $decimal = ! is_null( $decimal ) ? $decimal : tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'decimal_point' );
43
+ $thousand_sep = ! is_null( $thousand_sep ) ? $thousand_sep : tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'thousands_sep' );
 
 
44
 
45
+ $number = static::to_integer( $value, $decimal, $thousand_sep );
46
+ $sub_total = static::to_decimal( $number * $quantity );
47
 
48
  return number_format( $sub_total, 2, $decimal, $thousand_sep );
49
  }
52
  * Taking an array of values it creates the sum of those values, it will not convert the values into float at any
53
  * point, it will use full integers and strings to calculate, to avoid float point problems.
54
  *
55
+ * This function expects that the incoming values will be either integers with decimals as the last 2 digits
56
+ * or formatted strings using the same decimal and thousands separators as set in the system.
57
+ *
58
  * We only allow two decimal points.
59
  *
60
  * @since 5.1.9
66
  * @return string
67
  */
68
  public static function total( array $values, $decimal = null, $thousand_sep = null ) {
69
+ $decimal = ! is_null( $decimal ) ? $decimal : tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'decimal_point' );
70
+ $thousand_sep = ! is_null( $thousand_sep ) ? $thousand_sep : tribe( \Tribe__Tickets__Commerce__Currency::class )->get_currency_locale( 'thousands_sep' );
71
 
72
  $values = array_map( static function ( $value ) use ( $decimal, $thousand_sep ) {
73
+ return static::to_integer( $value, $decimal, $thousand_sep );
 
 
74
  }, $values );
75
 
76
+ $total = array_sum( $values );
77
+ $total = static::to_decimal( $total );
 
78
 
79
  return number_format( $total, 2, $decimal, $thousand_sep );
80
  }
81
+
82
+ /**
83
+ * Removes decimal and thousands separator from a numeric string, transforming it into an int
84
+ *
85
+ * @todo currently this requires that the $value be formatted using $decimal and $thousand_sep, which
86
+ * can be an issue in migrated sites, or sites that changed number formatting. It will also fail if
87
+ * $value is a float and neither $decimal or $thousand_sep are '.'.
88
+ * We should expand this to remove any possible combination of decimal/thousands marks from numbers.
89
+ *
90
+ * @since 5.2.0
91
+ *
92
+ * @param string $value Numeric value to clean.
93
+ * @param string $decimal Which Decimal separator.
94
+ * @param string $thousand_sep Which thousand separator.
95
+ *
96
+ * @return int
97
+ */
98
+ public static function to_integer( $value, $decimal, $thousand_sep ) {
99
+
100
+ // If the string is formatted with thousands separators but not with decimals, pad with decimals
101
+ if ( false !== strpos( $value, $thousand_sep ) && false === strpos( $value, $decimal ) ) {
102
+ $value = $value . '.00';
103
+ }
104
+
105
+ // We're done with thousands separators
106
+ $value = str_replace( $thousand_sep, '', $value );
107
+
108
+ // If the last char on the value is a decimal point, pad with two zeros
109
+ if (