Razorpay for WooCommerce - Version 3.0.0

Version Description

  • Added Magic Checkout feature.
Download this release

Release Info

Developer razorpay
Plugin Icon 128x128 Razorpay for WooCommerce
Version 3.0.0
Comparing to
See all releases

Code changes from version 2.8.6 to 3.0.0

btn-1cc-checkout.js ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ window.addEventListener('DOMContentLoaded', function() {
2
+
3
+ var btn = document.getElementById('btn-1cc');
4
+ var btnMini = document.getElementById('btn-1cc-mini-cart');
5
+ var btnPdp = document.getElementById('btn-1cc-pdp');
6
+ var rzpSpinnerBackdrop = document.getElementById('rzp-spinner-backdrop');
7
+ var rzpSpinner = document.getElementById('rzp-spinner');
8
+ var pageURL = jQuery(location).attr('href');
9
+ var url = new URL(pageURL);
10
+ var accessToken = new URLSearchParams(url.search).get('wcf_ac_token');
11
+
12
+ // event triggered by wc on any cart change
13
+ // as input function is the same, duplicate event listeners are NOT called
14
+ jQuery(document.body).on('updated_cart_totals', function(event) {
15
+ var btn = document.getElementById('btn-1cc');
16
+ if (btn !== null) {
17
+ btn.addEventListener('click', openRzpCheckout);
18
+ }
19
+
20
+ var btnMini = document.getElementById('btn-1cc-mini-cart');
21
+ if (btnMini !== null) {
22
+ btnMini.addEventListener('click', openRzpCheckout);
23
+ }
24
+ });
25
+
26
+ function addEventListenerToMinicart(wcEvent) {
27
+ jQuery(document.body).on(wcEvent, function(event) {
28
+ var btnMini = document.getElementById('btn-1cc-mini-cart');
29
+ if (btnMini !== null) {
30
+ btnMini.addEventListener('click', openRzpCheckout);
31
+ }
32
+ });
33
+ }
34
+
35
+ addEventListenerToMinicart('wc_fragments_refreshed');
36
+ addEventListenerToMinicart('wc_fragments_loaded');
37
+ addEventListenerToMinicart('added_to_cart');
38
+
39
+ if (btnPdp != null) {
40
+ btnPdp.onclick = function() {
41
+
42
+ var pdpCheckout = btnPdp.getAttribute('pdp_checkout');
43
+ var productId = btnPdp.getAttribute('product_id');
44
+ var quantity = btnPdp.getAttribute('quantity');
45
+
46
+ rzp1ccCheckoutData.pdpCheckout = pdpCheckout;
47
+ rzp1ccCheckoutData.productId = productId;
48
+ rzp1ccCheckoutData.quantity = quantity;
49
+
50
+ if (btnPdp.getAttribute('variation_id') != null) {
51
+ var variationId = btnPdp.getAttribute('variation_id');
52
+ var variations = btnPdp.getAttribute('variations');
53
+
54
+ rzp1ccCheckoutData.variationId = variationId;
55
+ rzp1ccCheckoutData.variations = variations;
56
+ }
57
+
58
+ //To support custom product fields plugin.
59
+ const customFieldForm = document.getElementsByClassName('wcpa_form_outer');
60
+
61
+ if (customFieldForm && customFieldForm.length > 0) {
62
+
63
+ var customProductFieldForm = customFieldForm[0];
64
+
65
+ var fieldValues = customProductFieldForm.getElementsByTagName('input');
66
+ var fieldKey = customProductFieldForm.getElementsByTagName('label');
67
+ var fieldArray = [];
68
+ var fieldObj = {};
69
+
70
+ for (i = 0; i < fieldKey.length; i++) {
71
+ fieldObj[fieldKey[i].innerText] = fieldValues[i].value;
72
+ }
73
+
74
+ rzp1ccCheckoutData.fieldObj = fieldObj;
75
+ }
76
+ }
77
+ }
78
+
79
+ // fetch opts from server and open 1cc modal
80
+ var rzp1cc = {
81
+ orderApi: rzp1ccCheckoutData.siteurl + '/wp-json/1cc/v1/order/create',
82
+ saveAbandonedCartApi: rzp1ccCheckoutData.siteurl + '/wp-json/1cc/v1/abandoned-cart',
83
+ makeRequest: function(url, body) {
84
+ return new Promise(function(resolve, reject) {
85
+ var xhr = new XMLHttpRequest();
86
+ xhr.open('POST', url, true);
87
+ xhr.setRequestHeader('Content-Type', 'application/json');
88
+ xhr.setRequestHeader('X-WP-Nonce', rzp1ccCheckoutData.nonce);
89
+ xhr.onload = function() {
90
+ if (this.status === 200) {
91
+ resolve(rzp1cc.parseIfJson(this.response));
92
+ } else {
93
+ reject({ status: this.status, response: rzp1cc.parseIfJson(this.response) });
94
+ }
95
+ }
96
+ xhr.onerror = function () {
97
+ reject({ status: this.status, statusText: this.statusText});
98
+ };
99
+ xhr.send(JSON.stringify(body));
100
+ });
101
+ },
102
+ parseIfJson: function (str) {
103
+ try {
104
+ return JSON.parse(str);
105
+ } catch (e) {
106
+ return str;
107
+ }
108
+ },
109
+ setDisabled: function(id, state) {
110
+ if (typeof state === 'undefined') {
111
+ state = true;
112
+ }
113
+ var elem = document.getElementById(id);
114
+
115
+ if(elem != null)
116
+ {
117
+ if (state === false) {
118
+ elem.removeAttribute('disabled');
119
+ } else {
120
+ elem.setAttribute('disabled', state);
121
+ }
122
+ }
123
+ },
124
+ showSpinner: function(state) {
125
+ if (rzpSpinnerBackdrop == null) {
126
+ rzpSpinnerBackdrop = document.getElementById('rzp-spinner-backdrop');
127
+ }
128
+ if (rzpSpinner == null) {
129
+ rzpSpinner = document.getElementById('rzp-spinner');
130
+ }
131
+ if (state === true) {
132
+ rzpSpinnerBackdrop.classList.add('show');
133
+ rzpSpinner.classList.add('show');
134
+ } else {
135
+ rzpSpinnerBackdrop.classList.remove('show');
136
+ rzpSpinner.classList.remove('show');
137
+ }
138
+ },
139
+ handleAbandonmentCart: function(rzpOrderId) {
140
+ if(rzpOrderId != null) {
141
+ var xhr = new XMLHttpRequest();
142
+ try {
143
+ var body = {
144
+ order_id: rzpOrderId
145
+ };
146
+ xhr.open('POST', rzp1cc.saveAbandonedCartApi, true);
147
+ xhr.setRequestHeader('Content-Type', 'application/json');
148
+ xhr.send(JSON.stringify(body));
149
+ } catch (e) {
150
+
151
+ }
152
+ }
153
+ },
154
+ enableCheckoutButtons: function() {
155
+ rzp1cc.setDisabled('btn-1cc', false);
156
+ rzp1cc.setDisabled('btn-1cc-mini-cart', false);
157
+ rzp1cc.setDisabled('btn-1cc-pdp', false);
158
+ }
159
+ }
160
+
161
+ if (btn !== null) {
162
+ btn.addEventListener('click', openRzpCheckout);
163
+ }
164
+
165
+ if (btnMini !== null) {
166
+ btnMini.addEventListener('click', openRzpCheckout);
167
+ }
168
+
169
+ if (btnPdp !== null) {
170
+ btnPdp.addEventListener('click', openRzpCheckout);
171
+ }
172
+
173
+ async function openRzpCheckout(e) {
174
+ e.preventDefault();
175
+ rzp1cc.showSpinner(true);
176
+
177
+ if (accessToken !== null)
178
+ {
179
+ rzp1ccCheckoutData.token = accessToken;
180
+ }
181
+
182
+ var body = rzp1ccCheckoutData;
183
+
184
+ rzp1cc.setDisabled('btn-1cc');
185
+ rzp1cc.setDisabled('btn-1cc-mini-cart');
186
+ rzp1cc.setDisabled('btn-1cc-pdp');
187
+
188
+ rzp1cc.makeRequest(rzp1cc.orderApi, body)
189
+ .then(data => {
190
+ rzp1cc.showSpinner(false);
191
+ try {
192
+ var razorpayCheckout = new Razorpay({
193
+ ...data,
194
+ modal: {
195
+ ondismiss: function() {
196
+ rzp1cc.handleAbandonmentCart(data.order_id);
197
+ rzp1cc.enableCheckoutButtons();
198
+ }
199
+ },
200
+ });
201
+ razorpayCheckout.open();
202
+
203
+ } catch (e) {
204
+ document.getElementById('error-message').innerHTML =
205
+ "<div class='entry-content'><div class='woocommerce'><div class='woocommerce-notices-wrapper'><p class='cart-empty woocommerce-info' style='margin-left: -50px; margin-right: 75px'>Something went wrong, please try again after sometime.</p></div></div></div>";
206
+
207
+ rzp1cc.enableCheckoutButtons();
208
+ rzp1cc.showSpinner(false);
209
+
210
+ }
211
+ })
212
+ .catch(e => {
213
+ // Response sent to the User when cart is empty or order creation fails
214
+ if (e.status == 400){
215
+ if (e.response.code == 'BAD_REQUEST_EMPTY_CART'){
216
+ document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Order could not be placed as your cart is empty.</p>";
217
+ } else if (e.response.code == 'ORDER_CREATION_FAILED'){
218
+ document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Razorpay Error: Order could not be placed, please try again after sometime.</p>";
219
+ } else if (e.response.code == 'MIN_CART_AMOUNT_CHECK_FAILED'){
220
+ document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>"+e.response.message+"</p>";
221
+ } else if (e.response.code == 'WOOCOMMERCE_ORDER_CREATION_FAILED'){
222
+ document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Order could not be placed, please connect with the "+rzp1ccCheckoutData.blogname+"</p>";
223
+ } else {
224
+ document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Something went wrong, please try again after sometime.</p>";
225
+ }
226
+
227
+ } else {
228
+ document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Something went wrong, please try again after sometime.</p>";
229
+ }
230
+
231
+ rzp1cc.enableCheckoutButtons();
232
+ rzp1cc.showSpinner(false);
233
+ });
234
+ }
235
+ });
debug.md ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ localhost - incognito - key + order_id sent
2
+
3
+
4
+ kinsta - incognito - key + order_id sent
5
+
6
+
7
+
8
+ localhost - incognito - only order_id
9
+
10
+
11
+ kinsta - incognito - only order_id
12
+
13
+
14
+ TODO
15
+ - Confirm if we send both `key` and `order_id`
16
+ -
17
+
18
+
19
+ Bug on Chrome NOT on Firefox
20
+ Incog -> prefill number + email -> open checkout for non-logged in user -> goes to address before otp check
21
+
22
+ Firefox Curl
23
+ ```
24
+ curl 'https://omega-api.stage.razorpay.in/v1/customers/status/+918888888888?x_entity_id=order_IDu8TYW7wKolMv&_[platform]=browser' --globoff -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:93.0) Gecko/20100101 Firefox/93.0' -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: https://omega-api.stage.razorpay.in/test/checkout.html?branch=feat/1cc' -H 'Cookie: razorpay_api_session=eyJpdiI6IjJUYkU1Kzc2cXNLa2ZzeW5wNzhPTWc9PSIsInZhbHVlIjoiRDFSdFJhTllcL2NrbnI3UFlYQnh4SHRCazNYS0JlNlVla05HWm9rQ0piaVwvbzduemtPQ3did1RiZDQwUnRvWnVQOTVmVkx3aWhMbGVOeFZZVXpyRThlcU9UNUE5Z2xyXC9YNE5FM2VxcnBhb292RTJuSGRzaE1WeGtGZGF2OERGQW4iLCJtYWMiOiJmZjBjOWM0OTNlM2JiMTk0OGQ3MzdkYzRlMDQxYTg4ZjgyYzM2MjIzYjRiNzYzYWI2MGYzNTgyNmVhZjE4Nzg3In0%3D' -H 'Sec-Fetch-Dest: empty' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin'
25
+ ```
26
+
27
+
28
+ Chrome Curl
29
+ ```
30
+ curl 'https://omega-api.stage.razorpay.in/v1/customers/status/+918888888888?x_entity_id=order_IDu8TYW7wKolMv&_\[platform\]=browser' \
31
+ -H 'Connection: keep-alive' \
32
+ -H 'sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"' \
33
+ -H 'sec-ch-ua-mobile: ?0' \
34
+ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36' \
35
+ -H 'sec-ch-ua-platform: "macOS"' \
36
+ -H 'Accept: */*' \
37
+ -H 'Sec-Fetch-Site: same-origin' \
38
+ -H 'Sec-Fetch-Mode: cors' \
39
+ -H 'Sec-Fetch-Dest: empty' \
40
+ -H 'Referer: https://omega-api.stage.razorpay.in/test/checkout.html?branch=feat/1cc' \
41
+ -H 'Accept-Language: en-GB,en;q=0.9' \
42
+ --compressed
43
+ ```
44
+
45
+
46
+
47
+ curl --location --request POST 'https://api.razorpay.com/v1/orders' \
48
+ --header 'Authorization: Basic cnpwX3Rlc3RfMURQNW1tT2xGNUc1YWc6dGhpc2lzc3VwZXJzZWNyZXQ=' \
49
+ --header 'Content-Type: application/json' \
50
+ --data-raw '{
51
+ "amount": 100000,
52
+ "currency": "INR",
53
+ "receipt": "ORDER_COUPON",
54
+ "payment_capture": 1,
55
+ "notes": {
56
+ "notes_key_1": "Book 1"
57
+ }
58
+ }'
includes/api/api.php ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * custom APIs for Razorpay 1cc
5
+ */
6
+
7
+ require_once __DIR__ . '/../debug.php';
8
+ require_once __DIR__ . '/../../woo-razorpay.php';
9
+ require_once __DIR__ . '/shipping-info.php';
10
+ require_once __DIR__ . '/coupon-apply.php';
11
+ require_once __DIR__ . '/coupon-get.php';
12
+ require_once __DIR__ . '/order.php';
13
+ require_once __DIR__ . '/cart.php';
14
+ require_once __DIR__ . '/auth.php';
15
+ require_once __DIR__ . '/../state-map.php';
16
+ require_once __DIR__ . '/save-abandonment-data.php';
17
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
18
+
19
+ define('RZP_1CC_ROUTES_BASE', '1cc/v1');
20
+ define('RZP_1CC_CART_HASH', 'wc_razorpay_cart_hash_');
21
+
22
+ function rzp1ccInitRestApi()
23
+ {
24
+
25
+ /**
26
+ * coupon APIs required
27
+ */
28
+
29
+ // returns applicable coupons for an order
30
+ register_rest_route(
31
+ RZP_1CC_ROUTES_BASE . '/coupon',
32
+ 'list',
33
+ array(
34
+ 'methods' => 'POST',
35
+ 'callback' => 'getCouponList',
36
+ 'permission_callback' => 'checkAuthCredentials',
37
+ )
38
+ );
39
+
40
+ // checks if a coupon can be applied and returns discount amount
41
+ register_rest_route(
42
+ RZP_1CC_ROUTES_BASE . '/coupon',
43
+ 'apply',
44
+ array(
45
+ 'methods' => 'POST',
46
+ 'callback' => 'applyCouponOnCart',
47
+ 'permission_callback' => 'checkAuthCredentials',
48
+ )
49
+ );
50
+
51
+ /**
52
+ * order APIs
53
+ */
54
+
55
+ // create new wc order
56
+ register_rest_route(
57
+ RZP_1CC_ROUTES_BASE . '/order',
58
+ 'create',
59
+ array(
60
+ 'methods' => 'POST',
61
+ 'callback' => 'createWcOrder',
62
+ 'permission_callback' => 'checkAuthCredentials',
63
+ )
64
+ );
65
+
66
+ /**
67
+ * shipping APIs
68
+ */
69
+
70
+ // list of shipping methods for an order
71
+ register_rest_route(
72
+ RZP_1CC_ROUTES_BASE . '/shipping',
73
+ 'shipping-info',
74
+ array(
75
+ 'methods' => 'POST',
76
+ 'callback' => 'calculateShipping1cc',
77
+ 'permission_callback' => 'checkAuthCredentials',
78
+ )
79
+ );
80
+
81
+ // save abandoned cart data
82
+ register_rest_route(
83
+ RZP_1CC_ROUTES_BASE . '/',
84
+ 'abandoned-cart',
85
+ array(
86
+ 'methods' => 'POST',
87
+ 'callback' => 'saveCartAbandonmentData',
88
+ 'permission_callback' => 'checkAuthCredentials',
89
+ )
90
+ );
91
+ }
92
+
93
+ add_action('rest_api_init', 'rzp1ccInitRestApi');
94
+
95
+ /**
96
+ * Check any prerequisites for our REST request
97
+ */
98
+ function initCustomerSessionAndCart()
99
+ {
100
+ if (defined('WC_ABSPATH')) {
101
+ // WC 3.6+ - Cart and other frontend functions are not included for REST requests.
102
+ include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
103
+ include_once WC_ABSPATH . 'includes/wc-notice-functions.php';
104
+ include_once WC_ABSPATH . 'includes/wc-template-hooks.php';
105
+ }
106
+
107
+ if (null === WC()->session) {
108
+ $session_class = apply_filters('woocommerce_session_handler', 'WC_Session_Handler');
109
+ WC()->session = new $session_class();
110
+ WC()->session->init();
111
+ }
112
+
113
+ if (null === WC()->customer) {
114
+ WC()->customer = new WC_Customer(get_current_user_id(), true);
115
+ }
116
+
117
+ if (null === WC()->cart) {
118
+ WC()->cart = new WC_Cart();
119
+ WC()->cart->get_cart();
120
+ }
121
+ }
122
+
123
+ add_action('setup_extra_setting_fields', 'addMagicCheckoutSettingFields');
124
+
125
+ function addMagicCheckoutSettingFields(&$defaultFormFields)
126
+ {
127
+ $magicCheckoutConfigFields = array(
128
+
129
+ 'enable_1cc' => array(
130
+ 'title' => __('Activate Magic Checkout'),
131
+ 'type' => 'checkbox',
132
+ 'description' => "",
133
+ 'label' => __('Activate Magic Checkout'),
134
+ 'default' => 'no',
135
+ ),
136
+ 'enable_1cc_test_mode' => array(
137
+ 'title' => __('Activate test mode'),
138
+ 'type' => 'checkbox',
139
+ 'description' => 'When test mode is active, only logged-in admin users will see the Razorpay Magic Checkout button',
140
+ 'label' => __('Activate test mode for Magic Checkout'),
141
+ 'default' => 'no',
142
+ ),
143
+ 'enable_1cc_pdp_checkout' => array(
144
+ 'title' => __('Activate Buy Now Button'),
145
+ 'type' => 'checkbox',
146
+ 'description' => 'By enabling the Buy Now button, user will be able to see the Razorpay Magic Checkout button on Product display page. ',
147
+ 'label' => __('Activate Buy Now for Magic Checkout'),
148
+ 'default' => 'yes',
149
+ ),
150
+ 'enable_1cc_mini_cart_checkout' => array(
151
+ 'title' => __('Activate Mini Cart Checkout'),
152
+ 'type' => 'checkbox',
153
+ 'description' => 'By enabling the Mini Cart checkout button, user will be able to see the Razorpay Magic Checkout on click of checkout button. ',
154
+ 'label' => __('Activate Mini Cart for Magic Checkout'),
155
+ 'default' => 'yes',
156
+ ),
157
+ '1cc_min_cart_amount' => array(
158
+ 'title' => __('Set minimum cart amount (INR)'),
159
+ 'type' => 'number',
160
+ 'description' => 'Enter a minimum cart amount required to place an order via Magic Checkout.',
161
+ 'default' => 0,
162
+ 'css' => 'width: 120px;',
163
+ 'custom_attributes' => array(
164
+ 'min' => 0,
165
+ 'step' => 1,
166
+ ),
167
+ ),
168
+ 'enable_1cc_mandatory_login' => array(
169
+ 'title' => __('Activate Mandatory Login'),
170
+ 'type' => 'checkbox',
171
+ 'description' => "",
172
+ 'label' => __('Activate Mandatory Login for Magic Checkout'),
173
+ 'default' => 'no',
174
+ ),
175
+ 'enable_1cc_cod_intelligence' => array(
176
+ 'title' => __('Activate COD Intelligence'),
177
+ 'type' => 'checkbox',
178
+ 'description' => "By enabling this you allow Magic Checkout to decide which customer sees the COD option based on past shopping history",
179
+ 'label' => __('Activate Magic Checkout COD Intelligence'),
180
+ 'default' => 'no',
181
+ ),
182
+ '1cc_min_COD_slab_amount' => array(
183
+ 'title' => __('Set minimum amount (INR) for COD'),
184
+ 'type' => 'number',
185
+ 'description' => 'Enter a minimum amount required to place an order via COD (if enabled)',
186
+ 'default' => 0,
187
+ 'css' => 'width: 120px;',
188
+ 'custom_attributes' => array(
189
+ 'min' => 0,
190
+ 'step' => 1,
191
+ ),
192
+ ),
193
+ '1cc_max_COD_slab_amount' => array(
194
+ 'title' => __('Set maximum amount (INR) for COD'),
195
+ 'type' => 'number',
196
+ 'description' => 'Enter a maximum amount allowed to place an order via COD (if enabled)',
197
+ 'default' => 0,
198
+ 'css' => 'width: 120px;',
199
+ 'custom_attributes' => array(
200
+ 'min' => 0,
201
+ 'step' => 1,
202
+ ),
203
+ ),
204
+ 'enable_1cc_ga_analytics' => array(
205
+ 'title' => __('Activate Google Analytics'),
206
+ 'type' => 'checkbox',
207
+ 'description' => "To track orders using Google Analytics",
208
+ 'label' => __('Activate Magic Checkout Google Analytics'),
209
+ 'default' => 'no',
210
+ ),
211
+ 'enable_1cc_fb_analytics' => array(
212
+ 'title' => __('Activate Facebook Analytics'),
213
+ 'type' => 'checkbox',
214
+ 'description' => "To track orders using Facebook Pixel",
215
+ 'label' => __('Activate Magic Checkout Facebook Analytics'),
216
+ 'default' => 'no',
217
+ ),
218
+ 'enable_1cc_debug_mode' => array(
219
+ 'title' => __('Activate debug mode'),
220
+ 'type' => 'checkbox',
221
+ 'description' => 'When debug mode is active, API logs and errors are collected and stored in your Woocommerce dashboard. It is recommended to keep this activated.',
222
+ 'label' => __('Enable debug mode for Magic Checkout'),
223
+ 'default' => 'yes',
224
+ ),
225
+ );
226
+
227
+ $defaultFormFields = array_merge($defaultFormFields, $magicCheckoutConfigFields);
228
+
229
+ }
includes/api/auth.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * custom auth to secure 1cc APIs
5
+ */
6
+
7
+ function checkAuthCredentials()
8
+ {
9
+ return true;
10
+ }
11
+
12
+ ?>
includes/api/cart.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * For cart related functionality
4
+ */
5
+
6
+ /**
7
+ * Create the cart object for the line items exist in order
8
+ */
9
+ function create1ccCart($orderId)
10
+ {
11
+ global $woocommerce;
12
+
13
+ $order = wc_get_order($orderId);
14
+
15
+ if ($order && $order->get_item_count() > 0) {
16
+ foreach ($order->get_items() as $item_id => $item) {
17
+ $productId = $item->get_product_id();
18
+ $variationId = $item->get_variation_id();
19
+ $quantity = $item->get_quantity();
20
+ $customData["item_id"] = $item_id;
21
+
22
+ WC()->cart->add_to_cart(
23
+ $productId,
24
+ $quantity,
25
+ $variationId,
26
+ [],
27
+ $customData
28
+ );
29
+ }
30
+
31
+ return true;
32
+ } else {
33
+ return false;
34
+ }
35
+ }
includes/api/coupon-apply.php ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * for coupon related API
5
+ */
6
+
7
+ function applyCouponOnCart(WP_REST_Request $request)
8
+ {
9
+ global $woocommerce;
10
+
11
+ $status = 400;
12
+ $failure_reason = "";
13
+
14
+ $params = $request->get_params();
15
+
16
+ $logObj = [];
17
+ $logObj["api"] = "applyCouponOnCart";
18
+ $logObj["params"] = $params;
19
+
20
+ $validateInput = validateApplyCouponApi($params);
21
+
22
+ if ($validateInput != null) {
23
+ $response["failure_reason"] = $validateInput;
24
+ $response["failure_code"] = "VALIDATION_ERROR";
25
+ $logObj["response"] = $response;
26
+
27
+ rzpLogError(json_encode($logObj));
28
+
29
+ return new WP_REST_Response($response, 400);
30
+ }
31
+
32
+ $couponCode = sanitize_text_field($params["code"]);
33
+ $email = sanitize_text_field($params["email"]) ?? "";
34
+ $orderId = sanitize_text_field($params["order_id"]);
35
+
36
+ // initializes the session
37
+ initCustomerSessionAndCart();
38
+
39
+ // Set current user for smart coupon plugin
40
+ if (is_plugin_active('wt-smart-coupons-for-woocommerce/wt-smart-coupon.php')) {
41
+ if (empty($email) === false) {
42
+ $user = get_user_by('email', $email);
43
+ wp_set_current_user($user->id);
44
+ }
45
+ }
46
+
47
+ // check for individual specific coupons
48
+ // cart->apply does not enforce this
49
+ $coupon = new WC_Coupon($couponCode);
50
+
51
+ // check the enable coupon option
52
+ if (get_option("woocommerce_enable_coupons") === "no") {
53
+ $response["failure_reason"] = "Coupon feature disabled";
54
+ $response["failure_code"] = "INVALID_COUPON";
55
+ $logObj["response"] = $response;
56
+
57
+ rzpLogError(json_encode($logObj));
58
+
59
+ return new WP_REST_Response($response, 400);
60
+ }
61
+
62
+ //check woo-discount-rule plugin disabling the coupons
63
+ $discountOptions = get_option('woo-discount-config-v2', []);
64
+ if (!empty($discountOptions)) {
65
+ $isCouponEnabled = $discountOptions['disable_coupon_when_rule_applied'];
66
+ if ($isCouponEnabled == 'disable_coupon') {
67
+ $response["failure_reason"] = "Coupon feature disabled";
68
+ $response["failure_code"] = "INVALID_COUPON";
69
+ $logObj["response"] = $response;
70
+
71
+ rzpLogError(json_encode($logObj));
72
+
73
+ return new WP_REST_Response($response, 400);
74
+ }
75
+ }
76
+
77
+ if (empty($coupon->get_email_restrictions()) === false) {
78
+ if ($email == "") {
79
+ $response["failure_reason"] = "User email is required";
80
+ $response["failure_code"] = "LOGIN_REQUIRED";
81
+ $logObj["response"] = $response;
82
+
83
+ rzpLogError(json_encode($logObj));
84
+
85
+ return new WP_REST_Response($response, 400);
86
+ } elseif (in_array($email, $coupon->get_email_restrictions()) === false) {
87
+ $response["failure_reason"] = "Coupon does not exist";
88
+ $response["failure_code"] = "INVALID_COUPON";
89
+ $logObj["response"] = $response;
90
+
91
+ rzpLogError(json_encode($logObj));
92
+
93
+ return new WP_REST_Response($response, 400);
94
+ }
95
+ }
96
+
97
+ // Get coupon usage limit per user
98
+ $userLimit = $coupon->get_usage_limit_per_user();
99
+ if (!empty($userLimit)) {
100
+ $dataStore = $coupon->get_data_store();
101
+ $order = wc_get_order($orderId);
102
+ $usageCount = $order->get_customer_id() ? $dataStore->get_usage_by_user_id($coupon, $order->get_customer_id()) : $dataStore->get_usage_by_email($coupon, $email);
103
+
104
+ if (!empty($usageCount) && !empty($userLimit)) {
105
+ // Calculate remaining
106
+ $remainingCount = $userLimit - $usageCount;
107
+
108
+ if ($remainingCount <= 0) {
109
+ $response["failure_reason"] = "Coupon usage limit has been reached";
110
+ $response["failure_code"] = "REQUIREMENT_NOT_MET";
111
+ $logObj["response"] = $response;
112
+
113
+ rzpLogError(json_encode($logObj));
114
+
115
+ return new WP_REST_Response($response, 400);
116
+ }
117
+ }
118
+ }
119
+
120
+ // to clear any residual notices
121
+ $temp = wc_print_notices(true);
122
+
123
+ WC()->cart->remove_coupon($couponCode);
124
+ WC()->cart->empty_cart();
125
+
126
+ $cart1cc = create1ccCart($orderId);
127
+
128
+ if ($cart1cc) {
129
+ $applyCoupon = WC()->cart->add_discount($couponCode);
130
+
131
+ if ($applyCoupon === true) {
132
+ $status = true;
133
+ } else {
134
+ $markup = wc_print_notices(true);
135
+ $errorArray = explode("<li>", $markup);
136
+ $errorMessage = preg_replace(
137
+ "/\t|\n/",
138
+ "",
139
+ strip_tags(end($errorArray))
140
+ );
141
+ $failureReason = html_entity_decode($errorMessage);
142
+ }
143
+ } else {
144
+ $invalidCartResponse = [];
145
+ $invalidCartResponse["failure_reason"] = "Invalid merchant order id";
146
+ $invalidCartResponse["failure_code"] = "VALIDATION_ERROR";
147
+
148
+ $logObj["response"] = $invalidCartResponse;
149
+
150
+ rzpLogError(json_encode($logObj));
151
+ return new WP_REST_Response($invalidCartResponse, 400);
152
+ }
153
+
154
+ $newAmount = (WC()->cart->cart_contents_total + WC()->cart->tax_total) * 100;
155
+ $discountAmount = (WC()->cart->get_cart_discount_tax_total() + WC()->cart->get_cart_discount_total()) * 100;
156
+
157
+ $couponError = getApplyCouponErrorCodes($failureReason);
158
+
159
+ $promotion = [];
160
+ $promotion["code"] = $couponCode;
161
+ $promotion["reference_id"] = $couponCode;
162
+ $promotion["value"] = round($discountAmount ?? 0);
163
+ $response["promotion"] = $promotion;
164
+
165
+ if ($couponError["failure_reason"] === "") {
166
+ $logObj["response"] = $response;
167
+ rzpLogInfo(json_encode($logObj));
168
+ return new WP_REST_Response($response, 200);
169
+ } else {
170
+ $logObj["response"] = array_merge($response, $couponError);
171
+ rzpLogError(json_encode($logObj));
172
+ return new WP_REST_Response($couponError, 400);
173
+ }
174
+ }
175
+
176
+ function getApplyCouponErrorCodes($failureMessage)
177
+ {
178
+ $result = [];
179
+ $result["failure_code"] = "REQUIREMENT_NOT_MET";
180
+
181
+ if ($failureMessage === "" || is_null($failureMessage)) {
182
+ $result["failure_reason"] = "";
183
+ $result["failure_code"] = "";
184
+ } elseif (stripos($failureMessage, "does not exist") !== false) {
185
+ $result["failure_reason"] = "Coupon does not exist";
186
+ $result["failure_code"] = "INVALID_COUPON";
187
+ } elseif (stripos($failureMessage, "coupon has expired") !== false) {
188
+ $result["failure_reason"] = "This coupon has expired";
189
+ } elseif (stripos($failureMessage, "minimum spend") !== false) {
190
+ $result["failure_reason"] = "Cart is below the minimum amount";
191
+ } elseif (stripos($failureMessage, "maximum spend") !== false) {
192
+ $result["failure_reason"] = "Cart is above maximum allowed amount";
193
+ } elseif (
194
+ stripos($failureMessage, "not applicable to selected products") !==
195
+ false
196
+ ) {
197
+ $result["failure_reason"] = "Required product is missing";
198
+ } elseif (
199
+ stripos($failureMessage, "Coupon usage limit has been reached") !==
200
+ false
201
+ ) {
202
+ $result["failure_reason"] = "Coupon usage limit has been reached";
203
+ } else {
204
+ $result["failure_reason"] = "Coupon could not be applied";
205
+ $result["failure_code"] = "INVALID_COUPON";
206
+ }
207
+
208
+ return $result;
209
+ }
210
+
211
+ function validateApplyCouponApi($param)
212
+ {
213
+ if (empty(sanitize_text_field($param["code"])) === true) {
214
+ $failureReason = "Field code is required.";
215
+ } elseif (empty(sanitize_text_field($param["order_id"])) === true) {
216
+ $failureReason = "Field order id is required.";
217
+ }
218
+ return $failureReason;
219
+ }
includes/api/coupon-get.php ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * for coupon related API
5
+ */
6
+
7
+ /**
8
+ * create cart from "order_id" using $cart_1cc = create1ccCart($merchant_order_id);
9
+ * get total amount of items from the cart (replace $amount with that)
10
+ * run the query for coupons
11
+ * apply checks for expired coupons (see GMT time)
12
+ * check for min cart amount condition
13
+ * check if the email exists in `$coupon->get_email_restrictions())`
14
+ * convert all amounts to int in paise
15
+ * return whatever clears
16
+ */
17
+ function getCouponList($request)
18
+ {
19
+ global $woocommerce;
20
+ $couponData = [];
21
+
22
+ $params = $request->get_params();
23
+ $logObj = array();
24
+ $logObj['api'] = 'getCouponList';
25
+ $logObj['params'] = $params;
26
+
27
+ $orderId = sanitize_text_field($request->get_params()['order_id']);
28
+ $order = wc_get_order($orderId);
29
+
30
+ if (!$order) {
31
+ $response['failure_reason'] = 'Invalid merchant order id';
32
+ $response['failure_code'] = 'VALIDATION_ERROR';
33
+ $statusCode = 400;
34
+ $logObj['response'] = $response;
35
+ $logObj['status_code'] = $statusCode;
36
+ rzpLogError(json_encode($logObj));
37
+ return new WP_REST_Response($response, $statusCode);
38
+ }
39
+
40
+ $amount = floatval($order->get_total());
41
+ $email = sanitize_text_field($request->get_params()['email']);
42
+ $contact = sanitize_text_field($request->get_params()['contact']);
43
+
44
+ //Updating the email address to wc order.
45
+ if (empty($email) == false) {
46
+ update_post_meta($orderId, '_billing_email', $email);
47
+ update_post_meta($orderId, '_shipping_email', $email);
48
+ }
49
+
50
+ if (empty($contact) == false) {
51
+ update_post_meta($orderId, '_billing_phone', $contact);
52
+ update_post_meta($orderId, '_shipping_phone', $contact);
53
+ }
54
+
55
+ $args = array(
56
+ 'post_type' => 'shop_coupon',
57
+ 'orderby' => 'title',
58
+ 'order' => 'ASC',
59
+ 'meta_query' => array(
60
+ array(
61
+ 'key' => 'discount_type',
62
+ 'value' => array('fixed_cart', 'percent', 'fixed_product'),
63
+ 'compare' => 'IN',
64
+ ),
65
+ ),
66
+ 'fields' => 'ids',
67
+ 'posts_per_page' => -1, // By default WP_Query will return only 10 posts, to avoid that we need to pass -1
68
+ );
69
+
70
+ //check woo-discount-rule plugin disabling the coupons
71
+ $discountOptions = get_option('woo-discount-config-v2', []);
72
+ if (!empty($discountOptions)) {
73
+ $isCouponEnabled = $discountOptions['disable_coupon_when_rule_applied'];
74
+ if ($isCouponEnabled == 'disable_coupon') {
75
+ $args = array();
76
+ }
77
+ }
78
+
79
+ $coupons = new WP_Query($args);
80
+
81
+ $couponData['promotions'] = array();
82
+
83
+ if ($coupons->have_posts() && 'yes' === get_option('woocommerce_enable_coupons')) {
84
+ while ($coupons->have_posts()) {
85
+ $coupons->the_post();
86
+ $coupon = new WC_Coupon(get_the_ID());
87
+ $items = $order->get_items();
88
+ $couponMinAmount = floatval($coupon->get_minimum_amount());
89
+ $couponMaxAmount = floatval($coupon->get_maximum_amount());
90
+ $couponExpiryDate = $coupon->get_date_expires() ? $coupon->get_date_expires()->getTimestamp() : null;
91
+
92
+ //check coupon description
93
+ if (empty($coupon->get_description()) === true) {
94
+ continue;
95
+ }
96
+
97
+ // validation for email coupon
98
+ if (empty($coupon->get_email_restrictions()) === false) {
99
+ if (empty($email) === true || in_array($email, $coupon->get_email_restrictions()) === false) {
100
+ continue;
101
+ }
102
+ }
103
+
104
+ if (
105
+ ($amount < $couponMinAmount)
106
+ || (($amount > $couponMaxAmount) && ($couponMaxAmount != 0))
107
+ || ($couponExpiryDate !== null && $couponExpiryDate < time())
108
+ ) {
109
+ continue;
110
+ }
111
+
112
+ // Get usage count
113
+ $count = $coupon->get_usage_count();
114
+ // Get coupon limit
115
+ $limit = $coupon->get_usage_limit();
116
+
117
+ if (!empty($count) && !empty($limit)) {
118
+ // Calculate remaining
119
+ $remaining = $limit - $count;
120
+ if ($remaining <= 0) {
121
+ continue;
122
+ }
123
+ }
124
+
125
+ // Get coupon usage limit per user
126
+ $userLimit = $coupon->get_usage_limit_per_user();
127
+
128
+ if (!empty($userLimit)) {
129
+ $dataStore = $coupon->get_data_store();
130
+ $usageCount = $order->get_customer_id() ? $dataStore->get_usage_by_user_id($coupon, $order->get_customer_id()) : $dataStore->get_usage_by_email($coupon, $email);
131
+
132
+ if (!empty($usageCount) && !empty($userLimit)) {
133
+ // Calculate remaining
134
+ $remainingCount = $userLimit - $usageCount;
135
+ if ($remainingCount <= 0) {
136
+ continue;
137
+ }
138
+ }
139
+ }
140
+
141
+ // Add item based coupons
142
+ if (count($coupon->get_product_ids()) > 0) {
143
+ $valid = false;
144
+ // TODO: fix this logic
145
+ foreach ($items as $item) {
146
+ if (in_array($item->get_product_id(), $coupon->get_product_ids()) || in_array($item->get_variation_id(), $coupon->get_product_ids())) {
147
+ $valid = true;
148
+ break;
149
+ }
150
+ }
151
+ if (!$valid) {
152
+ continue;
153
+ }
154
+ }
155
+
156
+ // Exclude item based coupons
157
+ if (count($coupon->get_excluded_product_ids()) > 0) {
158
+ $valid = false;
159
+ foreach ($items as $item) {
160
+ if (in_array($item->get_product_id(), $coupon->get_excluded_product_ids()) || in_array($item->get_variation_id(), $coupon->get_excluded_product_ids())) {
161
+ $valid = true;
162
+ break;
163
+ }
164
+ }
165
+ if ($valid) {
166
+ continue;
167
+ }
168
+ }
169
+
170
+ // include and exclude product category items
171
+ if (count($coupon->get_excluded_product_categories()) > 0) {
172
+ $categories = array();
173
+ foreach ($items as $item) {
174
+ $product_cats = wc_get_product_cat_ids($item->get_product_id());
175
+ $cat_id_list = array_intersect($product_cats, $coupon->get_excluded_product_categories());
176
+ if (count($cat_id_list) > 0) {
177
+ foreach ($cat_id_list as $cat_id) {
178
+ $cat = get_term($cat_id, 'product_cat');
179
+ $categories[] = $cat->name;
180
+ }
181
+ }
182
+ }
183
+
184
+ if (!empty($categories)) {
185
+ continue;
186
+ }
187
+ }
188
+
189
+ if (count($coupon->get_product_categories()) > 0) {
190
+ $valid = false;
191
+ foreach ($items as $item) {
192
+ $product_cats = wc_get_product_cat_ids($item->get_product_id());
193
+ if (count(array_intersect($product_cats, $coupon->get_product_categories())) > 0) {
194
+ $valid = true;
195
+ break;
196
+ }
197
+ }
198
+
199
+ if (!$valid) {
200
+ continue;
201
+ }
202
+ }
203
+
204
+ // exclude sale item from coupons
205
+ if ($coupon->get_exclude_sale_items()) {
206
+ $valid = false;
207
+ foreach ($items as $item) {
208
+ $product = new WC_Product($item->get_product_id());
209
+ if ($product->is_on_sale()) {
210
+ $valid = true;
211
+ break;
212
+ }
213
+ }
214
+
215
+ if ($valid) {
216
+ continue;
217
+ }
218
+ }
219
+
220
+ // Check for smart coupon plugin
221
+ if (is_plugin_active('wt-smart-coupons-for-woocommerce/wt-smart-coupon.php')) {
222
+ initCustomerSessionAndCart();
223
+ // Cleanup cart.
224
+ WC()->cart->empty_cart();
225
+ create1ccCart($orderId);
226
+ $smartCoupon = new Wt_Smart_Coupon_Public(" ", " ");
227
+
228
+ // Quantity of matching Products
229
+ $minMatchingProductQty = get_post_meta($coupon->get_id(), '_wt_min_matching_product_qty', true);
230
+ $maxMatchingProductQty = get_post_meta($coupon->get_id(), '_wt_max_matching_product_qty', true);
231
+
232
+ if ($minMatchingProductQty > 0 || $maxMatchingProductQty > 0) {
233
+ $quantityMatchingProduct = $smartCoupon->get_quantity_of_matching_product($coupon);
234
+ if ($minMatchingProductQty > 0 && $quantityMatchingProduct < $minMatchingProductQty) {
235
+ continue;
236
+ }
237
+ if ($maxMatchingProductQty > 0 && $quantityMatchingProduct > $maxMatchingProductQty) {
238
+ continue;
239
+ }
240
+ }
241
+
242
+ // Subtotal of matching products
243
+ $minMatchingProductSubtotal = get_post_meta($coupon->get_id(), '_wt_min_matching_product_subtotal', true);
244
+ $maxMatchingProductSubtotal = get_post_meta($coupon->get_id(), '_wt_max_matching_product_subtotal', true);
245
+
246
+ if ($minMatchingProductSubtotal !== 0 || $maxMatchingProductSubtotal !== 0) {
247
+ $subtotalMatchingProduct = $smartCoupon->get_sub_total_of_matching_products($coupon);
248
+ if ($minMatchingProductSubtotal > 0 && $subtotalMatchingProduct < $minMatchingProductSubtotal) {
249
+ continue;
250
+ }
251
+ if ($maxMatchingProductSubtotal > 0 && $subtotalMatchingProduct > $maxMatchingProductSubtotal) {
252
+ continue;
253
+ }
254
+ }
255
+
256
+ // User role restriction
257
+ $userRoles = get_post_meta($coupon->get_id(), '_wt_sc_user_roles', true);
258
+ if ('' != $userRoles && !is_array($userRoles)) {
259
+ $userRoles = explode(',', $userRoles);
260
+ } else {
261
+ $userRoles = array();
262
+ }
263
+
264
+ if (sizeof($userRoles) > 0) {
265
+ if (empty($email) === false) {
266
+ $user = get_user_by('email', $email);
267
+ $role = !empty($user) ? $user->roles : [];
268
+
269
+ if (!array_intersect($userRoles, $role)) {
270
+ continue;
271
+ }
272
+ } else {
273
+ continue;
274
+ }
275
+ }
276
+ }
277
+
278
+ $couponData['promotions'][] = transformCouponResponse($coupon);
279
+ }
280
+ }
281
+
282
+ $logObj['response'] = $couponData;
283
+ $statusCode = 200;
284
+ $logObj['status_code'] = $statusCode;
285
+ rzpLogInfo(json_encode($logObj));
286
+ return new WP_REST_Response($couponData, $statusCode);
287
+ }
288
+
289
+ function transformCouponResponse($coupon)
290
+ {
291
+ return array(
292
+ 'code' => $coupon->get_code(),
293
+ 'summary' => $coupon->get_description(),
294
+ 'tnc' => [],
295
+ );
296
+ }
297
+
298
+ function transformAmountForRzp($amount)
299
+ {
300
+ return wc_format_decimal($amount, 2) * 100;
301
+ }
includes/api/order.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * create order with status pending
5
+ * user, adddress, coupon and shipping are left blank
6
+ */
7
+ function createWcOrder(WP_REST_Request $request)
8
+ {
9
+ rzpLogInfo("createWcOrder");
10
+ global $woocommerce;
11
+ $params = $request->get_params();
12
+ $logObj = array();
13
+ $logObj['api'] = 'createWcOrder';
14
+ $logObj['params'] = $params;
15
+
16
+ //Abandoment cart plugin decode the coupon code from token
17
+ $couponCode = null;
18
+ if (isset($params['token'])) {
19
+ $token = sanitize_text_field($params['token']);
20
+ parse_str(base64_decode(urldecode($token)), $token);
21
+ if (is_array($token) && array_key_exists('wcf_session_id', $token) && isset($token['wcf_coupon_code'])) {
22
+ $couponCode = $token['wcf_coupon_code'];
23
+ }
24
+ }
25
+
26
+ $nonce = $request->get_header('X-WP-Nonce');
27
+ $verifyReq = wp_verify_nonce($nonce, 'wp_rest');
28
+
29
+ if ($verifyReq === false) {
30
+ $response['status'] = false;
31
+ $response['message'] = 'Authentication failed';
32
+
33
+ $statusCode = 401;
34
+ $logObj['status_code'] = $statusCode;
35
+ $logObj['response'] = $response;
36
+ rzpLogError(json_encode($logObj));
37
+
38
+ return new WP_REST_Response($response, $statusCode);
39
+ }
40
+
41
+ initCustomerSessionAndCart();
42
+
43
+ if (empty($params['pdpCheckout']) === false) {
44
+ $variations = [];
45
+ // Cleanup cart.
46
+ WC()->cart->empty_cart();
47
+
48
+ $variation_id = (empty($params['variationId']) === false) ? (int) $params['variationId'] : 0;
49
+
50
+ if (empty($params['variations']) === false) {
51
+ $variations_arr = json_decode($params['variations'], true);
52
+
53
+ foreach ($variations_arr as $key => $value) {
54
+ $var_key = explode('_', $key);
55
+ $variations_key[] = ucwords(end($var_key));
56
+ $variations_val[] = ucwords($value);
57
+ }
58
+
59
+ $variations = array_combine($variations_key, $variations_val);
60
+ }
61
+
62
+ //To add custom fields to buy now orders
63
+ if (empty($params['fieldObj']) === false) {
64
+ foreach ($params['fieldObj'] as $key => $value) {
65
+ if (!empty($value)) {
66
+ $variations[$key] = $value;
67
+ }
68
+ }
69
+ }
70
+
71
+ WC()->cart->add_to_cart($params['productId'], $params['quantity'], $variation_id, $variations);
72
+ }
73
+
74
+ // check if cart is empty
75
+ if (WC()->cart->get_cart_contents_count() == 0) {
76
+ $response['message'] = 'Cart cannot be empty';
77
+ $response['code'] = 'BAD_REQUEST_EMPTY_CART';
78
+
79
+ $statusCode = 400;
80
+ $logObj['status_code'] = $statusCode;
81
+ $logObj['response'] = $response;
82
+ rzpLogError(json_encode($logObj));
83
+
84
+ return new WP_REST_Response($response, $statusCode);
85
+ }
86
+
87
+ $cartHash = WC()->cart->get_cart_hash();
88
+
89
+ $orderIdFromHash = $woocommerce->session->get(RZP_1CC_CART_HASH . $cartHash);
90
+
91
+ if ($orderIdFromHash == null) {
92
+ $checkout = WC()->checkout();
93
+ $orderId = $checkout->create_order(array());
94
+ } else {
95
+ $existingOrder = wc_get_order($orderIdFromHash);
96
+ $existingOrder->calculate_totals();
97
+
98
+ if ($existingOrder->needs_payment() == false) {
99
+ $woocommerce->session->__unset(RZP_1CC_CART_HASH . $cartHash);
100
+ $checkout = WC()->checkout();
101
+ $orderId = $checkout->create_order(array());
102
+ } else {
103
+ $orderId = $woocommerce->session->get(RZP_1CC_CART_HASH . $cartHash);
104
+ }
105
+ }
106
+
107
+ $order = wc_get_order($orderId);
108
+
109
+ //To remove by default shipping method added on order.
110
+ $items = (array) $order->get_items('shipping');
111
+
112
+ if (sizeof($items) > 0) {
113
+ // Loop through shipping items
114
+ foreach ($items as $item_id => $item) {
115
+ $order->remove_item($item_id);
116
+ }
117
+ }
118
+
119
+ $order->calculate_totals();
120
+ if ($order) {
121
+ update_post_meta($orderId, 'is_magic_checkout_order', 'yes');
122
+
123
+ $minCartAmount1cc = !empty(get_option('woocommerce_razorpay_settings')['1cc_min_cart_amount']) ? get_option('woocommerce_razorpay_settings')['1cc_min_cart_amount'] : 0;
124
+
125
+ // Response sent to the user when order creation fails
126
+ if ($order->get_total() < $minCartAmount1cc) {
127
+ $response['status'] = false;
128
+ $response['message'] = 'Your current order total is ₹' . $order->get_total() . ' — you must have an order with a minimum of ₹' . $minCartAmount1cc . ' to place your order';
129
+ $response['code'] = 'MIN_CART_AMOUNT_CHECK_FAILED';
130
+
131
+ $status = 400;
132
+ $logObj['response'] = $response;
133
+ $logObj['rzp_order_id'] = $rzp_order_id;
134
+ $logObj['rzp_response'] = $rzp_response;
135
+ rzpLogError(json_encode($logObj));
136
+
137
+ return new WP_REST_Response($response, $status);
138
+ }
139
+
140
+ $razorpay = new WC_Razorpay(false);
141
+
142
+ $rzp_order_id = $razorpay->createOrGetRazorpayOrderId($orderId, 'yes');
143
+ $rzp_response = $razorpay->getDefaultCheckoutArguments($order);
144
+
145
+ // Response sent to the user when order creation fails
146
+ if (empty($rzp_response['order_id'])) {
147
+ $response['status'] = false;
148
+ $response['message'] = 'Unable to create order';
149
+ $response['code'] = 'ORDER_CREATION_FAILED';
150
+
151
+ $status = 400;
152
+ $logObj['response'] = $response;
153
+ $logObj['rzp_order_id'] = $rzp_order_id;
154
+ $logObj['rzp_response'] = $rzp_response;
155
+ rzpLogError(json_encode($logObj));
156
+
157
+ return new WP_REST_Response($response, $status);
158
+ }
159
+
160
+ // TODO: getDefaultCheckoutArguments() is already being called in L65 above
161
+ $response = $razorpay->getDefaultCheckoutArguments($order);
162
+
163
+ $current_user = wp_get_current_user();
164
+
165
+ if ($current_user instanceof WP_User) {
166
+ update_post_meta($orderId, '_customer_user', $current_user->ID);
167
+ $response['prefill']['email'] = $current_user->user_email ?? '';
168
+ $contact = get_user_meta($current_user->ID, 'billing_phone', true);
169
+ $response['prefill']['contact'] = $contact ? $contact : '';
170
+ }
171
+
172
+ $response['prefill']['coupon_code'] = $couponCode;
173
+
174
+ $response['mandatory_login'] = get_option('woocommerce_razorpay_settings')['enable_1cc_mandatory_login'] === 'yes' ? true : false;
175
+
176
+ $response['enable_ga_analytics'] = get_option('woocommerce_razorpay_settings')['enable_1cc_ga_analytics'] === 'yes' ? true : false;
177
+ $response['enable_fb_analytics'] = get_option('woocommerce_razorpay_settings')['enable_1cc_fb_analytics'] === 'yes' ? true : false;
178
+ $response['redirect'] = true;
179
+ $response['one_click_checkout'] = true;
180
+
181
+ if ($response['enable_fb_analytics'] === true) {
182
+ //Customer cart related data for FB analytics.
183
+ $customer_cart['value'] = (string) WC()->cart->subtotal;
184
+ $customer_cart['content_type'] = 'product';
185
+ $customer_cart['currency'] = 'INR';
186
+
187
+ $x = 0;
188
+ // Loop over $cart items
189
+ foreach (WC()->cart->get_cart() as $cart_item) {
190
+
191
+ $customer_cart['contents'][$x]['id'] = (string) $cart_item['product_id'];
192
+ $customer_cart['contents'][$x]['name'] = $cart_item['data']->get_title();
193
+ $customer_cart['contents'][$x]['quantity'] = (string) $cart_item['quantity'];
194
+ $customer_cart['contents'][$x]['value'] = (string) ($cart_item['line_subtotal'] + $cart_item['line_subtotal_tax']) / $cart_item['quantity'];
195
+ $customer_cart['contents'][$x]['variant_id'] = (string) $cart_item['variation_id'];
196
+
197
+ $x++;
198
+ }
199
+
200
+ $response['customer_cart'] = $customer_cart ?? '';
201
+ }
202
+
203
+ if (empty(get_option('woocommerce_razorpay_settings')['enable_1cc_cod_intelligence']) === true
204
+ || get_option('woocommerce_razorpay_settings')['enable_1cc_cod_intelligence'] != 'yes') {
205
+ $response['force_cod'] = true;
206
+ }
207
+
208
+ $woocommerce->session->set(RZP_1CC_CART_HASH . $cartHash, $orderId);
209
+ set_transient(RZP_1CC_CART_HASH . $orderId, $cartHash, 3600);
210
+ set_transient($razorpay::SESSION_KEY, $orderId, 3600);
211
+
212
+ $logObj['response'] = $response;
213
+ rzpLogInfo(json_encode($logObj));
214
+
215
+ return new WP_REST_Response($response, 200);
216
+ } else {
217
+ $response['status'] = false;
218
+ $response['message'] = 'Unable to create woocommerce order';
219
+ $response['code'] = 'WOOCOMMERCE_ORDER_CREATION_FAILED';
220
+
221
+ $logObj['response'] = $response;
222
+ $logObj['status_code'] = 400;
223
+ rzpLogError(json_encode($logObj));
224
+
225
+ return new WP_REST_Response($response, 400);
226
+ }
227
+ }
includes/api/save-abandonment-data.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * For abandon cart recovery related API
4
+ */
5
+
6
+ function saveCartAbandonmentData(WP_REST_Request $request)
7
+ {
8
+ global $woocommerce;
9
+ global $wpdb;
10
+
11
+ $params = $request->get_params();
12
+ $rzpOrderId = sanitize_text_field($params['order_id']);
13
+
14
+ $logObj = array();
15
+ $logObj['api'] = "saveCartAbandonmentData";
16
+ $logObj['params'] = $params;
17
+
18
+ $razorpay = new WC_Razorpay(false);
19
+ $api = $razorpay->getRazorpayApiInstance();
20
+ try
21
+ {
22
+ $razorpayData = $api->order->fetch($rzpOrderId);
23
+ } catch (Exception $e) {
24
+ $response['status'] = false;
25
+ $response['message'] = 'RZP order id does not exist';
26
+ $statusCode = 400;
27
+
28
+ $logObj['response'] = $response;
29
+ $logObj['status_code'] = $statusCode;
30
+ rzpLogError(json_encode($logObj));
31
+
32
+ return new WP_REST_Response($response, $statusCode);
33
+ }
34
+
35
+ if (isset($razorpayData['receipt'])) {
36
+ $wcOrderId = $razorpayData['receipt'];
37
+
38
+ $order = wc_get_order($wcOrderId);
39
+ }
40
+
41
+ $razorpay->UpdateOrderAddress($razorpayData, $order);
42
+
43
+ initCustomerSessionAndCart();
44
+
45
+ $customerEmail = get_post_meta($wcOrderId, '_billing_email', true);
46
+
47
+ //Retrieving cart products and their quantities.
48
+ // check plugin is activated or not
49
+ rzpLogInfo('Woocommerce order id:');
50
+ rzpLogInfo(json_encode($wcOrderId));
51
+
52
+ if (is_plugin_active('woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php') && empty($customerEmail) == false) {
53
+
54
+ $products = WC()->cart->get_cart();
55
+ $currentTime = current_time('Y-m-d H:i:s');
56
+
57
+ if (isset($razorpayData['shipping_fee'])) {
58
+ $cartTotal = $razorpayData['amount'] / 100 - $razorpayData['shipping_fee'] / 100;
59
+ } else {
60
+ $cartTotal = $razorpayData['amount'] / 100;
61
+ }
62
+
63
+ $otherFields = array(
64
+ 'wcf_billing_company' => "",
65
+ 'wcf_billing_address_1' => $razorpayData['customer_details']['billing_address']['line1'] ?? '',
66
+ 'wcf_billing_address_2' => $razorpayData['customer_details']['billing_address']['line2'] ?? '',
67
+ 'wcf_billing_state' => $razorpayData['customer_details']['billing_address']['state'] ?? '',
68
+ 'wcf_billing_postcode' => $razorpayData['customer_details']['billing_address']['zipcode'] ?? '',
69
+ 'wcf_shipping_first_name' => $razorpayData['customer_details']['billing_address']['name'] ?? '',
70
+ 'wcf_shipping_last_name' => "",
71
+ 'wcf_shipping_company' => "",
72
+ 'wcf_shipping_country' => $razorpayData['customer_details']['shipping_address']['country'] ?? '',
73
+ 'wcf_shipping_address_1' => $razorpayData['customer_details']['shipping_address']['line1'] ?? '',
74
+ 'wcf_shipping_address_2' => $razorpayData['customer_details']['shipping_address']['line2'] ?? '',
75
+ 'wcf_shipping_city' => $razorpayData['customer_details']['shipping_address']['city'] ?? '',
76
+ 'wcf_shipping_state' => $razorpayData['customer_details']['shipping_address']['state'] ?? '',
77
+ 'wcf_shipping_postcode' => $razorpayData['customer_details']['shipping_address']['zipcode'] ?? '',
78
+ 'wcf_order_comments' => "",
79
+ 'wcf_first_name' => $razorpayData['customer_details']['shipping_address']['name'] ?? '',
80
+ 'wcf_last_name' => "",
81
+ 'wcf_phone_number' => $razorpayData['customer_details']['shipping_address']['contact'] ?? '',
82
+ 'wcf_location' => $razorpayData['customer_details']['shipping_address']['country'] ?? '',
83
+ );
84
+
85
+ $checkoutDetails = array(
86
+ 'email' => $razorpayData['customer_details']['email'] ?? $customerEmail,
87
+ 'cart_contents' => serialize($products),
88
+ 'cart_total' => sanitize_text_field($cartTotal),
89
+ 'time' => $currentTime,
90
+ 'other_fields' => serialize($otherFields),
91
+ 'checkout_id' => wc_get_page_id('cart'),
92
+ );
93
+
94
+ $sessionId = WC()->session->get('wcf_session_id');
95
+
96
+ $cartAbandonmentTable = $wpdb->prefix . "cartflows_ca_cart_abandonment";
97
+
98
+ $logObj['checkoutDetails'] = $checkoutDetails;
99
+
100
+ if (empty($checkoutDetails) == false) {
101
+ $result = $wpdb->get_row(
102
+ $wpdb->prepare('SELECT * FROM `' . $cartAbandonmentTable . '` WHERE session_id = %s and order_status IN (%s, %s)', $sessionId, 'normal', 'abandoned') // phpcs:ignore
103
+ );
104
+
105
+ if (isset($result)) {
106
+ $wpdb->update(
107
+ $cartAbandonmentTable,
108
+ $checkoutDetails,
109
+ array('session_id' => $sessionId)
110
+ );
111
+
112
+ if ($wpdb->last_error) {
113
+ $response['status'] = false;
114
+ $response['message'] = $wpdb->last_error;
115
+ $statusCode = 400;
116
+ } else {
117
+ $response['status'] = true;
118
+ $response['message'] = 'Data successfully updated for wooCommerce cart abandonment recovery';
119
+ $statusCode = 200;
120
+ }
121
+
122
+ } else {
123
+ $sessionId = md5(uniqid(wp_rand(), true));
124
+ $checkoutDetails['session_id'] = sanitize_text_field($sessionId);
125
+
126
+ // Inserting row into Database.
127
+ $wpdb->insert(
128
+ $cartAbandonmentTable,
129
+ $checkoutDetails
130
+ );
131
+
132
+ if ($wpdb->last_error) {
133
+ $response['status'] = false;
134
+ $response['message'] = $wpdb->last_error;
135
+ $statusCode = 400;
136
+ } else {
137
+ // Storing session_id in WooCommerce session.
138
+ WC()->session->set('wcf_session_id', $sessionId);
139
+ $response['status'] = true;
140
+ $response['message'] = 'Data successfully inserted for wooCommerce cart abandonment recovery';
141
+ $statusCode = 200;
142
+ }
143
+ }
144
+
145
+ $logObj['response'] = $response;
146
+ $logObj['status_code'] = $statusCode;
147
+ rzpLogInfo(json_encode($logObj));
148
+ }
149
+
150
+ } else {
151
+ $response['status'] = false;
152
+ $response['message'] = 'Failed to insert data';
153
+ $statusCode = 400;
154
+
155
+ $logObj['response'] = $response;
156
+ $logObj['status_code'] = $statusCode;
157
+ rzpLogInfo(json_encode($logObj));
158
+ }
159
+
160
+ return new WP_REST_Response($response, $statusCode);
161
+
162
+ }
includes/api/shipping-info.php ADDED
@@ -0,0 +1,422 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Given shipping address and product, attempts to calculate available shipping rates for the address.
4
+ * Doesn't support shipping > 1 address.
5
+ *
6
+ * @param WP_REST_Request $request JSON request for shipping endpoint.
7
+ * @return array|WP_Error|WP_REST_Response
8
+ * @throws Exception If failed to add items to cart or no shipping options available for address.
9
+ */
10
+ function calculateShipping1cc(WP_REST_Request $request)
11
+ {
12
+ $params = $request->get_params();
13
+
14
+ $logObj = array();
15
+ $logObj['api'] = 'calculateShipping1cc';
16
+ $logObj['params'] = $params;
17
+
18
+ $validateInput = validateInput('shipping', $params);
19
+
20
+ if ($validateInput != null) {
21
+ $response['failure_reason'] = $validateInput;
22
+ $response['failure_code'] = 'VALIDATION_ERROR';
23
+ $logObj['response'] = $response;
24
+ rzpLogError(json_encode($logObj));
25
+ return new WP_REST_Response($response, 400);
26
+ }
27
+
28
+ $cartResponse = false;
29
+ $orderId = (int) sanitize_text_field($params['order_id']);
30
+ $addresses = $params['addresses'];
31
+
32
+ initCustomerSessionAndCart();
33
+ // Cleanup cart.
34
+ WC()->cart->empty_cart();
35
+
36
+ $cartResponse = create1ccCart($orderId);
37
+
38
+ if ($cartResponse === false) {
39
+ $response['status'] = false;
40
+ $response['failure_reason'] = 'Invalid merchant order id';
41
+ $response['failure_code'] = 'VALIDATION_ERROR';
42
+ $logObj['response'] = $response;
43
+ rzpLogError(json_encode($logObj));
44
+ return new WP_REST_Response($response, 400);
45
+ }
46
+
47
+ foreach ($addresses as $address) {
48
+ if ($cartResponse) {
49
+ $customerResponse = shippingUpdateCustomerInformation1cc($address);
50
+ }
51
+
52
+ if ($customerResponse) {
53
+ $response[] = shippingCalculatePackages1cc($address['id'], $orderId);
54
+ } else {
55
+ $response['failure_reason'] = 'Set customer shipping information failed';
56
+ $response['failure_code'] = 'VALIDATION_ERROR';
57
+ $logger->log('info', json_encode($response), array('source' => 'rzp1cc'));
58
+ return new WP_REST_Response($response, 400);
59
+ }
60
+ }
61
+
62
+ // Cleanup cart.
63
+ WC()->cart->empty_cart();
64
+ $logObj['response'] = $response;
65
+ rzpLogInfo(json_encode($logObj));
66
+ return new WP_REST_Response(array('addresses' => $response), 200);
67
+ }
68
+
69
+ /**
70
+ * Update customer information.
71
+ *
72
+ * @param array $params The request params.
73
+ *
74
+ * @return mixed
75
+ */
76
+ function shippingUpdateCustomerInformation1cc($params)
77
+ {
78
+
79
+ $wcStateCode = normalizeWcStateCode($params['state_code']);
80
+
81
+ // Update customer information.
82
+ WC()->customer->set_props(
83
+ array(
84
+ 'shipping_country' => sanitize_text_field(strtoupper($params['country'])),
85
+ 'shipping_state' => sanitize_text_field(strtoupper($wcStateCode)),
86
+ 'shipping_postcode' => sanitize_text_field($params['zipcode']),
87
+ 'shipping_city' => sanitize_text_field($params['city']), //This field is required for custom shipping plugin support.
88
+ )
89
+ );
90
+
91
+ // Calculate shipping.
92
+ WC()->cart->calculate_shipping();
93
+ WC()->cart->calculate_totals();
94
+
95
+ // See if we need to calculate anything
96
+ if (!WC()->cart->needs_shipping()) {
97
+ return new WP_Error('shipping_methods_error', 'no shipping methods available for product and address', array('status' => 400));
98
+ }
99
+
100
+ // Return true for no error.
101
+ return true;
102
+ }
103
+
104
+ /**
105
+ * Calculate packages
106
+ *
107
+ * @return mixed
108
+ */
109
+ function shippingCalculatePackages1cc($id, $orderId)
110
+ {
111
+ // Get packages for the cart.
112
+ $packages = WC()->cart->get_shipping_packages();
113
+
114
+ // Currently we only support 1 shipping address per package.
115
+ if (count($packages) > 1) {
116
+ // Perform address check to make sure all are the same
117
+ for ($x = 1; $x < count($packages); $x++) {
118
+ if ($packages[0]->destination !== $packages[$x]->destination) {
119
+ return new WP_Error('shipping_packages', 'Shipping package to > 1 address is not supported', array('status' => 400));
120
+ }
121
+ }
122
+ }
123
+
124
+ $vendorId = array();
125
+ $isStoreShippingEnabled = "";
126
+
127
+ // check shipping option in multivendor plugin
128
+ if (class_exists('WCFMmp')) {
129
+ $shippingOptions = get_option('wcfm_shipping_options', array());
130
+ // By default store shipping should be consider enable
131
+ $isStoreShippingEnabled = isset($shippingOptions['enable_store_shipping']) ? $shippingOptions['enable_store_shipping'] : 'yes';
132
+ }
133
+
134
+ // Add package ID to array.
135
+ foreach ($packages as $key => $package) {
136
+ if (!isset($packages[$key]['package_id'])) {
137
+ $packages[$key]['package_id'] = $key;
138
+ }
139
+
140
+ if (isset($packages[$key]['vendor_id']) && $isStoreShippingEnabled == 'yes') {
141
+ $vendorId[] = $packages[$key]['vendor_id'];
142
+ }
143
+ }
144
+ $calculatedPackages = wc()->shipping()->calculate_shipping($packages);
145
+
146
+ return getItemResponse1cc($calculatedPackages, $id, $vendorId, $orderId);
147
+ }
148
+
149
+ /**
150
+ * Build JSON response for line item.
151
+ *
152
+ * @param array $package WooCommerce shipping packages.
153
+ * @return array
154
+ */
155
+ function getItemResponse1cc($package, $id, $vendorId, $orderId)
156
+ {
157
+
158
+ // Add product names and quantities.
159
+ $items = array();
160
+
161
+ //To support advancd free shipping plugin
162
+ if (is_plugin_active('woocommerce-advanced-free-shipping/woocommerce-advanced-free-shipping.php')) {
163
+ include_once ABSPATH . 'wp-content/plugins/woocommerce-advanced-free-shipping/woocommerce-advanced-free-shipping.php';
164
+
165
+ if (class_exists('Wafs_Free_Shipping_Method')) {
166
+ $wasp_method = new Wafs_Free_Shipping_Method();
167
+ $advancedFreeShipping = $wasp_method->calculate_shipping($package[0]);
168
+ }
169
+ }
170
+
171
+ $shippingResponse = prepareRatesResponse1cc($package, $vendorId, $orderId);
172
+
173
+ $isServiceable = count($shippingResponse) > 0 ? true : false;
174
+ // TODO: also return 'state'?
175
+ return array(
176
+ 'id' => $id,
177
+ 'zipcode' => $package[0]['destination']['postcode'],
178
+ 'state_code' => $package[0]['destination']['state'],
179
+ 'country' => $package[0]['destination']['country'],
180
+ 'serviceable' => $isServiceable,
181
+ 'cod' => $isServiceable === false ? false : $shippingResponse['cod'],
182
+ 'shipping_fee' => isset($shippingResponse['shipping_fee']) ? ($shippingResponse['shipping_fee'] + $shippingResponse['shipping_fee_tax']) : 0,
183
+ // hardcode as null as wc does not provide support
184
+ 'cod_fee' => null,
185
+ );
186
+ }
187
+
188
+ /**
189
+ * Prepare an array of rates from a package for the response.
190
+ *
191
+ * @param array $package Shipping package complete with rates from WooCommerce.
192
+ * @return array
193
+ */
194
+ function prepareRatesResponse1cc($package, $vendorId, $orderId)
195
+ {
196
+
197
+ $response = array();
198
+
199
+ if (isset($vendorId)) {
200
+ foreach ($vendorId as $id) {
201
+ $rates = $package[$id]['rates'];
202
+ foreach ($rates as $rate) {
203
+ $response[] = getRateResponse1cc($rate, $id, $orderId);
204
+ }
205
+ }
206
+ }
207
+
208
+ $rates = $package[0]['rates'];
209
+ foreach ($rates as $val) {
210
+ $response[] = getRateResponse1cc($val, "", $orderId);
211
+ }
212
+
213
+ if (empty($response) === true) {
214
+ return array();
215
+ }
216
+ // add shipping in postmeta for multivendor plugin
217
+ add_post_meta($orderId, '1cc_shippinginfo', $response);
218
+
219
+ // Choosing the lowest shipping rate
220
+ $price = array();
221
+ foreach ($response as $key => $row) {
222
+ $price[$key] = $row['price'];
223
+ }
224
+ // we only consider the lowest shipping fee
225
+ array_multisort($price, SORT_ASC, $response);
226
+
227
+ if (!empty($vendorId)) {
228
+ foreach ($response as $key => $row) {
229
+ $response['shipping_fee'] += isset($response[$key]['price']) ? $response[$key]['price'] : 0;
230
+ $response['shipping_fee_tax'] += !empty($response[$key]['taxes']) ? 0 : 0; //By default tax is considered as zero.
231
+ }
232
+ } else {
233
+ $response['shipping_fee'] = isset($response[0]['price']) ? $response[0]['price'] : 0;
234
+ $response['shipping_fee_tax'] = !empty($response[0]['taxes']) ? 0 : 0; //By default tax is considered as zero.
235
+ }
236
+ $response['cod'] = isset($response[0]['cod']) ? $response[0]['cod'] : false;
237
+
238
+ return $response;
239
+ }
240
+
241
+ /**
242
+ * Response for a single rate.
243
+ *
244
+ * @param WC_Shipping_Rate $rate Rate object.
245
+ * @return array
246
+ */
247
+
248
+ function getRateResponse1cc($rate, $vendorId, $orderId)
249
+ {
250
+
251
+ return array_merge(
252
+ array(
253
+ 'rate_id' => getRateProp1cc($rate, 'id'),
254
+ 'name' => prepareHtmlResponse1cc(getRateProp1cc($rate, 'label')),
255
+ 'description' => prepareHtmlResponse1cc(getRateProp1cc($rate, 'description')),
256
+ 'delivery_time' => prepareHtmlResponse1cc(getRateProp1cc($rate, 'delivery_time')),
257
+ 'price' => convertToPaisa(getRateProp1cc($rate, 'cost')),
258
+ 'taxes' => getRateProp1cc($rate, 'taxes'),
259
+ 'instance_id' => getRateProp1cc($rate, 'instance_id'),
260
+ 'method_id' => getRateProp1cc($rate, 'method_id'),
261
+ 'meta_data' => getRateMetaData1cc($rate),
262
+ 'vendor_id' => $vendorId,
263
+ 'cod' => getCodShippingInfo1cc(getRateProp1cc($rate, 'instance_id'), getRateProp1cc($rate, 'method_id'), $orderId),
264
+ ),
265
+ getStoreCurrencyResponse1cc()
266
+ );
267
+ }
268
+
269
+ /**
270
+ * Verify whether COD availbale for the shipping method
271
+ *
272
+ * @returns bool
273
+ */
274
+ function getCodShippingInfo1cc($instanceId, $methodId, $orderId)
275
+ {
276
+
277
+ global $woocommerce;
278
+
279
+ $availablePaymentMethods = WC()->payment_gateways->payment_gateways();
280
+
281
+ if (!isset($availablePaymentMethods['cod']) || 'no' == $availablePaymentMethods['cod']->enabled || !(($minCODAmount1cc <= $amount) && ($maxCODAmount1cc <= $amount))) {
282
+ return false;
283
+ }
284
+
285
+ $minCODAmount1cc = !empty(get_option('woocommerce_razorpay_settings')['1cc_min_COD_slab_amount']) ? get_option('woocommerce_razorpay_settings')['1cc_min_COD_slab_amount'] : 0;
286
+ $maxCODAmount1cc = !empty(get_option('woocommerce_razorpay_settings')['1cc_max_COD_slab_amount']) ? get_option('woocommerce_razorpay_settings')['1cc_max_COD_slab_amount'] : 0;
287
+
288
+ $order = wc_get_order($orderId);
289
+ $amount = floatval($order->get_total());
290
+
291
+ //To verify the min order amount required to place COD order
292
+ if (!($minCODAmount1cc <= $amount)) {
293
+ return false;
294
+ }
295
+
296
+ //To verify the max order amount restriction to place COD order
297
+ if ($maxCODAmount1cc != 0 && ($maxCODAmount1cc <= $amount)) {
298
+ return false;
299
+ }
300
+
301
+ if (isset($availablePaymentMethods['cod'])) {
302
+ $shipping_method_ids_cod = $availablePaymentMethods['cod']->enable_for_methods;
303
+
304
+ foreach ($shipping_method_ids_cod as $shipping_method_id) {
305
+
306
+ $shippingInstanceId[] = end(explode(':', $shipping_method_id));
307
+
308
+ if (in_array('flat_rate', $shippingInstanceId) && ($methodId === 'flat_rate')) {
309
+ return true;
310
+ } elseif (in_array('free_shipping', $shippingInstanceId) && ($methodId === 'free_shipping')) {
311
+ return true;
312
+ } elseif (in_array($instanceId, $shippingInstanceId)) {
313
+ return true;
314
+ }
315
+ }
316
+ }
317
+ return false;
318
+ }
319
+
320
+ /**
321
+ * Convert to paisa
322
+ * @returns int
323
+ */
324
+ function convertToPaisa($price)
325
+ {
326
+ if (is_string($price)) {
327
+ $price = (int) $price;
328
+ }
329
+ return $price * 100;
330
+ }
331
+
332
+ /**
333
+ * Prepares a list of store currency data to return in responses.
334
+ * @return array
335
+ */
336
+ function getStoreCurrencyResponse1cc()
337
+ {
338
+ $position = get_option('woocommerce_currency_pos');
339
+ $symbol = html_entity_decode(get_woocommerce_currency_symbol());
340
+ $prefix = '';
341
+ $suffix = '';
342
+
343
+ switch ($position) {
344
+ case 'left_space':
345
+ $prefix = $symbol . ' ';
346
+ break;
347
+ case 'left':
348
+ $prefix = $symbol;
349
+ break;
350
+ case 'right_space':
351
+ $suffix = ' ' . $symbol;
352
+ break;
353
+ case 'right':
354
+ $suffix = $symbol;
355
+ break;
356
+ default:
357
+ break;
358
+ }
359
+
360
+ return array(
361
+ 'currency_code' => get_woocommerce_currency(),
362
+ 'currency_symbol' => $symbol,
363
+ 'currency_minor_unit' => wc_get_price_decimals(),
364
+ 'currency_decimal_separator' => wc_get_price_decimal_separator(),
365
+ 'currency_thousand_separator' => wc_get_price_thousand_separator(),
366
+ 'currency_prefix' => $prefix,
367
+ 'currency_suffix' => $suffix,
368
+ );
369
+ }
370
+
371
+ /**
372
+ * Gets a prop of the rate object, if callable.
373
+ *
374
+ * @param WC_Shipping_Rate $rate Rate object.
375
+ * @param string $prop Prop name.
376
+ * @return string
377
+ */
378
+ function getRateProp1cc($rate, $prop)
379
+ {
380
+ $getter = 'get_' . $prop;
381
+ return \is_callable(array($rate, $getter)) ? $rate->$getter() : '';
382
+ }
383
+
384
+ /**
385
+ * Converts rate meta data into a suitable response object.
386
+ *
387
+ * @param WC_Shipping_Rate $rate Rate object.
388
+ * @return array
389
+ */
390
+ function getRateMetaData1cc($rate)
391
+ {
392
+ $metaData = $rate->get_meta_data();
393
+
394
+ return array_reduce(
395
+ array_keys($metaData),
396
+ function ($return, $key) use ($metaData) {
397
+ $return[] = array(
398
+ 'key' => $key,
399
+ 'value' => $metaData[$key],
400
+ );
401
+ return $return;
402
+ },
403
+ array()
404
+ );
405
+ }
406
+
407
+ /**
408
+ * Prepares HTML based content, such as post titles and content, for the API response.
409
+ *
410
+ * The wptexturize, convert_chars, and trim functions are also used in the `the_title` filter.
411
+ * The function wp_kses_post removes disallowed HTML tags.
412
+ *
413
+ * @param string|array $response Data to format.
414
+ * @return string|array Formatted data.
415
+ */
416
+ function prepareHtmlResponse1cc($response)
417
+ {
418
+ if (is_array($response)) {
419
+ return array_map('prepareHtmlResponse1cc', $response);
420
+ }
421
+ return is_scalar($response) ? wp_kses_post(trim(convert_chars(wptexturize($response)))) : $response;
422
+ }
includes/debug.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Log a message if Razorpay debug mode is enabled.
5
+ *
6
+ * @param string $level
7
+ * 'emergency': System is unusable.
8
+ * 'alert': Action must be taken immediately.
9
+ * 'critical': Critical conditions.
10
+ * 'error': Error conditions.
11
+ * 'warning': Warning conditions.
12
+ * 'notice': Normal but significant condition.
13
+ * 'info': Informational messages.
14
+ * 'debug': Debug-level messages.
15
+ * @param string $message Message to log.
16
+ */
17
+ define('RAZORPAY_LOG_NAME', 'razorpay-logs');
18
+
19
+ function rzpLog($level, $message)
20
+ {
21
+ if (isDebugModeEnabled()) {
22
+ $logger = wc_get_logger();
23
+ $logger->log($level, $message, array('source' => RAZORPAY_LOG_NAME));
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Adds an emergency level message if Razorpay debug mode is enabled
29
+ *
30
+ * System is unusable.
31
+ *
32
+ * @see WC_Logger::log
33
+ *
34
+ * @param string $message Message to log.
35
+ */
36
+ function rzpLogEmergency($message)
37
+ {
38
+ rzpLog('emergency', $message);
39
+ }
40
+
41
+ /**
42
+ * Adds an alert level message if Razorpay debug mode is enabled.
43
+ *
44
+ * Action must be taken immediately.
45
+ * Example: Entire website down, database unavailable, etc.
46
+ *
47
+ * @see WC_Logger::log
48
+ *
49
+ * @param string $message Message to log.
50
+ */
51
+ function rzpLogAlert($message)
52
+ {
53
+ rzpLog('alert', $message);
54
+ }
55
+
56
+ /**
57
+ * Adds a critical level message if Razorpay debug mode is enabled.
58
+ *
59
+ * Critical conditions.
60
+ * Example: Application component unavailable, unexpected exception.
61
+ *
62
+ * @see WC_Logger::log
63
+ *
64
+ * @param string $message Message to log.
65
+ */
66
+ function rzpLogCritical($message)
67
+ {
68
+ rzpLog('critical', $message);
69
+ }
70
+
71
+ /**
72
+ * Adds an error level message if Razorpay debug mode is enabled.
73
+ *
74
+ * Runtime errors that do not require immediate action but should typically be logged
75
+ * and monitored.
76
+ *
77
+ * @see WC_Logger::log
78
+ *
79
+ * @param string $message Message to log.
80
+ */
81
+ function rzpLogError($message)
82
+ {
83
+ rzpLog('error', $message);
84
+ }
85
+
86
+ /**
87
+ * Adds a warning level message if Razorpay debug mode is enabled.
88
+ *
89
+ * Exceptional occurrences that are not errors.
90
+ *
91
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things that are not
92
+ * necessarily wrong.
93
+ *
94
+ * @see WC_Logger::log
95
+ *
96
+ * @param string $message Message to log.
97
+ */
98
+ function rzpRazorpay_log_warning($message)
99
+ {
100
+ rzpLog('warning', $message);
101
+ }
102
+
103
+ /**
104
+ * Adds a notice level message if Razorpay debug mode is enabled.
105
+ *
106
+ * Normal but significant events.
107
+ *
108
+ * @see WC_Logger::log
109
+ *
110
+ * @param string $message Message to log.
111
+ */
112
+ function rzpLogNotice($message)
113
+ {
114
+ rzpLog('notice', $message);
115
+ }
116
+
117
+ /**
118
+ * Adds a info level message if Razorpay debug mode is enabled
119
+ *
120
+ * Interesting events.
121
+ * Example: User logs in, SQL logs
122
+ *
123
+ * @see WC_Logger::log
124
+ *
125
+ * @param string $message Message to log.
126
+ */
127
+ function rzpLogInfo($message)
128
+ {
129
+ rzpLog('info', $message);
130
+ }
131
+
132
+ /**
133
+ * Adds a debug level message if Razorpay debug mode is enabled
134
+ * Detailed debug information
135
+ * @see WC_Logger::log
136
+ * @param string $message Message to log
137
+ */
138
+ function rzpLogDebug($message)
139
+ {
140
+ rzpLog('debug', $message);
141
+ }
includes/razorpay-route.php CHANGED
@@ -1039,12 +1039,12 @@ function razorpayPaymentsView(){
1039
  function adminEnqueueScriptsFunc()
1040
  {
1041
  //$name, $src, $dependencies, $version, $in_footer
1042
- wp_enqueue_script( 'route-script', plugin_dir_url(dirname(__FILE__)) . 'js/woo_route.js', array( 'jquery' ), null, true );
1043
- wp_enqueue_script( 'bootstrap-script', plugin_dir_url(dirname(__FILE__)) . 'js/bootstrap.min.js', array( 'jquery' ), null, true );
1044
 
1045
- wp_register_style('bootstrap-css', plugin_dir_url(dirname(__FILE__)) . 'css/bootstrap.min.css',
1046
  null, null);
1047
- wp_register_style('woo_route-css', plugin_dir_url(dirname(__FILE__)) . 'css/woo_route.css',
1048
  null, null);
1049
  wp_enqueue_style('bootstrap-css');
1050
  wp_enqueue_style('woo_route-css');
1039
  function adminEnqueueScriptsFunc()
1040
  {
1041
  //$name, $src, $dependencies, $version, $in_footer
1042
+ wp_enqueue_script( 'route-script', plugin_dir_url(dirname(__FILE__)) . 'public/js/woo_route.js', array( 'jquery' ), null, true );
1043
+ wp_enqueue_script( 'bootstrap-script', plugin_dir_url(dirname(__FILE__)) . 'public/js/bootstrap.min.js', array( 'jquery' ), null, true );
1044
 
1045
+ wp_register_style('bootstrap-css', plugin_dir_url(dirname(__FILE__)) . 'public/css/bootstrap.min.css',
1046
  null, null);
1047
+ wp_register_style('woo_route-css', plugin_dir_url(dirname(__FILE__)) . 'public/css/woo_route.css',
1048
  null, null);
1049
  wp_enqueue_style('bootstrap-css');
1050
  wp_enqueue_style('woo_route-css');
includes/razorpay-webhook.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
- require_once __DIR__.'/../woo-razorpay.php';
4
- require_once __DIR__.'/../razorpay-sdk/Razorpay.php';
5
 
6
  use Razorpay\Api\Api;
7
  use Razorpay\Api\Errors;
@@ -23,13 +23,13 @@ class RZP_Webhook
23
  /**
24
  * Event constants
25
  */
26
- const PAYMENT_AUTHORIZED = 'payment.authorized';
27
- const PAYMENT_FAILED = 'payment.failed';
28
- const SUBSCRIPTION_CANCELLED = 'subscription.cancelled';
29
- const REFUNDED_CREATED = 'refund.created';
30
- const VIRTUAL_ACCOUNT_CREDITED = 'virtual_account.credited';
31
- const SUBSCRIPTION_PAUSED = 'subscription.paused';
32
- const SUBSCRIPTION_RESUMED = 'subscription.resumed';
33
 
34
  protected $eventsArray = [
35
  self::PAYMENT_AUTHORIZED,
@@ -38,7 +38,7 @@ class RZP_Webhook
38
  self::PAYMENT_FAILED,
39
  self::SUBSCRIPTION_CANCELLED,
40
  self::SUBSCRIPTION_PAUSED,
41
- self::SUBSCRIPTION_RESUMED
42
  ];
43
 
44
  public function __construct()
@@ -70,54 +70,50 @@ class RZP_Webhook
70
 
71
  $data = json_decode($post, true);
72
 
73
- if (json_last_error() !== 0)
74
- {
75
  return;
76
  }
77
 
78
  $enabled = $this->razorpay->getSetting('enable_webhook');
79
 
80
  if (($enabled === 'yes') and
81
- (empty($data['event']) === false))
82
- {
83
  // Skip the webhook if not the valid data and event
84
- if ($this->shouldConsumeWebhook($data) === false)
85
- {
86
  return;
87
  }
88
 
89
- if (isset($_SERVER['HTTP_X_RAZORPAY_SIGNATURE']) === true)
90
- {
91
  $razorpayWebhookSecret = $this->razorpay->getSetting('webhook_secret');
92
 
93
  //
94
  // If the webhook secret isn't set on wordpress, return
95
  //
96
- if (empty($razorpayWebhookSecret) === true)
97
- {
98
  return;
99
  }
100
 
101
  try
102
  {
103
  $this->api->utility->verifyWebhookSignature($post,
104
- $_SERVER['HTTP_X_RAZORPAY_SIGNATURE'],
105
- $razorpayWebhookSecret);
106
- }
107
- catch (Errors\SignatureVerificationError $e)
108
- {
109
  $log = array(
110
- 'message' => $e->getMessage(),
111
- 'data' => $data,
112
- 'event' => 'razorpay.wc.signature.verify_failed'
113
  );
114
 
115
  error_log(json_encode($log));
116
  return;
117
  }
118
 
119
- switch ($data['event'])
120
- {
 
 
 
121
  case self::PAYMENT_AUTHORIZED:
122
  return $this->paymentAuthorized($data);
123
 
@@ -190,8 +186,7 @@ class RZP_Webhook
190
  protected function paymentAuthorized(array $data)
191
  {
192
  // We don't process subscription/invoice payments here
193
- if (isset($data['payload']['payment']['entity']['invoice_id']) === true)
194
- {
195
  return;
196
  }
197
 
@@ -200,11 +195,27 @@ class RZP_Webhook
200
  //
201
  $orderId = $data['payload']['payment']['entity']['notes']['woocommerce_order_number'];
202
 
 
 
203
  $order = wc_get_order($orderId);
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  // If it is already marked as paid, ignore the event
206
- if ($order->needs_payment() === false)
207
- {
 
208
  return;
209
  }
210
 
@@ -214,16 +225,13 @@ class RZP_Webhook
214
 
215
  $amount = $this->getOrderAmountAsInteger($order);
216
 
217
- $success = false;
218
  $errorMessage = 'The payment has failed.';
219
 
220
- if ($payment['status'] === 'captured')
221
- {
222
  $success = true;
223
- }
224
- else if (($payment['status'] === 'authorized') and
225
- ($this->razorpay->getSetting('payment_action') === WC_Razorpay::CAPTURE))
226
- {
227
  //
228
  // If the payment is only authorized, we capture it
229
  // If the merchant has enabled auto capture
@@ -233,16 +241,14 @@ class RZP_Webhook
233
  $payment->capture(array('amount' => $amount));
234
 
235
  $success = true;
236
- }
237
- catch (Exception $e)
238
- {
239
  //
240
  // Capture will fail if the payment is already captured
241
  //
242
  $log = array(
243
- 'message' => $e->getMessage(),
244
- 'payment_id' => $razorpayPaymentId,
245
- 'event' => $data['event']
246
  );
247
 
248
  error_log(json_encode($log));
@@ -252,14 +258,16 @@ class RZP_Webhook
252
  //
253
  $payment = $this->getPaymentEntity($razorpayPaymentId, $data);
254
 
255
- if ($payment['status'] === 'captured')
256
- {
257
  $success = true;
258
  }
259
  }
260
  }
261
 
262
  $this->razorpay->updateOrder($order, $success, $errorMessage, $razorpayPaymentId, null, true);
 
 
 
263
 
264
  // Graceful exit since payment is now processed.
265
  exit;
@@ -273,8 +281,7 @@ class RZP_Webhook
273
  protected function virtualAccountCredited(array $data)
274
  {
275
  // We don't process subscription/invoice payments here
276
- if (isset($data['payload']['payment']['entity']['invoice_id']) === true)
277
- {
278
  return;
279
  }
280
 
@@ -286,8 +293,7 @@ class RZP_Webhook
286
  $order = wc_get_order($orderId);
287
 
288
  // If it is already marked as paid, ignore the event
289
- if ($order->needs_payment() === false)
290
- {
291
  return;
292
  }
293
 
@@ -299,16 +305,13 @@ class RZP_Webhook
299
 
300
  $amount = $this->getOrderAmountAsInteger($order);
301
 
302
- $success = false;
303
  $errorMessage = 'The payment has failed.';
304
 
305
- if ($payment['status'] === 'captured' and $amountPaid === $amount)
306
- {
307
  $success = true;
308
- }
309
- else if (($payment['status'] === 'authorized') and $amountPaid === $amount and
310
- ($this->razorpay->getSetting('payment_action') === WC_Razorpay::CAPTURE))
311
- {
312
  //
313
  // If the payment is only authorized, we capture it
314
  // If the merchant has enabled auto capture
@@ -318,16 +321,14 @@ class RZP_Webhook
318
  $payment->capture(array('amount' => $amount));
319
 
320
  $success = true;
321
- }
322
- catch (Exception $e)
323
- {
324
  //
325
  // Capture will fail if the payment is already captured
326
  //
327
  $log = array(
328
- 'message' => $e->getMessage(),
329
- 'payment_id' => $razorpayPaymentId,
330
- 'event' => $data['event']
331
  );
332
 
333
  error_log(json_encode($log));
@@ -337,8 +338,7 @@ class RZP_Webhook
337
  //
338
  $payment = $this->getPaymentEntity($razorpayPaymentId, $data);
339
 
340
- if ($payment['status'] === 'captured')
341
- {
342
  $success = true;
343
  }
344
  }
@@ -355,13 +355,11 @@ class RZP_Webhook
355
  try
356
  {
357
  $payment = $this->api->payment->fetch($razorpayPaymentId);
358
- }
359
- catch (Exception $e)
360
- {
361
  $log = array(
362
- 'message' => $e->getMessage(),
363
- 'payment_id' => $razorpayPaymentId,
364
- 'event' => $data['event']
365
  );
366
 
367
  error_log(json_encode($log));
@@ -379,8 +377,7 @@ class RZP_Webhook
379
  {
380
  if ((isset($data['event']) === true) and
381
  (in_array($data['event'], $this->eventsArray) === true) and
382
- isset($data['payload']['payment']['entity']['notes']['woocommerce_order_number']) === true)
383
- {
384
  return true;
385
  }
386
 
@@ -394,8 +391,7 @@ class RZP_Webhook
394
  */
395
  public function getOrderAmountAsInteger($order)
396
  {
397
- if (version_compare(WOOCOMMERCE_VERSION, '3.0.0', '>='))
398
- {
399
  return (int) round($order->get_total() * 100);
400
  }
401
 
@@ -411,14 +407,12 @@ class RZP_Webhook
411
  public function refundedCreated(array $data)
412
  {
413
  // We don't process subscription/invoice payments here
414
- if (isset($data['payload']['payment']['entity']['invoice_id']) === true)
415
- {
416
  return;
417
  }
418
 
419
  //Avoid to recreate refund, If already refund saved and initiated from woocommerce website.
420
- if (isset($data['payload']['refund']['entity']['notes']['refund_from_website']) === true)
421
- {
422
  return;
423
  }
424
 
@@ -436,25 +430,22 @@ class RZP_Webhook
436
  $order = wc_get_order($orderId);
437
 
438
  // If it is already marked as unpaid, ignore the event
439
- if ($order->needs_payment() === true)
440
- {
441
  return;
442
  }
443
 
444
  // If it's something else such as a WC_Order_Refund, we don't want that.
445
- if( ! is_a( $order, 'WC_Order') )
446
- {
447
  $log = array(
448
- 'Error' => 'Provided ID is not a WC Order',
449
  );
450
 
451
  error_log(json_encode($log));
452
  }
453
 
454
- if( 'refunded' == $order->get_status() )
455
- {
456
  $log = array(
457
- 'Error' => 'Order has been already refunded for Order Id -'. $orderId,
458
  );
459
 
460
  error_log(json_encode($log));
@@ -466,27 +457,25 @@ class RZP_Webhook
466
 
467
  try
468
  {
469
- wc_create_refund( array(
470
  'amount' => $refundAmount,
471
  'reason' => $refundReason,
472
  'order_id' => $orderId,
473
  'refund_id' => $refundId,
474
  'line_items' => array(),
475
- 'refund_payment' => false
476
  ));
477
 
478
- $order->add_order_note( __( 'Refund Id: ' . $refundId, 'woocommerce' ) );
479
 
480
- }
481
- catch (Exception $e)
482
- {
483
  //
484
  // Capture will fail if the payment is already captured
485
  //
486
  $log = array(
487
- 'message' => $e->getMessage(),
488
  'payment_id' => $razorpayPaymentId,
489
- 'event' => $data['event']
490
  );
491
 
492
  error_log(json_encode($log));
1
  <?php
2
 
3
+ require_once __DIR__ . '/../woo-razorpay.php';
4
+ require_once __DIR__ . '/../razorpay-sdk/Razorpay.php';
5
 
6
  use Razorpay\Api\Api;
7
  use Razorpay\Api\Errors;
23
  /**
24
  * Event constants
25
  */
26
+ const PAYMENT_AUTHORIZED = 'payment.authorized';
27
+ const PAYMENT_FAILED = 'payment.failed';
28
+ const SUBSCRIPTION_CANCELLED = 'subscription.cancelled';
29
+ const REFUNDED_CREATED = 'refund.created';
30
+ const VIRTUAL_ACCOUNT_CREDITED = 'virtual_account.credited';
31
+ const SUBSCRIPTION_PAUSED = 'subscription.paused';
32
+ const SUBSCRIPTION_RESUMED = 'subscription.resumed';
33
 
34
  protected $eventsArray = [
35
  self::PAYMENT_AUTHORIZED,
38
  self::PAYMENT_FAILED,
39
  self::SUBSCRIPTION_CANCELLED,
40
  self::SUBSCRIPTION_PAUSED,
41
+ self::SUBSCRIPTION_RESUMED,
42
  ];
43
 
44
  public function __construct()
70
 
71
  $data = json_decode($post, true);
72
 
73
+ if (json_last_error() !== 0) {
 
74
  return;
75
  }
76
 
77
  $enabled = $this->razorpay->getSetting('enable_webhook');
78
 
79
  if (($enabled === 'yes') and
80
+ (empty($data['event']) === false)) {
 
81
  // Skip the webhook if not the valid data and event
82
+ if ($this->shouldConsumeWebhook($data) === false) {
 
83
  return;
84
  }
85
 
86
+ if (isset($_SERVER['HTTP_X_RAZORPAY_SIGNATURE']) === true) {
 
87
  $razorpayWebhookSecret = $this->razorpay->getSetting('webhook_secret');
88
 
89
  //
90
  // If the webhook secret isn't set on wordpress, return
91
  //
92
+ if (empty($razorpayWebhookSecret) === true) {
 
93
  return;
94
  }
95
 
96
  try
97
  {
98
  $this->api->utility->verifyWebhookSignature($post,
99
+ $_SERVER['HTTP_X_RAZORPAY_SIGNATURE'],
100
+ $razorpayWebhookSecret);
101
+ } catch (Errors\SignatureVerificationError $e) {
 
 
102
  $log = array(
103
+ 'message' => $e->getMessage(),
104
+ 'data' => $data,
105
+ 'event' => 'razorpay.wc.signature.verify_failed',
106
  );
107
 
108
  error_log(json_encode($log));
109
  return;
110
  }
111
 
112
+ $orderId = $data['payload']['payment']['entity']['notes']['woocommerce_order_number'];
113
+
114
+ rzpLogInfo("Woocommerce orderId: $orderId webhook process intitiated");
115
+
116
+ switch ($data['event']) {
117
  case self::PAYMENT_AUTHORIZED:
118
  return $this->paymentAuthorized($data);
119
 
186
  protected function paymentAuthorized(array $data)
187
  {
188
  // We don't process subscription/invoice payments here
189
+ if (isset($data['payload']['payment']['entity']['invoice_id']) === true) {
 
190
  return;
191
  }
192
 
195
  //
196
  $orderId = $data['payload']['payment']['entity']['notes']['woocommerce_order_number'];
197
 
198
+ rzpLogInfo("Woocommerce orderId: $orderId webhook process intitiated for payment authorized event");
199
+
200
  $order = wc_get_order($orderId);
201
 
202
+ //To give the priority to callback script to compleate the execution fist adding this locking.
203
+ $transientData = get_transient('webhook_trigger_count_for_' . $orderId);
204
+
205
+ if (empty($transientData) || $transientData == 1) {
206
+ rzpLogInfo("Woocommerce orderId: $orderId with transientData: $transientData webhook halted for 60 sec");
207
+
208
+ sleep(60);
209
+ }
210
+
211
+ $triggerCount = !empty($transientData) ? ($transientData + 1) : 1;
212
+
213
+ set_transient('webhook_trigger_count_for_' . $orderId, $triggerCount, 180);
214
+
215
  // If it is already marked as paid, ignore the event
216
+ if ($order->needs_payment() === false) {
217
+ rzpLogInfo("Woocommerce orderId: $orderId webhook process exited");
218
+
219
  return;
220
  }
221
 
225
 
226
  $amount = $this->getOrderAmountAsInteger($order);
227
 
228
+ $success = false;
229
  $errorMessage = 'The payment has failed.';
230
 
231
+ if ($payment['status'] === 'captured') {
 
232
  $success = true;
233
+ } else if (($payment['status'] === 'authorized') and
234
+ ($this->razorpay->getSetting('payment_action') === WC_Razorpay::CAPTURE)) {
 
 
235
  //
236
  // If the payment is only authorized, we capture it
237
  // If the merchant has enabled auto capture
241
  $payment->capture(array('amount' => $amount));
242
 
243
  $success = true;
244
+ } catch (Exception $e) {
 
 
245
  //
246
  // Capture will fail if the payment is already captured
247
  //
248
  $log = array(
249
+ 'message' => $e->getMessage(),
250
+ 'payment_id' => $razorpayPaymentId,
251
+ 'event' => $data['event'],
252
  );
253
 
254
  error_log(json_encode($log));
258
  //
259
  $payment = $this->getPaymentEntity($razorpayPaymentId, $data);
260
 
261
+ if ($payment['status'] === 'captured') {
 
262
  $success = true;
263
  }
264
  }
265
  }
266
 
267
  $this->razorpay->updateOrder($order, $success, $errorMessage, $razorpayPaymentId, null, true);
268
+ rzpLogInfo("Woocommerce orderId: $orderId webhook process finished the update order function");
269
+
270
+ rzpLogInfo("Woocommerce orderId: $orderId webhook process finished the updateOrder function");
271
 
272
  // Graceful exit since payment is now processed.
273
  exit;
281
  protected function virtualAccountCredited(array $data)
282
  {
283
  // We don't process subscription/invoice payments here
284
+ if (isset($data['payload']['payment']['entity']['invoice_id']) === true) {
 
285
  return;
286
  }
287
 
293
  $order = wc_get_order($orderId);
294
 
295
  // If it is already marked as paid, ignore the event
296
+ if ($order->needs_payment() === false) {
 
297
  return;
298
  }
299
 
305
 
306
  $amount = $this->getOrderAmountAsInteger($order);
307
 
308
+ $success = false;
309
  $errorMessage = 'The payment has failed.';
310
 
311
+ if ($payment['status'] === 'captured' and $amountPaid === $amount) {
 
312
  $success = true;
313
+ } else if (($payment['status'] === 'authorized') and $amountPaid === $amount and
314
+ ($this->razorpay->getSetting('payment_action') === WC_Razorpay::CAPTURE)) {
 
 
315
  //
316
  // If the payment is only authorized, we capture it
317
  // If the merchant has enabled auto capture
321
  $payment->capture(array('amount' => $amount));
322
 
323
  $success = true;
324
+ } catch (Exception $e) {
 
 
325
  //
326
  // Capture will fail if the payment is already captured
327
  //
328
  $log = array(
329
+ 'message' => $e->getMessage(),
330
+ 'payment_id' => $razorpayPaymentId,
331
+ 'event' => $data['event'],
332
  );
333
 
334
  error_log(json_encode($log));
338
  //
339
  $payment = $this->getPaymentEntity($razorpayPaymentId, $data);
340
 
341
+ if ($payment['status'] === 'captured') {
 
342
  $success = true;
343
  }
344
  }
355
  try
356
  {
357
  $payment = $this->api->payment->fetch($razorpayPaymentId);
358
+ } catch (Exception $e) {
 
 
359
  $log = array(
360
+ 'message' => $e->getMessage(),
361
+ 'payment_id' => $razorpayPaymentId,
362
+ 'event' => $data['event'],
363
  );
364
 
365
  error_log(json_encode($log));
377
  {
378
  if ((isset($data['event']) === true) and
379
  (in_array($data['event'], $this->eventsArray) === true) and
380
+ isset($data['payload']['payment']['entity']['notes']['woocommerce_order_number']) === true) {
 
381
  return true;
382
  }
383
 
391
  */
392
  public function getOrderAmountAsInteger($order)
393
  {
394
+ if (version_compare(WOOCOMMERCE_VERSION, '3.0.0', '>=')) {
 
395
  return (int) round($order->get_total() * 100);
396
  }
397
 
407
  public function refundedCreated(array $data)
408
  {
409
  // We don't process subscription/invoice payments here
410
+ if (isset($data['payload']['payment']['entity']['invoice_id']) === true) {
 
411
  return;
412
  }
413
 
414
  //Avoid to recreate refund, If already refund saved and initiated from woocommerce website.
415
+ if (isset($data['payload']['refund']['entity']['notes']['refund_from_website']) === true) {
 
416
  return;
417
  }
418
 
430
  $order = wc_get_order($orderId);
431
 
432
  // If it is already marked as unpaid, ignore the event
433
+ if ($order->needs_payment() === true) {
 
434
  return;
435
  }
436
 
437
  // If it's something else such as a WC_Order_Refund, we don't want that.
438
+ if (!is_a($order, 'WC_Order')) {
 
439
  $log = array(
440
+ 'Error' => 'Provided ID is not a WC Order',
441
  );
442
 
443
  error_log(json_encode($log));
444
  }
445
 
446
+ if ('refunded' == $order->get_status()) {
 
447
  $log = array(
448
+ 'Error' => 'Order has been already refunded for Order Id -' . $orderId,
449
  );
450
 
451
  error_log(json_encode($log));
457
 
458
  try
459
  {
460
+ wc_create_refund(array(
461
  'amount' => $refundAmount,
462
  'reason' => $refundReason,
463
  'order_id' => $orderId,
464
  'refund_id' => $refundId,
465
  'line_items' => array(),
466
+ 'refund_payment' => false,
467
  ));
468
 
469
+ $order->add_order_note(__('Refund Id: ' . $refundId, 'woocommerce'));
470
 
471
+ } catch (Exception $e) {
 
 
472
  //
473
  // Capture will fail if the payment is already captured
474
  //
475
  $log = array(
476
+ 'message' => $e->getMessage(),
477
  'payment_id' => $razorpayPaymentId,
478
+ 'event' => $data['event'],
479
  );
480
 
481
  error_log(json_encode($log));
includes/state-map.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Map the state name & state code according to the woocommerce standerds, so that the state name should be properly mapped with state code in billing and shipping address and tax calculation should not break.
5
+ */
6
+ function getWcStateCodeFromName($stateName)
7
+ {
8
+ $stateCodeMap = [
9
+ 'ANDAMAN&NICOBARISLANDS' => 'AN',
10
+ 'ANDAMANANDNICOBARISLANDS' => 'AN',
11
+ 'ANDHRAPRADESH' => 'AP',
12
+ 'ARUNACHALPRADESH' => 'AR',
13
+ 'ASSAM' => 'AS',
14
+ 'BIHAR' => 'BR',
15
+ 'CHANDIGARH' => 'CH',
16
+ 'CHATTISGARH' => 'CT',
17
+ 'CHHATTISGARH' => 'CT',
18
+ 'DADRA&NAGARHAVELI' => 'DN',
19
+ 'DADRAANDNAGARHAVELI' => 'DN',
20
+ 'DAMAN&DIU' => 'DD',
21
+ 'DAMANANDDIU' => 'DD',
22
+ 'DELHI' => 'DL',
23
+ 'GOA' => 'GA',
24
+ 'GUJARAT' => 'GJ',
25
+ 'HARYANA' => 'HR',
26
+ 'HIMACHALPRADESH' => 'HP',
27
+ 'JAMMU&KASHMIR' => 'JK',
28
+ 'JAMMUANDKASHMIR' => 'JK',
29
+ 'JAMMUKASHMIR' => 'JK',
30
+ 'JHARKHAND' => 'JH',
31
+ 'KARNATAKA' => 'KA',
32
+ 'KERALA' => 'KL',
33
+ 'LAKSHADWEEP' => 'LD',
34
+ 'LAKSHADEEP' => 'LD',
35
+ 'LADAKH' => 'LA',
36
+ 'MADHYAPRADESH' => 'MP',
37
+ 'MAHARASHTRA' => 'MH',
38
+ 'MANIPUR' => 'MN',
39
+ 'MEGHALAYA' => 'ML',
40
+ 'MIZORAM' => 'MZ',
41
+ 'NAGALAND' => 'NL',
42
+ 'ODISHA' => 'OR',
43
+ 'PONDICHERRY' => 'PY',
44
+ 'PUNJAB' => 'PB',
45
+ 'RAJASTHAN' => 'RJ',
46
+ 'SIKKIM' => 'SK',
47
+ 'TAMILNADU' => 'TN',
48
+ 'TRIPURA' => 'TR',
49
+ 'TELANGANA' => 'TS',
50
+ 'UTTARPRADESH' => 'UP',
51
+ 'UTTARAKHAND' => 'UK',
52
+ 'WESTBENGAL' => 'WB',
53
+ ];
54
+
55
+ return $stateCodeMap[$stateName];
56
+ }
57
+
58
+ /**
59
+ * Mapping the state code passed in rest API with the wc state code.
60
+ *
61
+ */
62
+ function normalizeWcStateCode($stateCode)
63
+ {
64
+
65
+ $shippingStateCodeMap = [
66
+ 'AN' => 'AN',
67
+ 'AP' => 'AP',
68
+ 'AD' => 'AP',
69
+ 'AR' => 'AR',
70
+ 'AS' => 'AS',
71
+ 'BI' => 'BR',
72
+ 'BH' => 'BR',
73
+ 'CH' => 'CH',
74
+ 'CT' => 'CT',
75
+ 'DN' => 'DN',
76
+ 'DD' => 'DD',
77
+ 'DL' => 'DL',
78
+ 'GO' => 'GA',
79
+ 'GJ' => 'GJ',
80
+ 'HA' => 'HR',
81
+ 'HP' => 'HP',
82
+ 'JK' => 'JK',
83
+ 'JH' => 'JH',
84
+ 'KA' => 'KA',
85
+ 'KE' => 'KL',
86
+ 'LD' => 'LD',
87
+ 'LA' => 'LA',
88
+ 'MP' => 'MP',
89
+ 'MH' => 'MH',
90
+ 'MA' => 'MN',
91
+ 'ME' => 'ML',
92
+ 'MI' => 'MZ',
93
+ 'NA' => 'NL',
94
+ 'OR' => 'OR',
95
+ 'PO' => 'PY',
96
+ 'PB' => 'PB',
97
+ 'RJ' => 'RJ',
98
+ 'SK' => 'SK',
99
+ 'TN' => 'TN',
100
+ 'TR' => 'TR',
101
+ 'TG' => 'TS',
102
+ 'UP' => 'UP',
103
+ 'UT' => 'UK',
104
+ 'WB' => 'WB',
105
+ ];
106
+
107
+ $wcStateCode = isset($shippingStateCodeMap[$stateCode]) ? $shippingStateCodeMap[$stateCode] : $stateCode;
108
+
109
+ return $wcStateCode;
110
+ }
includes/utils.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * controls visibility of 1cc buttons
4
+ * checks test mode, metrics collection config
5
+ * NOTE: we add additional check to see if the config field exists as it may cause issues
6
+ * during plugin updates
7
+ */
8
+
9
+ /**
10
+ * payment plugins are loaded even if they are disabled which triggers the 1cc button flow
11
+ * we need to check if the plugin is disabled
12
+ */
13
+ function isRazorpayPluginEnabled()
14
+ {
15
+ return (
16
+ empty(get_option('woocommerce_razorpay_settings')['enabled']) === false
17
+ && 'yes' == get_option('woocommerce_razorpay_settings')['enabled']
18
+ );
19
+ }
20
+
21
+ function isTestModeEnabled()
22
+ {
23
+ return (
24
+ empty(get_option('woocommerce_razorpay_settings')['enable_1cc_test_mode']) === false
25
+ && 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc_test_mode']
26
+ );
27
+ }
28
+
29
+ function is1ccEnabled()
30
+ {
31
+ return (
32
+ empty(get_option('woocommerce_razorpay_settings')['enable_1cc']) === false
33
+ && 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc']
34
+ );
35
+ }
36
+
37
+ function isProductSupported()
38
+ {
39
+
40
+ }
41
+
42
+ function isCartSupported()
43
+ {
44
+
45
+ }
46
+
47
+ function isDebugModeEnabled()
48
+ {
49
+ return (
50
+ empty(get_option('woocommerce_razorpay_settings')['enable_1cc_debug_mode']) === false
51
+ && 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc_debug_mode']
52
+ );
53
+ }
54
+
55
+ function isPdpCheckoutEnabled()
56
+ {
57
+ return (
58
+ empty(get_option('woocommerce_razorpay_settings')['enable_1cc_pdp_checkout']) === false
59
+ && 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc_pdp_checkout']
60
+ );
61
+ }
62
+
63
+ function isMiniCartCheckoutEnabled()
64
+ {
65
+ return (
66
+ empty(get_option('woocommerce_razorpay_settings')['enable_1cc_mini_cart_checkout']) === false
67
+ && 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc_mini_cart_checkout']
68
+ );
69
+ }
70
+
71
+ function validateInput($route, $param)
72
+ {
73
+ $failure_reason = null;
74
+
75
+ switch ($route) {
76
+ case 'list':
77
+ if (empty(sanitize_text_field($param['amount'])) === true) {
78
+ $failure_reason = 'Field amount is required.';
79
+ }
80
+ break;
81
+
82
+ case 'apply':
83
+ if (empty(sanitize_text_field($param['code'])) === true) {
84
+ $failure_reason = 'Field code is required.';
85
+
86
+ } elseif (empty(sanitize_text_field($param['order_id'])) === true) {
87
+
88
+ $failure_reason = 'Field order id is required.';
89
+
90
+ }
91
+ break;
92
+
93
+ case 'shipping':
94
+ if (empty(sanitize_text_field($param['order_id'])) === true) {
95
+ $failure_reason = 'Field order id is required.';
96
+
97
+ } elseif (empty($param['addresses']) === true) {
98
+
99
+ $failure_reason = 'Field addresses is required.';
100
+
101
+ }
102
+ break;
103
+
104
+ default:
105
+
106
+ break;
107
+ }
108
+
109
+ return $failure_reason;
110
+ }
public/css/1cc-product-checkout.css ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #btn-1cc {
2
+ display: block !important;
3
+ width: 100%;
4
+ }
5
+ #btn-1cc-mini-cart {
6
+ display: block !important;
7
+ width: 100%;
8
+ }
9
+ #btn-1cc-pdp {
10
+ margin-left: 5px;
11
+ }
12
+ #rzp-spinner-backdrop {
13
+ position: fixed;
14
+ top: 0;
15
+ left: 0;
16
+ z-index: 9999;
17
+ width: 100%;
18
+ height: 100%;
19
+ background: rgba(0, 0, 0);
20
+ visibility: hidden;
21
+ opacity: 0;
22
+ }
23
+ #rzp-spinner-backdrop.show {
24
+ visibility: visible;
25
+ opacity: 0.4;
26
+ }
27
+ #rzp-spinner {
28
+ visibility: hidden;
29
+ opacity: 0;
30
+ /* positioning and centering */
31
+ position: fixed;
32
+ left: 0;
33
+ top: 0;
34
+ bottom: 0;
35
+ right: 0;
36
+ margin: auto;
37
+ z-index: 10000;
38
+ display: flex !important;
39
+ align-items: center;
40
+ justify-content: center;
41
+ }
42
+ #rzp-spinner.show {
43
+ visibility: visible;
44
+ opacity: 1;
45
+ }
46
+ @keyframes rotate {
47
+ 0% {
48
+ transform: rotate(0);
49
+ }
50
+ 100% {
51
+ transform: rotate(360deg);
52
+ }
53
+ }
54
+ #loading-indicator {
55
+ border-radius: 50%;
56
+ width: 80px;
57
+ height: 80px;
58
+ border: 4px solid;
59
+ border-color: rgb(59, 124, 245) transparent rgb(59, 124, 245) rgb(59, 124, 245) !important;
60
+ animation: 1s linear 0s infinite normal none running rotate;
61
+ margin-top: 2px;
62
+ box-sizing: content-box;
63
+ }
64
+ #icon {
65
+ position: absolute;
66
+ }
67
+ #rzp-logo{
68
+ width: auto;
69
+ height: 80px !important;
70
+ }
71
+ @media (max-device-height: 768px), (max-device-width: 768px) {
72
+ #loading-indicator {
73
+ width: 45px;
74
+ height: 45px;
75
+ }
76
+ #rzp-logo {
77
+ height: 45px !important;
78
+ }
79
+ }
public/css/bootstrap.min.css ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*!
2
+ * Bootstrap v4.5.2 (https://getbootstrap.com/)
3
+ * Copyright 2011-2020 The Bootstrap Authors
4
+ * Copyright 2011-2020 Twitter, Inc.
5
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
6
+ */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:-ms-flexbox;display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
7
+ /*# sourceMappingURL=bootstrap.min.css.map */
public/css/woo_route.css ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wrap {
2
+ font-family: Helvetica;
3
+ }
4
+ .rzp-container {
5
+ border: 1px solid #dfe5e7;
6
+ margin-top: 30px;
7
+ background-color: #f0f3f4;
8
+ margin-left: 5px !important;
9
+ }
10
+ .rzp-dashicons {
11
+ margin-top: 3px;
12
+ }
13
+ .text {
14
+ display: inline-block;
15
+ white-space: nowrap;
16
+ overflow: hidden;
17
+ text-overflow: ellipsis;
18
+ vertical-align: bottom;
19
+ font-weight: 600;
20
+ width: 48%;
21
+ }
22
+ .panel-heading {
23
+ line-height: 74px;
24
+ vertical-align: middle;
25
+ font-size: 18px;
26
+ padding: 0 20px;
27
+ border-bottom: 1px solid #fff;
28
+ }
29
+ .Button {
30
+ background-color: #fff;
31
+ padding: 5px 11px;
32
+ line-height: 16px;
33
+ outline: none;
34
+ transition: .15s,.3s border;
35
+ vertical-align: middle;
36
+ font-size: 13px;
37
+ color: #528ff0;
38
+ border: 1px solid #528ff0;
39
+ border-radius: 3px;
40
+ }
41
+ .content-header a:hover{
42
+ text-decoration: none;
43
+ }
44
+ .panel-body {
45
+ margin: 10px 0;
46
+ }
47
+ .panel-body-left .row{
48
+ padding: 5px;
49
+ font-size: 14px;
50
+ }
51
+ .button-items-detail{
52
+ margin: 10px 0;
53
+ background-color: #f9f9f9;
54
+ padding: 10px;
55
+ border-radius: 3px;
56
+ font-size: 14px;
57
+ }
58
+ .panel-label{
59
+ color: #8991ae;
60
+ }
61
+ .panel-value{
62
+ color: #58666e;
63
+ }
64
+
65
+ button:hover {
66
+ opacity:1;
67
+ }
68
+
69
+ .overlay, .rev_trf_overlay, .trf_settlement_overlay {
70
+ position: fixed;
71
+ top: 0;
72
+ left: 0;
73
+ width: 100vw;
74
+ height: 100vh;
75
+ background-color: rgba(128,128,128,0.5);
76
+ display: none;
77
+ }
78
+
79
+ .modal {
80
+ position: relative;
81
+ display: block;
82
+ height: 365px;
83
+ width: 325px;
84
+ margin: 70px auto;
85
+ border-radius: 5px;
86
+ background-color: white;
87
+ }
88
+ .modal-content {
89
+ border: 0;
90
+ }
91
+ .modal-header {
92
+ padding: 24px 22px 0;
93
+ border-bottom: 0;
94
+ }
95
+ .modal-title {
96
+ font-size: 18px;
97
+ font-weight: bold;
98
+ line-height: 1em;
99
+ margin: 0;
100
+ }
101
+ .btn-default {
102
+ color: #58666e;
103
+ background-color: #fafafa;
104
+ border-color: #58666e;
105
+ font-size: 14px;
106
+ padding: 6px 12px;
107
+ font-weight: 400;
108
+ }
109
+ .btn-primary {
110
+ background-color: #528ff0;
111
+ border-color: #3b80ee;
112
+ }
113
+ .rzp-currency {
114
+ font-weight: normal;
115
+ color: inherit;
116
+ opacity: 0.7;
117
+ white-space: nowrap;
118
+ font-size: 100%;
119
+ }
120
+ p:empty:before {
121
+ display: none;
122
+ }
123
+
124
+ .route-container header {
125
+ line-height: 50px;
126
+ border: 1px solid #e2e8ea;
127
+ position: relative;
128
+ background-color: #e2e8ea;
129
+ padding: 0 12px 0 24px;
130
+ margin-bottom: 20px;
131
+ }
132
+ .route-container header a {
133
+ color: #555;
134
+ border-bottom: 3px solid transparent;
135
+ display: inline-block;
136
+ margin: 0 16px;
137
+ font-weight: bold;
138
+ position: relative;
139
+ bottom: -1px;
140
+ }
141
+ .route-container header a:hover { text-decoration: none; }
142
+
143
+ .route-container header > a:first-child {
144
+ margin-left: 0;
145
+ }
146
+ .route-container header a.active {
147
+ color: #528ff0;
148
+ border-color: #528ff0;
149
+ }
150
+
151
+ .trf_settlement_label {
152
+ margin-left: 5px !important;
153
+ width: 100px !important;
154
+ }
155
+
156
+ .rzp_transfer_custom_field input{
157
+ margin-right: 5px !important;
158
+ }
159
+ .rzp_transfer_custom_field input[type=text], .rzp_transfer_custom_field input[type=number]{
160
+ width: 220px !important;
161
+ }
162
+ .rzp_transfer_custom_field .remove_field{ float: right;}
163
+ .rzp_transfer_custom_field .add_field_button{ float: right;}
164
+
165
+ .pay_search_label{ float: left;position: relative; left: 704px;font-size: 15px;}
166
+ .input-group { position: relative; display: table; }
167
+ .input-group .input-group-addon {
168
+ padding: 6px 12px;
169
+ font-size: 14px;
170
+ line-height: 1;
171
+ color: #555;
172
+ text-align: center;
173
+ background-color: #eee;
174
+ border: 1px solid #cfdadd;
175
+ border-radius: 2px;
176
+ width: 1%;
177
+ vertical-align: middle;
178
+ display: table-cell;
179
+ }
180
+
181
+ .modal .btn{ width: 100%; }
182
+
183
+ #revTransferModal{ height: 270px !important; }
184
+ #paymentTransferModal{ height: 540px !important; width: 350px !important; }
185
+ .RadioButton{ margin: 12px auto; }
186
+ span.trf-status{ margin-right: 10px; }
187
+ .panel-heading strong{ margin-left: 10px;}
188
+ .panel-value button{ margin-left: 10px !important;}
189
+ .btn-default:hover{ background-color: #dee5e7}
190
+ .rzp_transfer_from_field li{ float: left}
191
+ .rzp_transfer_from_field li label{ width: 330px;}
192
+ .rzp_transfer_from_field .woocommerce-help-tip{ right: 146px;}
193
+ .post-type-shop_order .wp-list-table .check-column { width: 15px !important; }
public/images/payment.png ADDED
Binary file
public/images/rzp-spinner.svg ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <circle cx="16.5" cy="16.5" r="16.5" fill="#DFECFB"/>
3
+ <path d="M10.5788 19.7215L9.30762 24.5381H15.6016C15.6016 24.5381 18.1759 14.7421 18.1766 14.7393C18.1742 14.7408 10.5788 19.7215 10.5788 19.7215Z" fill="#1F2849"/>
4
+ <path d="M15.5556 13.0953L14.7476 16.1153L19.3712 13.0784L16.3475 24.536L19.418 24.5388L23.8848 7.61572L15.5556 13.0953Z" fill="#3395FF"/>
5
+ </svg>
public/js/admin-rzp-settings.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ window.onload = function() {
2
+ // for confirmation of toggling 1cc
3
+ var enableRzpCheckout = document.getElementById('woocommerce_razorpay_enable_1cc');
4
+ if (enableRzpCheckout) {
5
+ enableRzpCheckout.onclick = function(e) {
6
+ var current_val = enableRzpCheckout.checked;
7
+ if (current_val) {
8
+ var message = 'Do you want to activate Magic Checkout?'
9
+ } else {
10
+ var message = 'Are you sure you want to deactivate Magic Checkout?'
11
+ }
12
+ if (!confirm(message)) {
13
+ if (current_val) {
14
+ enableRzpCheckout.checked = false;
15
+ } else {
16
+ enableRzpCheckout.checked = true;
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
public/js/bootstrap.min.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /*!
2
+ * Bootstrap v4.5.2 (https://getbootstrap.com/)
3
+ * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
+ */
6
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function o(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),t}function s(){return(s=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e,n=n&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n;function r(t){var n=this,i=!1;return e(this).one(a.TRANSITION_END,(function(){i=!0})),setTimeout((function(){i||a.triggerTransitionEnd(n)}),t),this}var a={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var n=e(t).css("transition-duration"),i=e(t).css("transition-delay"),o=parseFloat(n),s=parseFloat(i);return o||s?(n=n.split(",")[0],i=i.split(",")[0],1e3*(parseFloat(n)+parseFloat(i))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){e(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],s=e[i],r=s&&a.isElement(s)?"element":null===(l=s)||"undefined"==typeof l?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(r))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+r+'" but expected type "'+o+'".')}var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?a.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof e)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=e.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};a.jQueryDetection(),e.fn.emulateTransitionEnd=r,e.event.special[a.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var l="alert",c=e.fn[l],h=function(){function t(t){this._element=t}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},n.dispose=function(){e.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){var n=a.getSelectorFromElement(t),i=!1;return n&&(i=document.querySelector(n)),i||(i=e(t).closest(".alert")[0]),i},n._triggerCloseEvent=function(t){var n=e.Event("close.bs.alert");return e(t).trigger(n),n},n._removeElement=function(t){var n=this;if(e(t).removeClass("show"),e(t).hasClass("fade")){var i=a.getTransitionDurationFromElement(t);e(t).one(a.TRANSITION_END,(function(e){return n._destroyElement(t,e)})).emulateTransitionEnd(i)}else this._destroyElement(t)},n._destroyElement=function(t){e(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.alert");o||(o=new t(this),i.data("bs.alert",o)),"close"===n&&o[n](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',h._handleDismiss(new h)),e.fn[l]=h._jQueryInterface,e.fn[l].Constructor=h,e.fn[l].noConflict=function(){return e.fn[l]=c,h._jQueryInterface};var u=e.fn.button,d=function(){function t(t){this._element=t}var n=t.prototype;return n.toggle=function(){var t=!0,n=!0,i=e(this._element).closest('[data-toggle="buttons"]')[0];if(i){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var s=i.querySelector(".active");s&&e(s).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),e(o).trigger("change")),o.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&e(this._element).toggleClass("active"))},n.dispose=function(){e.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.button");i||(i=new t(this),e(this).data("bs.button",i)),"toggle"===n&&i[n]()}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=t.target,i=n;if(e(n).hasClass("btn")||(n=e(n).closest(".btn")[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))t.preventDefault();else{var o=n.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();("LABEL"!==i.tagName||o&&"checkbox"!==o.type)&&d._jQueryInterface.call(e(n),"toggle")}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=e(t.target).closest(".btn")[0];e(n).toggleClass("focus",/^focus(in)?$/.test(t.type))})),e(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var s=0,r=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;s<r;s++){var a=t[s];"true"===a.getAttribute("aria-pressed")?a.classList.add("active"):a.classList.remove("active")}})),e.fn.button=d._jQueryInterface,e.fn.button.Constructor=d,e.fn.button.noConflict=function(){return e.fn.button=u,d._jQueryInterface};var f="carousel",g=".bs.carousel",m=e.fn[f],p={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},_={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},v={TOUCH:"touch",PEN:"pen"},b=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&e(this._element).is(":visible")&&"hidden"!==e(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(a.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var n=this;this._activeElement=this._element.querySelector(".active.carousel-item");var i=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)e(this._element).one("slid.bs.carousel",(function(){return n.to(t)}));else{if(i===t)return this.pause(),void this.cycle();var o=t>i?"next":"prev";this._slide(o,this._items[t])}},n.dispose=function(){e(this._element).off(g),e.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=s({},p,t),a.typeCheckConfig(f,t,_),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&e(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&e(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var n=function(e){t._pointerEvent&&v[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},i=function(e){t._pointerEvent&&v[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};e(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(e(this._element).on("pointerdown.bs.carousel",(function(t){return n(t)})),e(this._element).on("pointerup.bs.carousel",(function(t){return i(t)})),this._element.classList.add("pointer-event")):(e(this._element).on("touchstart.bs.carousel",(function(t){return n(t)})),e(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),e(this._element).on("touchend.bs.carousel",(function(t){return i(t)})))}},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),s=this._items.length-1;if((i&&0===o||n&&o===s)&&!this._config.wrap)return e;var r=(o+("prev"===t?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]},n._triggerSlideEvent=function(t,n){var i=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),s=e.Event("slide.bs.carousel",{relatedTarget:t,direction:n,from:o,to:i});return e(this._element).trigger(s),s},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));e(n).removeClass("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&e(i).addClass("active")}},n._slide=function(t,n){var i,o,s,r=this,l=this._element.querySelector(".active.carousel-item"),c=this._getItemIndex(l),h=n||l&&this._getItemByDirection(t,l),u=this._getItemIndex(h),d=Boolean(this._interval);if("next"===t?(i="carousel-item-left",o="carousel-item-next",s="left"):(i="carousel-item-right",o="carousel-item-prev",s="right"),h&&e(h).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(h,s).isDefaultPrevented()&&l&&h){this._isSliding=!0,d&&this.pause(),this._setActiveIndicatorElement(h);var f=e.Event("slid.bs.carousel",{relatedTarget:h,direction:s,from:c,to:u});if(e(this._element).hasClass("slide")){e(h).addClass(o),a.reflow(h),e(l).addClass(i),e(h).addClass(i);var g=parseInt(h.getAttribute("data-interval"),10);g?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=g):this._config.interval=this._config.defaultInterval||this._config.interval;var m=a.getTransitionDurationFromElement(l);e(l).one(a.TRANSITION_END,(function(){e(h).removeClass(i+" "+o).addClass("active"),e(l).removeClass("active "+o+" "+i),r._isSliding=!1,setTimeout((function(){return e(r._element).trigger(f)}),0)})).emulateTransitionEnd(m)}else e(l).removeClass("active"),e(h).addClass("active"),this._isSliding=!1,e(this._element).trigger(f);d&&this.cycle()}},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.carousel"),o=s({},p,e(this).data());"object"==typeof n&&(o=s({},o,n));var r="string"==typeof n?n:o.slide;if(i||(i=new t(this,o),e(this).data("bs.carousel",i)),"number"==typeof n)i.to(n);else if("string"==typeof r){if("undefined"==typeof i[r])throw new TypeError('No method named "'+r+'"');i[r]()}else o.interval&&o.ride&&(i.pause(),i.cycle())}))},t._dataApiClickHandler=function(n){var i=a.getSelectorFromElement(this);if(i){var o=e(i)[0];if(o&&e(o).hasClass("carousel")){var r=s({},e(o).data(),e(this).data()),l=this.getAttribute("data-slide-to");l&&(r.interval=!1),t._jQueryInterface.call(e(o),r),l&&e(o).data("bs.carousel").to(l),n.preventDefault()}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return p}}]),t}();e(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",b._dataApiClickHandler),e(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),n=0,i=t.length;n<i;n++){var o=e(t[n]);b._jQueryInterface.call(o,o.data())}})),e.fn[f]=b._jQueryInterface,e.fn[f].Constructor=b,e.fn[f].noConflict=function(){return e.fn[f]=m,b._jQueryInterface};var y="collapse",E=e.fn[y],w={toggle:!0,parent:""},T={toggle:"boolean",parent:"(string|element)"},C=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var s=n[i],r=a.getSelectorFromElement(s),l=[].slice.call(document.querySelectorAll(r)).filter((function(e){return e===t}));null!==r&&l.length>0&&(this._selector=r,this._triggerArray.push(s))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=t.prototype;return n.toggle=function(){e(this._element).hasClass("show")?this.hide():this.show()},n.show=function(){var n,i,o=this;if(!this._isTransitioning&&!e(this._element).hasClass("show")&&(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(n=null),!(n&&(i=e(n).not(this._selector).data("bs.collapse"))&&i._isTransitioning))){var s=e.Event("show.bs.collapse");if(e(this._element).trigger(s),!s.isDefaultPrevented()){n&&(t._jQueryInterface.call(e(n).not(this._selector),"hide"),i||e(n).data("bs.collapse",null));var r=this._getDimension();e(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[r]=0,this._triggerArray.length&&e(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(r[0].toUpperCase()+r.slice(1)),c=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(){e(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[r]="",o.setTransitioning(!1),e(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(c),this._element.style[r]=this._element[l]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&e(this._element).hasClass("show")){var n=e.Event("hide.bs.collapse");if(e(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",a.reflow(this._element),e(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var s=0;s<o;s++){var r=this._triggerArray[s],l=a.getSelectorFromElement(r);if(null!==l)e([].slice.call(document.querySelectorAll(l))).hasClass("show")||e(r).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[i]="";var c=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(){t.setTransitioning(!1),e(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(c)}}},n.setTransitioning=function(t){this._isTransitioning=t},n.dispose=function(){e.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(t){return(t=s({},w,t)).toggle=Boolean(t.toggle),a.typeCheckConfig(y,t,T),t},n._getDimension=function(){return e(this._element).hasClass("width")?"width":"height"},n._getParent=function(){var n,i=this;a.isElement(this._config.parent)?(n=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(n=this._config.parent[0])):n=document.querySelector(this._config.parent);var o='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',s=[].slice.call(n.querySelectorAll(o));return e(s).each((function(e,n){i._addAriaAndCollapsedClass(t._getTargetFromElement(n),[n])})),n},n._addAriaAndCollapsedClass=function(t,n){var i=e(t).hasClass("show");n.length&&e(n).toggleClass("collapsed",!i).attr("aria-expanded",i)},t._getTargetFromElement=function(t){var e=a.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.collapse"),r=s({},w,i.data(),"object"==typeof n&&n?n:{});if(!o&&r.toggle&&"string"==typeof n&&/show|hide/.test(n)&&(r.toggle=!1),o||(o=new t(this,r),i.data("bs.collapse",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return w}}]),t}();e(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var n=e(this),i=a.getSelectorFromElement(this),o=[].slice.call(document.querySelectorAll(i));e(o).each((function(){var t=e(this),i=t.data("bs.collapse")?"toggle":n.data();C._jQueryInterface.call(t,i)}))})),e.fn[y]=C._jQueryInterface,e.fn[y].Constructor=C,e.fn[y].noConflict=function(){return e.fn[y]=E,C._jQueryInterface};var S="dropdown",k=e.fn[S],D=new RegExp("38|40|27"),N={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},A={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},I=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var i=t.prototype;return i.toggle=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")){var n=e(this._menu).hasClass("show");t._clearMenus(),n||this.show(!0)}},i.show=function(i){if(void 0===i&&(i=!1),!(this._element.disabled||e(this._element).hasClass("disabled")||e(this._menu).hasClass("show"))){var o={relatedTarget:this._element},s=e.Event("show.bs.dropdown",o),r=t._getParentFromElement(this._element);if(e(r).trigger(s),!s.isDefaultPrevented()){if(!this._inNavbar&&i){if("undefined"==typeof n)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var l=this._element;"parent"===this._config.reference?l=r:a.isElement(this._config.reference)&&(l=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(l=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e(r).addClass("position-static"),this._popper=new n(l,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===e(r).closest(".navbar-nav").length&&e(document.body).children().on("mouseover",null,e.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),e(this._menu).toggleClass("show"),e(r).toggleClass("show").trigger(e.Event("shown.bs.dropdown",o))}}},i.hide=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")&&e(this._menu).hasClass("show")){var n={relatedTarget:this._element},i=e.Event("hide.bs.dropdown",n),o=t._getParentFromElement(this._element);e(o).trigger(i),i.isDefaultPrevented()||(this._popper&&this._popper.destroy(),e(this._menu).toggleClass("show"),e(o).toggleClass("show").trigger(e.Event("hidden.bs.dropdown",n)))}},i.dispose=function(){e.removeData(this._element,"bs.dropdown"),e(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},i.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},i._addEventListeners=function(){var t=this;e(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},i._getConfig=function(t){return t=s({},this.constructor.Default,e(this._element).data(),t),a.typeCheckConfig(S,t,this.constructor.DefaultType),t},i._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},i._getPlacement=function(){var t=e(this._element.parentNode),n="bottom-start";return t.hasClass("dropup")?n=e(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?n="right-start":t.hasClass("dropleft")?n="left-start":e(this._menu).hasClass("dropdown-menu-right")&&(n="bottom-end"),n},i._detectNavbar=function(){return e(this._element).closest(".navbar").length>0},i._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=s({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},i._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),s({},t,this._config.popperConfig)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.dropdown");if(i||(i=new t(this,"object"==typeof n?n:null),e(this).data("bs.dropdown",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},t._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var i=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,s=i.length;o<s;o++){var r=t._getParentFromElement(i[o]),a=e(i[o]).data("bs.dropdown"),l={relatedTarget:i[o]};if(n&&"click"===n.type&&(l.clickEvent=n),a){var c=a._menu;if(e(r).hasClass("show")&&!(n&&("click"===n.type&&/input|textarea/i.test(n.target.tagName)||"keyup"===n.type&&9===n.which)&&e.contains(r,n.target))){var h=e.Event("hide.bs.dropdown",l);e(r).trigger(h),h.isDefaultPrevented()||("ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),i[o].setAttribute("aria-expanded","false"),a._popper&&a._popper.destroy(),e(c).removeClass("show"),e(r).removeClass("show").trigger(e.Event("hidden.bs.dropdown",l)))}}}},t._getParentFromElement=function(t){var e,n=a.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(n){if(!(/input|textarea/i.test(n.target.tagName)?32===n.which||27!==n.which&&(40!==n.which&&38!==n.which||e(n.target).closest(".dropdown-menu").length):!D.test(n.which))&&!this.disabled&&!e(this).hasClass("disabled")){var i=t._getParentFromElement(this),o=e(i).hasClass("show");if(o||27!==n.which){if(n.preventDefault(),n.stopPropagation(),!o||o&&(27===n.which||32===n.which))return 27===n.which&&e(i.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void e(this).trigger("click");var s=[].slice.call(i.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return e(t).is(":visible")}));if(0!==s.length){var r=s.indexOf(n.target);38===n.which&&r>0&&r--,40===n.which&&r<s.length-1&&r++,r<0&&(r=0),s[r].focus()}}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return N}},{key:"DefaultType",get:function(){return A}}]),t}();e(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',I._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",I._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",I._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),I._jQueryInterface.call(e(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),e.fn[S]=I._jQueryInterface,e.fn[S].Constructor=I,e.fn[S].noConflict=function(){return e.fn[S]=k,I._jQueryInterface};var O=e.fn.modal,j={backdrop:!0,keyboard:!0,focus:!0,show:!0},x={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},P=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var n=t.prototype;return n.toggle=function(t){return this._isShown?this.hide():this.show(t)},n.show=function(t){var n=this;if(!this._isShown&&!this._isTransitioning){e(this._element).hasClass("fade")&&(this._isTransitioning=!0);var i=e.Event("show.bs.modal",{relatedTarget:t});e(this._element).trigger(i),this._isShown||i.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),e(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return n.hide(t)})),e(this._dialog).on("mousedown.dismiss.bs.modal",(function(){e(n._element).one("mouseup.dismiss.bs.modal",(function(t){e(t.target).is(n._element)&&(n._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return n._showElement(t)})))}},n.hide=function(t){var n=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var i=e.Event("hide.bs.modal");if(e(this._element).trigger(i),this._isShown&&!i.isDefaultPrevented()){this._isShown=!1;var o=e(this._element).hasClass("fade");if(o&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),e(document).off("focusin.bs.modal"),e(this._element).removeClass("show"),e(this._element).off("click.dismiss.bs.modal"),e(this._dialog).off("mousedown.dismiss.bs.modal"),o){var s=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(t){return n._hideModal(t)})).emulateTransitionEnd(s)}else this._hideModal()}}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return e(t).off(".bs.modal")})),e(document).off("focusin.bs.modal"),e.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(t){return t=s({},j,t),a.typeCheckConfig("modal",t,x),t},n._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){var n=e.Event("hidePrevented.bs.modal");if(e(this._element).trigger(n),n.defaultPrevented)return;var i=this._element.scrollHeight>document.documentElement.clientHeight;i||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var o=a.getTransitionDurationFromElement(this._dialog);e(this._element).off(a.TRANSITION_END),e(this._element).one(a.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),i||e(t._element).one(a.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}else this.hide()},n._showElement=function(t){var n=this,i=e(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),e(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,i&&a.reflow(this._element),e(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var s=e.Event("shown.bs.modal",{relatedTarget:t}),r=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,e(n._element).trigger(s)};if(i){var l=a.getTransitionDurationFromElement(this._dialog);e(this._dialog).one(a.TRANSITION_END,r).emulateTransitionEnd(l)}else r()},n._enforceFocus=function(){var t=this;e(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(n){document!==n.target&&t._element!==n.target&&0===e(t._element).has(n.target).length&&t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?e(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||e(this._element).off("keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?e(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):e(window).off("resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){e(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),e(t._element).trigger("hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop&&(e(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(t){var n=this,i=e(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",i&&this._backdrop.classList.add(i),e(this._backdrop).appendTo(document.body),e(this._element).on("click.dismiss.bs.modal",(function(t){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:t.target===t.currentTarget&&n._triggerBackdropTransition()})),i&&a.reflow(this._backdrop),e(this._backdrop).addClass("show"),!t)return;if(!i)return void t();var o=a.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(a.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){e(this._backdrop).removeClass("show");var s=function(){n._removeBackdrop(),t&&t()};if(e(this._element).hasClass("fade")){var r=a.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(a.TRANSITION_END,s).emulateTransitionEnd(r)}else s()}else t&&t()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var n=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),i=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(n,i){var o=i.style.paddingRight,s=e(i).css("padding-right");e(i).data("padding-right",o).css("padding-right",parseFloat(s)+t._scrollbarWidth+"px")})),e(i).each((function(n,i){var o=i.style.marginRight,s=e(i).css("margin-right");e(i).data("margin-right",o).css("margin-right",parseFloat(s)-t._scrollbarWidth+"px")}));var o=document.body.style.paddingRight,s=e(document.body).css("padding-right");e(document.body).data("padding-right",o).css("padding-right",parseFloat(s)+this._scrollbarWidth+"px")}e(document.body).addClass("modal-open")},n._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));e(t).each((function(t,n){var i=e(n).data("padding-right");e(n).removeData("padding-right"),n.style.paddingRight=i||""}));var n=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(t,n){var i=e(n).data("margin-right");"undefined"!=typeof i&&e(n).css("margin-right",i).removeData("margin-right")}));var i=e(document.body).data("padding-right");e(document.body).removeData("padding-right"),document.body.style.paddingRight=i||""},n._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(n,i){return this.each((function(){var o=e(this).data("bs.modal"),r=s({},j,e(this).data(),"object"==typeof n&&n?n:{});if(o||(o=new t(this,r),e(this).data("bs.modal",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](i)}else r.show&&o.show(i)}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return j}}]),t}();e(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var n,i=this,o=a.getSelectorFromElement(this);o&&(n=document.querySelector(o));var r=e(n).data("bs.modal")?"toggle":s({},e(n).data(),e(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var l=e(n).one("show.bs.modal",(function(t){t.isDefaultPrevented()||l.one("hidden.bs.modal",(function(){e(i).is(":visible")&&i.focus()}))}));P._jQueryInterface.call(e(n),r,this)})),e.fn.modal=P._jQueryInterface,e.fn.modal.Constructor=P,e.fn.modal.noConflict=function(){return e.fn.modal=O,P._jQueryInterface};var R=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],L={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},q=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,F=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function Q(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),s=[].slice.call(i.body.querySelectorAll("*")),r=function(t,n){var i=s[t],r=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var a=[].slice.call(i.attributes),l=[].concat(e["*"]||[],e[r]||[]);a.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===R.indexOf(n)||Boolean(t.nodeValue.match(q)||t.nodeValue.match(F));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,s=i.length;o<s;o++)if(n.match(i[o]))return!0;return!1})(t,l)||i.removeAttribute(t.nodeName)}))},a=0,l=s.length;a<l;a++)r(a);return i.body.innerHTML}var B="tooltip",H=e.fn[B],U=new RegExp("(^|\\s)bs-tooltip\\S+","g"),M=["sanitize","whiteList","sanitizeFn"],W={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},V={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},z={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:L,popperConfig:null},K={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},X=function(){function t(t,e){if("undefined"==typeof n)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var i=t.prototype;return i.enable=function(){this._isEnabled=!0},i.disable=function(){this._isEnabled=!1},i.toggleEnabled=function(){this._isEnabled=!this._isEnabled},i.toggle=function(t){if(this._isEnabled)if(t){var n=this.constructor.DATA_KEY,i=e(t.currentTarget).data(n);i||(i=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(e(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},i.dispose=function(){clearTimeout(this._timeout),e.removeData(this.element,this.constructor.DATA_KEY),e(this.element).off(this.constructor.EVENT_KEY),e(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&e(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},i.show=function(){var t=this;if("none"===e(this.element).css("display"))throw new Error("Please use show on visible elements");var i=e.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){e(this.element).trigger(i);var o=a.findShadowRoot(this.element),s=e.contains(null!==o?o:this.element.ownerDocument.documentElement,this.element);if(i.isDefaultPrevented()||!s)return;var r=this.getTipElement(),l=a.getUID(this.constructor.NAME);r.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&e(r).addClass("fade");var c="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,h=this._getAttachment(c);this.addAttachmentClass(h);var u=this._getContainer();e(r).data(this.constructor.DATA_KEY,this),e.contains(this.element.ownerDocument.documentElement,this.tip)||e(r).appendTo(u),e(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new n(this.element,r,this._getPopperConfig(h)),e(r).addClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().on("mouseover",null,e.noop);var d=function(){t.config.animation&&t._fixTransition();var n=t._hoverState;t._hoverState=null,e(t.element).trigger(t.constructor.Event.SHOWN),"out"===n&&t._leave(null,t)};if(e(this.tip).hasClass("fade")){var f=a.getTransitionDurationFromElement(this.tip);e(this.tip).one(a.TRANSITION_END,d).emulateTransitionEnd(f)}else d()}},i.hide=function(t){var n=this,i=this.getTipElement(),o=e.Event(this.constructor.Event.HIDE),s=function(){"show"!==n._hoverState&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),e(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()};if(e(this.element).trigger(o),!o.isDefaultPrevented()){if(e(i).removeClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,e(this.tip).hasClass("fade")){var r=a.getTransitionDurationFromElement(i);e(i).one(a.TRANSITION_END,s).emulateTransitionEnd(r)}else s();this._hoverState=""}},i.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},i.isWithContent=function(){return Boolean(this.getTitle())},i.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-tooltip-"+t)},i.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},i.setContent=function(){var t=this.getTipElement();this.setElementContent(e(t.querySelectorAll(".tooltip-inner")),this.getTitle()),e(t).removeClass("fade show")},i.setElementContent=function(t,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=Q(n,this.config.whiteList,this.config.sanitizeFn)),t.html(n)):t.text(n):this.config.html?e(n).parent().is(t)||t.empty().append(n):t.text(e(n).text())},i.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},i._getPopperConfig=function(t){var e=this;return s({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},i._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=s({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},i._getContainer=function(){return!1===this.config.container?document.body:a.isElement(this.config.container)?e(this.config.container):e(document).find(this.config.container)},i._getAttachment=function(t){return V[t.toUpperCase()]},i._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)e(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==n){var i="hover"===n?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===n?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;e(t.element).on(i,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},e(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=s({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},i._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},i._enter=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e(n.getTipElement()).hasClass("show")||"show"===n._hoverState?n._hoverState="show":(clearTimeout(n._timeout),n._hoverState="show",n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){"show"===n._hoverState&&n.show()}),n.config.delay.show):n.show())},i._leave=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState="out",n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){"out"===n._hoverState&&n.hide()}),n.config.delay.hide):n.hide())},i._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},i._getConfig=function(t){var n=e(this.element).data();return Object.keys(n).forEach((function(t){-1!==M.indexOf(t)&&delete n[t]})),"number"==typeof(t=s({},this.constructor.Default,n,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a.typeCheckConfig(B,t,this.constructor.DefaultType),t.sanitize&&(t.template=Q(t.template,t.whiteList,t.sanitizeFn)),t},i._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},i._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(U);null!==n&&n.length&&t.removeClass(n.join(""))},i._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},i._fixTransition=function(){var t=this.getTipElement(),n=this.config.animation;null===t.getAttribute("x-placement")&&(e(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.tooltip"),o="object"==typeof n&&n;if((i||!/dispose|hide/.test(n))&&(i||(i=new t(this,o),e(this).data("bs.tooltip",i)),"string"==typeof n)){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return z}},{key:"NAME",get:function(){return B}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return K}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return W}}]),t}();e.fn[B]=X._jQueryInterface,e.fn[B].Constructor=X,e.fn[B].noConflict=function(){return e.fn[B]=H,X._jQueryInterface};var Y="popover",$=e.fn[Y],J=new RegExp("(^|\\s)bs-popover\\S+","g"),G=s({},X.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),Z=s({},X.DefaultType,{content:"(string|element|function)"}),tt={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},et=function(t){var n,i;function s(){return t.apply(this,arguments)||this}i=t,(n=s).prototype=Object.create(i.prototype),n.prototype.constructor=n,n.__proto__=i;var r=s.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-popover-"+t)},r.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},r.setContent=function(){var t=e(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(t.find(".popover-body"),n),t.removeClass("fade show")},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(J);null!==n&&n.length>0&&t.removeClass(n.join(""))},s._jQueryInterface=function(t){return this.each((function(){var n=e(this).data("bs.popover"),i="object"==typeof t?t:null;if((n||!/dispose|hide/.test(t))&&(n||(n=new s(this,i),e(this).data("bs.popover",n)),"string"==typeof t)){if("undefined"==typeof n[t])throw new TypeError('No method named "'+t+'"');n[t]()}}))},o(s,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return G}},{key:"NAME",get:function(){return Y}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return tt}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Z}}]),s}(X);e.fn[Y]=et._jQueryInterface,e.fn[Y].Constructor=et,e.fn[Y].noConflict=function(){return e.fn[Y]=$,et._jQueryInterface};var nt="scrollspy",it=e.fn[nt],ot={offset:10,method:"auto",target:""},st={offset:"number",method:"string",target:"(string|element)"},rt=function(){function t(t,n){var i=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(n),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,e(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return i._process(t)})),this.refresh(),this._process()}var n=t.prototype;return n.refresh=function(){var t=this,n=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?n:this._config.method,o="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var n,s=a.getSelectorFromElement(t);if(s&&(n=document.querySelector(s)),n){var r=n.getBoundingClientRect();if(r.width||r.height)return[e(n)[i]().top+o,s]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){e.removeData(this._element,"bs.scrollspy"),e(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=s({},ot,"object"==typeof t&&t?t:{})).target&&a.isElement(t.target)){var n=e(t.target).attr("id");n||(n=a.getUID(nt),e(t.target).attr("id",n)),t.target="#"+n}return a.typeCheckConfig(nt,t,st),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},n._activate=function(t){this._activeTarget=t,this._clear();var n=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),i=e([].slice.call(document.querySelectorAll(n.join(","))));i.hasClass("dropdown-item")?(i.closest(".dropdown").find(".dropdown-toggle").addClass("active"),i.addClass("active")):(i.addClass("active"),i.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),i.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),e(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},n._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.scrollspy");if(i||(i=new t(this,"object"==typeof n&&n),e(this).data("bs.scrollspy",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return ot}}]),t}();e(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),n=t.length;n--;){var i=e(t[n]);rt._jQueryInterface.call(i,i.data())}})),e.fn[nt]=rt._jQueryInterface,e.fn[nt].Constructor=rt,e.fn[nt].noConflict=function(){return e.fn[nt]=it,rt._jQueryInterface};var at=e.fn.tab,lt=function(){function t(t){this._element=t}var n=t.prototype;return n.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&e(this._element).hasClass("active")||e(this._element).hasClass("disabled"))){var n,i,o=e(this._element).closest(".nav, .list-group")[0],s=a.getSelectorFromElement(this._element);if(o){var r="UL"===o.nodeName||"OL"===o.nodeName?"> li > .active":".active";i=(i=e.makeArray(e(o).find(r)))[i.length-1]}var l=e.Event("hide.bs.tab",{relatedTarget:this._element}),c=e.Event("show.bs.tab",{relatedTarget:i});if(i&&e(i).trigger(l),e(this._element).trigger(c),!c.isDefaultPrevented()&&!l.isDefaultPrevented()){s&&(n=document.querySelector(s)),this._activate(this._element,o);var h=function(){var n=e.Event("hidden.bs.tab",{relatedTarget:t._element}),o=e.Event("shown.bs.tab",{relatedTarget:i});e(i).trigger(n),e(t._element).trigger(o)};n?this._activate(n,n.parentNode,h):h()}}},n.dispose=function(){e.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(t,n,i){var o=this,s=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?e(n).children(".active"):e(n).find("> li > .active"))[0],r=i&&s&&e(s).hasClass("fade"),l=function(){return o._transitionComplete(t,s,i)};if(s&&r){var c=a.getTransitionDurationFromElement(s);e(s).removeClass("show").one(a.TRANSITION_END,l).emulateTransitionEnd(c)}else l()},n._transitionComplete=function(t,n,i){if(n){e(n).removeClass("active");var o=e(n.parentNode).find("> .dropdown-menu .active")[0];o&&e(o).removeClass("active"),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(e(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),a.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&e(t.parentNode).hasClass("dropdown-menu")){var s=e(t).closest(".dropdown")[0];if(s){var r=[].slice.call(s.querySelectorAll(".dropdown-toggle"));e(r).addClass("active")}t.setAttribute("aria-expanded",!0)}i&&i()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.tab");if(o||(o=new t(this),i.data("bs.tab",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),lt._jQueryInterface.call(e(this),"show")})),e.fn.tab=lt._jQueryInterface,e.fn.tab.Constructor=lt,e.fn.tab.noConflict=function(){return e.fn.tab=at,lt._jQueryInterface};var ct=e.fn.toast,ht={animation:"boolean",autohide:"boolean",delay:"number"},ut={animation:!0,autohide:!0,delay:500},dt=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var n=t.prototype;return n.show=function(){var t=this,n=e.Event("show.bs.toast");if(e(this._element).trigger(n),!n.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var i=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),e(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),a.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}},n.hide=function(){if(this._element.classList.contains("show")){var t=e.Event("hide.bs.toast");e(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},n.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),e(this._element).off("click.dismiss.bs.toast"),e.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=s({},ut,e(this._element).data(),"object"==typeof t&&t?t:{}),a.typeCheckConfig("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;e(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},n._close=function(){var t=this,n=function(){t._element.classList.add("hide"),e(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var i=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,n).emulateTransitionEnd(i)}else n()},n._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.toast");if(o||(o=new t(this,"object"==typeof n&&n),i.data("bs.toast",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](this)}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"DefaultType",get:function(){return ht}},{key:"Default",get:function(){return ut}}]),t}();e.fn.toast=dt._jQueryInterface,e.fn.toast.Constructor=dt,e.fn.toast.noConflict=function(){return e.fn.toast=ct,dt._jQueryInterface},t.Alert=h,t.Button=d,t.Carousel=b,t.Collapse=C,t.Dropdown=I,t.Modal=P,t.Popover=et,t.Scrollspy=rt,t.Tab=lt,t.Toast=dt,t.Tooltip=X,t.Util=a,Object.defineProperty(t,"__esModule",{value:!0})}));
7
+ //# sourceMappingURL=bootstrap.min.js.map
public/js/woo_route.js ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var $ = jQuery;
2
+
3
+ var max_fields = 5; //maximum input boxes allowed
4
+ var wrapper = $(".rzp_transfer_custom_field"); //Fields wrapper
5
+ var add_button = $(".add_field_button"); //Add button ID
6
+
7
+ var x = 1;
8
+ $(add_button).click(function (e) {
9
+ e.preventDefault();
10
+ if (x < max_fields) {
11
+ x++;
12
+ $(wrapper).append('<p><input type="text" name="LA_number[]" placeholder="Linked Account Number"/><input type="number" name="LA_transfer_amount[]" class="LA_transfer_amount" placeholder="Amount"><label class="trf_settlement_label">Hold Settlement:</label><select name="LA_transfer_status[]"><optgroup label="On Hold"> <option value="1"> Yes</option><option value="0" selected> No</option></optgroup></select> <a href="#" class="remove_field">Remove</a></p>'); //add input box
13
+ }
14
+ });
15
+
16
+ $(wrapper).on("click", ".remove_field", function (e) { //user click on remove text
17
+ e.preventDefault();
18
+ $(this).parent('p').remove();
19
+ x--;
20
+ });
21
+
22
+ $(document).on('keyup', ".LA_transfer_amount",function () {
23
+
24
+ var productPrice = $('#_regular_price').val();
25
+ var trfAmount = 0;
26
+
27
+ $('input[name^=LA_transfer_amount]').each(function () {
28
+ var price = $(this).val();
29
+ trfAmount += Number(price);
30
+ });
31
+ if (trfAmount > productPrice) {
32
+ $('#transfer_err_msg').text('The sum of amount requested for transfer is greater than the product price');
33
+ } else {
34
+ $('#transfer_err_msg').text('');
35
+ }
36
+ });
37
+
38
+ $(document).on('keyup', "#trf_reversal_amount", function () {
39
+ var defaultValue = parseInt($(this).attr('value'));
40
+ var newValue = parseInt($(this).prop('value'));
41
+ if (newValue > defaultValue) {
42
+ $('#trf_reverse_text').text('Amount can\'t be greater than the total Reversible Amount.');
43
+ $('#reverse_transfer_btn').attr("disabled", true);
44
+ }else {
45
+ $('#trf_reverse_text').text('');
46
+ $("#reverse_transfer_btn").removeAttr("disabled");
47
+ }
48
+ });
49
+
50
+ $(document).on('keyup', "#payment_trf_amount", function () {
51
+ var defaultValue = parseInt($(this).attr('value'));
52
+ var newValue = parseInt($(this).prop('value'));
53
+ if (newValue > defaultValue) {
54
+ $('#payment_trf_error').text('Transfer amount can not exceed payment amount.');
55
+ $('#payment_transfer_btn').attr("disabled", true);
56
+ }else {
57
+ $('#payment_trf_error').text('');
58
+ $("#payment_transfer_btn").removeAttr("disabled");
59
+ }
60
+ });
61
+
62
+ $(function(){
63
+ $('input[name="rzp_transfer_from"]').click(function(){
64
+ var $routeTransferRadio = $(this);
65
+
66
+ // if this was previously checked
67
+ if ($routeTransferRadio.data('waschecked') == true)
68
+ {
69
+ $routeTransferRadio.prop('checked', false);
70
+ $routeTransferRadio.data('waschecked', false);
71
+ }
72
+ else
73
+ $routeTransferRadio.data('waschecked', true);
74
+
75
+ // remove was checked from other radios
76
+ $routeTransferRadio.siblings('input[name="rzp_transfer_from"]').data('waschecked', false);
77
+ });
78
+ });
79
+
80
+
81
+ $(".enable_hold_until").click(function() {
82
+ $("#hold_until").attr("disabled", false);
83
+ });
84
+
85
+ $(".disable_hold_until").click(function() {
86
+ $("#hold_until").attr("disabled", true);
87
+ });
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: razorpay
3
  Tags: razorpay, payments, india, woocommerce, ecommerce
4
  Requires at least: 3.9.2
5
  Tested up to: 5.9
6
- Stable tag: 2.8.6
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -41,6 +41,9 @@ This is compatible with WooCommerce>=2.4, including the new 3.0 release. It has
41
 
42
  == Changelog ==
43
 
 
 
 
44
  = 2.8.6 =
45
  * Bug fix for not reflecting an updated order success message.
46
  * Tested upto Wordpress 5.9
3
  Tags: razorpay, payments, india, woocommerce, ecommerce
4
  Requires at least: 3.9.2
5
  Tested up to: 5.9
6
+ Stable tag: 3.0.0
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
41
 
42
  == Changelog ==
43
 
44
+ = 3.0.0 =
45
+ * Added Magic Checkout feature.
46
+
47
  = 2.8.6 =
48
  * Bug fix for not reflecting an updated order success message.
49
  * Tested upto Wordpress 5.9
templates/rzp-cart-checkout-btn.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <style type="text/css">
2
+ .checkout-button {
3
+ display: none !important;
4
+ }
5
+ </style>
6
+ <div>
7
+ <button
8
+ id="btn-1cc"
9
+ class="rzp-checkout-button button alt wc-forward"
10
+ type="button"
11
+ >PROCEED TO CHECKOUT
12
+ </button>
13
+ </div>
14
+
15
+ <div id="rzp-spinner-backdrop"></div>
16
+ <div id="rzp-spinner">
17
+ <div id="loading-indicator"></div>
18
+ <div id="icon">
19
+ <img src="<?php echo plugin_dir_url(dirname(__FILE__)) . 'public/images/rzp-spinner.svg'; ?>" alt="Loading" id="rzp-logo" />
20
+ </div>
21
+ </div>
22
+ <div id="error-message">
23
+ </div>
templates/rzp-mini-checkout-btn.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div>
2
+ <button
3
+ id="btn-1cc-mini-cart"
4
+ class="button checkout wc-forward"
5
+ type="button"
6
+ >CHECKOUT
7
+ </button>
8
+ </div>
9
+ <div id="rzp-spinner-backdrop"></div>
10
+ <div id="rzp-spinner">
11
+ <div id="loading-indicator"></div>
12
+ <div id="icon">
13
+ <img src="<?php echo plugin_dir_url(dirname(__FILE__)) . 'public/images/rzp-spinner.svg'; ?>" alt="Loading" id="rzp-logo" />
14
+ </div>
15
+ </div>
16
+ <div id="error-message">
17
+ </div>
templates/rzp-pdp-checkout-btn.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ global $product;
3
+ $productData = wp_json_encode(['id' => $product->get_id(), 'quantity' => 1]);
4
+ ?>
5
+ <button
6
+ id="btn-1cc-pdp"
7
+ class="button alt single_add_to_cart_button"
8
+ type="button"
9
+ product_id="<?php echo esc_attr($product->get_id()); ?>"
10
+ pdp_checkout="<?php echo true; ?>"
11
+ >BUY NOW
12
+ </button>
13
+
14
+ <div id="rzp-spinner-backdrop"></div>
15
+ <div id="rzp-spinner">
16
+ <div id="loading-indicator"></div>
17
+ <div id="icon">
18
+ <img src="<?php echo plugin_dir_url(dirname(__FILE__)) . 'public/images/rzp-spinner.svg'; ?>" alt="Loading" id="rzp-logo" />
19
+ </div>
20
+ </div>
21
+ <div id="error-message">
22
+ </div>
23
+
24
+ <script type="">
25
+ var quantity = document.getElementsByClassName("qty")[0].value;
26
+
27
+ var btnPdp = document.getElementById('btn-1cc-pdp');
28
+
29
+ btnPdp.setAttribute('quantity', quantity);
30
+
31
+ jQuery('.qty').on('change',function(e)
32
+ {
33
+ var quantity = document.getElementsByClassName("qty")[0].value;
34
+ btnPdp.setAttribute('quantity', quantity);
35
+
36
+ if(quantity <= 0)
37
+ {
38
+ btnPdp.classList.add("disabled");
39
+ btnPdp.disabled = true;
40
+ }
41
+ else
42
+ {
43
+ btnPdp.classList.remove("disabled");
44
+ btnPdp.disabled = false;
45
+ }
46
+ });
47
+
48
+ (function($){
49
+
50
+ $('form.variations_form').on('show_variation', function(event, data){
51
+
52
+ btnPdp.classList.remove("disabled");
53
+ btnPdp.disabled = false;
54
+
55
+ btnPdp.setAttribute('variation_id', data.variation_id);
56
+
57
+ var variationArr = {};
58
+
59
+ $.each( data.attributes, function( key, value ) {
60
+ variationArr[key] = $("[name="+key+"]").val();
61
+ });
62
+
63
+ btnPdp.setAttribute('variations', JSON.stringify(variationArr));
64
+
65
+ }).on('hide_variation', function() {
66
+
67
+ btnPdp.classList.add("disabled");
68
+ btnPdp.disabled = true;
69
+ });
70
+ })(jQuery);
71
+ </script>
woo-razorpay.php CHANGED
@@ -3,8 +3,8 @@
3
  * Plugin Name: Razorpay for WooCommerce
4
  * Plugin URI: https://razorpay.com
5
  * Description: Razorpay Payment Gateway Integration for WooCommerce
6
- * Version: 2.8.6
7
- * Stable tag: 2.8.6
8
  * Author: Team Razorpay
9
  * WC tested up to: 6.2.0
10
  * Author URI: https://razorpay.com
@@ -20,6 +20,9 @@ require_once __DIR__.'/razorpay-sdk/Razorpay.php';
20
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
21
  require_once __DIR__.'/includes/razorpay-route.php';
22
  require_once __DIR__ .'/includes/razorpay-route-actions.php';
 
 
 
23
 
24
  use Razorpay\Api\Api;
25
  use Razorpay\Api\Errors;
@@ -40,6 +43,7 @@ function woocommerce_razorpay_init()
40
  const SESSION_KEY = 'razorpay_wc_order_id';
41
  const RAZORPAY_PAYMENT_ID = 'razorpay_payment_id';
42
  const RAZORPAY_ORDER_ID = 'razorpay_order_id';
 
43
  const RAZORPAY_SIGNATURE = 'razorpay_signature';
44
  const RAZORPAY_WC_FORM_SUBMIT = 'razorpay_wc_form_submit';
45
 
@@ -142,6 +146,38 @@ function woocommerce_razorpay_init()
142
  public function __construct($hooks = true)
143
  {
144
  $this->icon = "https://cdn.razorpay.com/static/assets/logo/payment.svg";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
  $this->init_form_fields();
147
  $this->init_settings();
@@ -170,11 +206,13 @@ function woocommerce_razorpay_init()
170
  {
171
  add_action("woocommerce_update_options_payment_gateways_{$this->id}", $cb);
172
  add_action( "woocommerce_update_options_payment_gateways_{$this->id}", array($this, 'autoEnableWebhook'));
 
173
  }
174
  else
175
  {
176
  add_action('woocommerce_update_options_payment_gateways', $cb);
177
  add_action( "woocommerce_update_options_payment_gateways", array($this, 'autoEnableWebhook'));
 
178
  }
179
 
180
  add_filter( 'woocommerce_thankyou_order_received_text', array($this, 'getCustomOrdercreationMessage'), 20, 2 );
@@ -257,7 +295,6 @@ function woocommerce_razorpay_init()
257
  'description' => __('Webhook secret is used for webhook signature verification. This has to match the one added <a href="https://dashboard.razorpay.com/#/app/webhooks">here</a>', $this->id),
258
  'default' => ''
259
  ),
260
-
261
  );
262
 
263
  do_action_ref_array( 'setup_extra_setting_fields', array( &$defaultFormFields ) );
@@ -393,6 +430,30 @@ function woocommerce_razorpay_init()
393
 
394
  }
395
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  protected function webhookAPI($method, $url, $data = array())
397
  {
398
  $webhook = [];
@@ -446,6 +507,12 @@ function woocommerce_razorpay_init()
446
  */
447
  protected function getOrderSessionKey($orderId)
448
  {
 
 
 
 
 
 
449
  return self::RAZORPAY_ORDER_ID . $orderId;
450
  }
451
 
@@ -458,18 +525,26 @@ function woocommerce_razorpay_init()
458
  * @param string $orderId Order Id
459
  * @return mixed Razorpay Order Id or Exception
460
  */
461
- protected function createOrGetRazorpayOrderId($orderId)
462
  {
463
  global $woocommerce;
464
-
465
- $sessionKey = $this->getOrderSessionKey($orderId);
466
 
467
  $create = false;
468
 
 
 
 
 
 
 
 
469
  try
470
  {
471
  $razorpayOrderId = get_transient($sessionKey);
472
-
 
 
473
  // If we don't have an Order
474
  // or the if the order is present in transient but doesn't match what we have saved
475
  if (($razorpayOrderId === false) or
@@ -521,7 +596,8 @@ function woocommerce_razorpay_init()
521
  'wc-api' => $this->id,
522
  'order_key' => $order->get_order_key(),
523
  ];
524
- return add_query_arg($query, trailingslashit( get_home_url()));
 
525
  }
526
 
527
  /**
@@ -532,6 +608,7 @@ function woocommerce_razorpay_init()
532
  */
533
  protected function getRazorpayPaymentParams($orderId)
534
  {
 
535
  $razorpayOrderId = $this->createOrGetRazorpayOrderId($orderId);
536
 
537
  if ($razorpayOrderId === null)
@@ -581,7 +658,7 @@ function woocommerce_razorpay_init()
581
  * @param WC_Order $order WC Order
582
  * @return array checkout params
583
  */
584
- private function getDefaultCheckoutArguments($order)
585
  {
586
  global $woocommerce;
587
 
@@ -591,7 +668,8 @@ function woocommerce_razorpay_init()
591
 
592
  $callbackUrl = $this->getRedirectUrl($wcOrderId);
593
 
594
- $sessionKey = $this->getOrderSessionKey($orderId);
 
595
  $razorpayOrderId = get_transient($sessionKey);
596
 
597
  $productinfo = "Order $orderId";
@@ -665,13 +743,15 @@ function woocommerce_razorpay_init()
665
 
666
  protected function createRazorpayOrderId($orderId, $sessionKey)
667
  {
 
668
  // Calls the helper function to create order data
669
  global $woocommerce;
670
 
671
  $api = $this->getRazorpayApiInstance();
672
 
673
  $data = $this->getOrderCreationData($orderId);
674
-
 
675
  try
676
  {
677
  $razorpayOrder = $api->order->create($data);
@@ -684,9 +764,9 @@ function woocommerce_razorpay_init()
684
  $razorpayOrderId = $razorpayOrder['id'];
685
 
686
  set_transient($sessionKey, $razorpayOrderId, 3600);
687
-
688
  $woocommerce->session->set($sessionKey, $razorpayOrderId);
689
 
 
690
  //update it in order comments
691
  $order = wc_get_order($orderId);
692
 
@@ -697,6 +777,7 @@ function woocommerce_razorpay_init()
697
 
698
  protected function verifyOrderAmount($razorpayOrderId, $orderId)
699
  {
 
700
  $order = wc_get_order($orderId);
701
 
702
  $api = $this->getRazorpayApiInstance();
@@ -708,6 +789,7 @@ function woocommerce_razorpay_init()
708
  catch (Exception $e)
709
  {
710
  $message = $e->getMessage();
 
711
  return "RAZORPAY ERROR: Order fetch failed with the message '$message'";
712
  }
713
 
@@ -735,8 +817,11 @@ function woocommerce_razorpay_init()
735
 
736
  private function getOrderCreationData($orderId)
737
  {
 
738
  $order = wc_get_order($orderId);
739
 
 
 
740
  $data = array(
741
  'receipt' => $orderId,
742
  'amount' => (int) round($order->get_total() * 100),
@@ -748,7 +833,7 @@ function woocommerce_razorpay_init()
748
  ),
749
  );
750
 
751
- if($this->getSetting('route_enable') == 'yes')
752
  {
753
  $razorpayRoute = new RZP_Route_Action();
754
  $orderTransferArr = $razorpayRoute->getOrderTransferData($orderId);
@@ -762,10 +847,23 @@ function woocommerce_razorpay_init()
762
  }
763
  }
764
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765
  return $data;
766
  }
767
 
768
- public function enqueueCheckoutScripts($data)
769
  {
770
  if($data === 'checkoutForm' || $data === 'routeAnalyticsForm')
771
  {
@@ -930,10 +1028,15 @@ EOT;
930
  **/
931
  function process_payment($order_id)
932
  {
 
 
933
  global $woocommerce;
934
 
935
  $order = wc_get_order($order_id);
936
 
 
 
 
937
  $orderKey = $this->getOrderKey($order);
938
 
939
  if (version_compare(WOOCOMMERCE_VERSION, '2.1', '>='))
@@ -968,37 +1071,55 @@ EOT;
968
 
969
  /**
970
  * Check for valid razorpay server callback
971
- **/
 
972
  function check_razorpay_response()
973
  {
974
  global $woocommerce;
975
  global $wpdb;
976
 
977
  $order = false;
 
978
 
979
  $post_type = 'shop_order';
 
980
  $post_password = sanitize_text_field($_GET['order_key']);
981
 
982
  $postIds = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts AS P WHERE post_type=%s AND post_password = %s", $post_type, $post_password ) );
983
 
984
- if(count($postIds) > 0)
985
  {
986
  $orderId = $postIds[0];
987
  $order = wc_get_order($orderId);
 
988
  }
989
 
990
- if($order === false)
 
991
  {
 
 
 
 
 
 
992
  wp_redirect(wc_get_checkout_url());
993
  exit;
994
  }
995
 
996
- //
997
  // If the order has already been paid for
998
  // redirect user to success page
999
- //
1000
  if ($order->needs_payment() === false)
1001
  {
 
 
 
 
 
 
 
 
 
1002
  $this->redirectUser($order);
1003
  }
1004
 
@@ -1014,6 +1135,15 @@ EOT;
1014
  $this->verifySignature($orderId);
1015
  $success = true;
1016
  $razorpayPaymentId = sanitize_text_field($_POST[self::RAZORPAY_PAYMENT_ID]);
 
 
 
 
 
 
 
 
 
1017
  }
1018
  catch (Errors\SignatureVerificationError $e)
1019
  {
@@ -1022,7 +1152,7 @@ EOT;
1022
  }
1023
  else
1024
  {
1025
- if($_POST[self::RAZORPAY_WC_FORM_SUBMIT] ==1)
1026
  {
1027
  $success = false;
1028
  $error = 'Customer cancelled the payment';
@@ -1033,9 +1163,27 @@ EOT;
1033
  $error = "Payment Failed.";
1034
  }
1035
 
 
 
 
 
 
 
 
 
 
 
 
 
1036
  $this->handleErrorCase($order);
1037
  $this->updateOrder($order, $success, $error, $razorpayPaymentId, null);
1038
 
 
 
 
 
 
 
1039
  wp_redirect(wc_get_checkout_url());
1040
  exit;
1041
  }
@@ -1055,6 +1203,8 @@ EOT;
1055
 
1056
  protected function verifySignature($orderId)
1057
  {
 
 
1058
  global $woocommerce;
1059
 
1060
  $api = $this->getRazorpayApiInstance();
@@ -1065,7 +1215,6 @@ EOT;
1065
  );
1066
 
1067
  $sessionKey = $this->getOrderSessionKey($orderId);
1068
-
1069
  //Check the transient data for razorpay order id, if it's not available then look into session data.
1070
  if(get_transient($sessionKey))
1071
  {
@@ -1077,7 +1226,8 @@ EOT;
1077
  }
1078
 
1079
  $attributes[self::RAZORPAY_ORDER_ID] = $razorpayOrderId?? '';
1080
-
 
1081
  $api->utility->verifyPaymentSignature($attributes);
1082
  }
1083
 
@@ -1089,6 +1239,8 @@ EOT;
1089
  protected function getErrorMessage($orderId)
1090
  {
1091
  // We don't have a proper order id
 
 
1092
  if ($orderId !== null)
1093
  {
1094
  $message = 'An error occured while processing this payment';
@@ -1112,7 +1264,7 @@ EOT;
1112
  {
1113
  $message = 'An error occured. Please contact administrator for assistance';
1114
  }
1115
-
1116
  return $message;
1117
  }
1118
 
@@ -1127,9 +1279,42 @@ EOT;
1127
 
1128
  $orderId = $order->get_order_number();
1129
 
 
 
1130
  if (($success === true) and ($order->needs_payment() === true))
1131
  {
1132
- $order->payment_complete($razorpayPaymentId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1133
  $order->add_order_note("Razorpay payment successful <br/>Razorpay Id: $razorpayPaymentId");
1134
 
1135
  if($this->getSetting('route_enable') == 'yes')
@@ -1168,13 +1353,276 @@ EOT;
1168
  if ($webhook === false)
1169
  {
1170
  $this->add_notice($this->msg['message'], $this->msg['class']);
 
 
 
 
 
 
1171
  }
1172
  }
1173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1174
  protected function handleErrorCase(& $order)
1175
  {
1176
  $orderId = $order->get_order_number();
1177
-
1178
  $this->msg['class'] = 'error';
1179
  $this->msg['message'] = $this->getErrorMessage($orderId);
1180
  }
@@ -1236,6 +1684,34 @@ EOT;
1236
 
1237
  }
1238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1239
  /**
1240
  * Add the Gateway to WooCommerce
1241
  **/
@@ -1245,7 +1721,7 @@ EOT;
1245
  return $methods;
1246
  }
1247
 
1248
- add_filter('woocommerce_payment_gateways', 'woocommerce_add_razorpay_gateway' );
1249
 
1250
  /**
1251
  * Creating the settings link from the plugins page
@@ -1273,3 +1749,151 @@ function razorpay_webhook_init()
1273
 
1274
  $rzpWebhook->process();
1275
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  * Plugin Name: Razorpay for WooCommerce
4
  * Plugin URI: https://razorpay.com
5
  * Description: Razorpay Payment Gateway Integration for WooCommerce
6
+ * Version: 3.0.0
7
+ * Stable tag: 3.0.0
8
  * Author: Team Razorpay
9
  * WC tested up to: 6.2.0
10
  * Author URI: https://razorpay.com
20
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
21
  require_once __DIR__.'/includes/razorpay-route.php';
22
  require_once __DIR__ .'/includes/razorpay-route-actions.php';
23
+ require_once __DIR__.'/includes/api/api.php';
24
+ require_once __DIR__.'/includes/utils.php';
25
+ require_once __DIR__.'/includes/state-map.php';
26
 
27
  use Razorpay\Api\Api;
28
  use Razorpay\Api\Errors;
43
  const SESSION_KEY = 'razorpay_wc_order_id';
44
  const RAZORPAY_PAYMENT_ID = 'razorpay_payment_id';
45
  const RAZORPAY_ORDER_ID = 'razorpay_order_id';
46
+ const RAZORPAY_ORDER_ID_1CC = 'razorpay_order_id_1cc';
47
  const RAZORPAY_SIGNATURE = 'razorpay_signature';
48
  const RAZORPAY_WC_FORM_SUBMIT = 'razorpay_wc_form_submit';
49
 
146
  public function __construct($hooks = true)
147
  {
148
  $this->icon = "https://cdn.razorpay.com/static/assets/logo/payment.svg";
149
+ // 1cc flags should be enabled only if merchant has access to 1cc feature
150
+ $is1ccAvailable = false;
151
+
152
+ try {
153
+ $api = new Api($this->getSetting('key_id'), '');
154
+ $merchantPreferences = $api->request->request('GET', 'preferences');
155
+
156
+ if (!empty($merchantPreferences['features']['one_click_checkout'])) {
157
+ $is1ccAvailable = true;
158
+ }
159
+
160
+ } catch (\Exception $e) {
161
+ rzpLogError($e->getMessage());
162
+ }
163
+
164
+
165
+ if ($is1ccAvailable) {
166
+ $this->visibleSettings = array_merge($this->visibleSettings, array(
167
+ 'enable_1cc',
168
+ 'enable_1cc_mandatory_login',
169
+ 'enable_1cc_cod_intelligence',
170
+ 'enable_1cc_test_mode',
171
+ 'enable_1cc_debug_mode',
172
+ 'enable_1cc_pdp_checkout',
173
+ 'enable_1cc_mini_cart_checkout',
174
+ 'enable_1cc_ga_analytics',
175
+ 'enable_1cc_fb_analytics',
176
+ '1cc_min_cart_amount',
177
+ '1cc_min_COD_slab_amount',
178
+ '1cc_max_COD_slab_amount',
179
+ ));
180
+ }
181
 
182
  $this->init_form_fields();
183
  $this->init_settings();
206
  {
207
  add_action("woocommerce_update_options_payment_gateways_{$this->id}", $cb);
208
  add_action( "woocommerce_update_options_payment_gateways_{$this->id}", array($this, 'autoEnableWebhook'));
209
+ add_action( "woocommerce_update_options_payment_gateways_{$this->id}", array($this, 'addAdminCheckoutSettingsAlert'));
210
  }
211
  else
212
  {
213
  add_action('woocommerce_update_options_payment_gateways', $cb);
214
  add_action( "woocommerce_update_options_payment_gateways", array($this, 'autoEnableWebhook'));
215
+ add_action( "woocommerce_update_options_payment_gateways", array($this, 'addAdminCheckoutSettingsAlert'));
216
  }
217
 
218
  add_filter( 'woocommerce_thankyou_order_received_text', array($this, 'getCustomOrdercreationMessage'), 20, 2 );
295
  'description' => __('Webhook secret is used for webhook signature verification. This has to match the one added <a href="https://dashboard.razorpay.com/#/app/webhooks">here</a>', $this->id),
296
  'default' => ''
297
  ),
 
298
  );
299
 
300
  do_action_ref_array( 'setup_extra_setting_fields', array( &$defaultFormFields ) );
430
 
431
  }
432
 
433
+ // showing notice : status of 1cc active / inactive message in admin dashboard
434
+ function addAdminCheckoutSettingsAlert() {
435
+ $enable_1cc = $this->getSetting('enable_1cc');
436
+ if($enable_1cc == 'no')
437
+ {
438
+ ?>
439
+ <div class="notice error is-dismissible" >
440
+ <p><b><?php _e( 'We are sorry to see you opt out of Magic Checkout experience. Please help us understand what went wrong by filling up this form.'); ?></b></p>
441
+ </div>
442
+ <?php
443
+ error_log('1cc is disabled.');
444
+ return;
445
+ }
446
+ elseif ($enable_1cc == 'yes')
447
+ {
448
+ ?>
449
+ <div class="notice notice-success is-dismissible" >
450
+ <p><b><?php _e( 'You are Live with Magic Checkout.'); ?></b></p>
451
+ </div>
452
+ <?php
453
+ return;
454
+ }
455
+ }
456
+
457
  protected function webhookAPI($method, $url, $data = array())
458
  {
459
  $webhook = [];
507
  */
508
  protected function getOrderSessionKey($orderId)
509
  {
510
+ $is1ccOrder = get_post_meta( $orderId, 'is_magic_checkout_order', true );
511
+
512
+ if($is1ccOrder == 'yes')
513
+ {
514
+ return self::RAZORPAY_ORDER_ID_1CC . $orderId;
515
+ }
516
  return self::RAZORPAY_ORDER_ID . $orderId;
517
  }
518
 
525
  * @param string $orderId Order Id
526
  * @return mixed Razorpay Order Id or Exception
527
  */
528
+ public function createOrGetRazorpayOrderId($orderId, $is1ccCheckout = 'no')
529
  {
530
  global $woocommerce;
531
+ rzpLogInfo("createOrGetRazorpayOrderId $orderId");
 
532
 
533
  $create = false;
534
 
535
+ if($is1ccCheckout == 'no')
536
+ {
537
+ update_post_meta( $orderId, 'is_magic_checkout_order', 'no' );
538
+ }
539
+
540
+ $sessionKey = $this->getOrderSessionKey($orderId);
541
+
542
  try
543
  {
544
  $razorpayOrderId = get_transient($sessionKey);
545
+ rzpLogInfo("razorpayOrderId $razorpayOrderId | sessionKey $sessionKey");
546
+ rzpLogInfo("verifying amt");
547
+ rzpLogInfo($this->verifyOrderAmount($razorpayOrderId, $orderId));
548
  // If we don't have an Order
549
  // or the if the order is present in transient but doesn't match what we have saved
550
  if (($razorpayOrderId === false) or
596
  'wc-api' => $this->id,
597
  'order_key' => $order->get_order_key(),
598
  ];
599
+
600
+ return add_query_arg($query, trailingslashit(get_home_url()));
601
  }
602
 
603
  /**
608
  */
609
  protected function getRazorpayPaymentParams($orderId)
610
  {
611
+ rzpLogInfo("getRazorpayPaymentParams $orderId");
612
  $razorpayOrderId = $this->createOrGetRazorpayOrderId($orderId);
613
 
614
  if ($razorpayOrderId === null)
658
  * @param WC_Order $order WC Order
659
  * @return array checkout params
660
  */
661
+ public function getDefaultCheckoutArguments($order)
662
  {
663
  global $woocommerce;
664
 
668
 
669
  $callbackUrl = $this->getRedirectUrl($wcOrderId);
670
 
671
+ $sessionKey = $this->getOrderSessionKey($wcOrderId);
672
+
673
  $razorpayOrderId = get_transient($sessionKey);
674
 
675
  $productinfo = "Order $orderId";
743
 
744
  protected function createRazorpayOrderId($orderId, $sessionKey)
745
  {
746
+ rzpLogInfo("Called createRazorpayOrderId with params orderId $orderId and sessionKey $sessionKey");
747
  // Calls the helper function to create order data
748
  global $woocommerce;
749
 
750
  $api = $this->getRazorpayApiInstance();
751
 
752
  $data = $this->getOrderCreationData($orderId);
753
+ rzpLogInfo('For order ' . $orderId);
754
+ rzpLogInfo(json_encode($data));
755
  try
756
  {
757
  $razorpayOrder = $api->order->create($data);
764
  $razorpayOrderId = $razorpayOrder['id'];
765
 
766
  set_transient($sessionKey, $razorpayOrderId, 3600);
 
767
  $woocommerce->session->set($sessionKey, $razorpayOrderId);
768
 
769
+ rzpLogInfo('For order session key ' . $sessionKey);
770
  //update it in order comments
771
  $order = wc_get_order($orderId);
772
 
777
 
778
  protected function verifyOrderAmount($razorpayOrderId, $orderId)
779
  {
780
+ rzpLogInfo("Called verifyOrderAmount with params orderId $orderId and rzporderId $razorpayOrderId");
781
  $order = wc_get_order($orderId);
782
 
783
  $api = $this->getRazorpayApiInstance();
789
  catch (Exception $e)
790
  {
791
  $message = $e->getMessage();
792
+ rzpLogInfo("Failed at verifyOrderAmount with $message");
793
  return "RAZORPAY ERROR: Order fetch failed with the message '$message'";
794
  }
795
 
817
 
818
  private function getOrderCreationData($orderId)
819
  {
820
+ rzpLogInfo("Called getOrderCreationData with params orderId $orderId");
821
  $order = wc_get_order($orderId);
822
 
823
+ $is1ccOrder = get_post_meta( $orderId, 'is_magic_checkout_order', true );
824
+
825
  $data = array(
826
  'receipt' => $orderId,
827
  'amount' => (int) round($order->get_total() * 100),
833
  ),
834
  );
835
 
836
+ if ($this->getSetting('route_enable') == 'yes')
837
  {
838
  $razorpayRoute = new RZP_Route_Action();
839
  $orderTransferArr = $razorpayRoute->getOrderTransferData($orderId);
847
  }
848
  }
849
 
850
+ if (is1ccEnabled() && !empty($is1ccOrder) && $is1ccOrder == 'yes')
851
+ {
852
+ $data = $this->orderArg1CC($data, $order);
853
+ }
854
+
855
+ return $data;
856
+ }
857
+
858
+ public function orderArg1CC($data, $order)
859
+ {
860
+ // TODO: trim to 2 deciamls
861
+ $data['line_items_total'] = $order->get_total()*100;
862
+
863
  return $data;
864
  }
865
 
866
+ private function enqueueCheckoutScripts($data)
867
  {
868
  if($data === 'checkoutForm' || $data === 'routeAnalyticsForm')
869
  {
1028
  **/
1029
  function process_payment($order_id)
1030
  {
1031
+ rzpLogInfo("Called process_payment with params order_id $order_id");
1032
+
1033
  global $woocommerce;
1034
 
1035
  $order = wc_get_order($order_id);
1036
 
1037
+ set_transient(self::SESSION_KEY, $order_id, 3600);
1038
+ rzpLogInfo("Set transient with key " . self::SESSION_KEY . " params order_id $order_id");
1039
+
1040
  $orderKey = $this->getOrderKey($order);
1041
 
1042
  if (version_compare(WOOCOMMERCE_VERSION, '2.1', '>='))
1071
 
1072
  /**
1073
  * Check for valid razorpay server callback
1074
+ * Called once payment is completed using redirect method
1075
+ */
1076
  function check_razorpay_response()
1077
  {
1078
  global $woocommerce;
1079
  global $wpdb;
1080
 
1081
  $order = false;
1082
+ rzpLogInfo("Called check_razorpay_response");
1083
 
1084
  $post_type = 'shop_order';
1085
+
1086
  $post_password = sanitize_text_field($_GET['order_key']);
1087
 
1088
  $postIds = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts AS P WHERE post_type=%s AND post_password = %s", $post_type, $post_password ) );
1089
 
1090
+ if (count($postIds) > 0)
1091
  {
1092
  $orderId = $postIds[0];
1093
  $order = wc_get_order($orderId);
1094
+ rzpLogInfo("get_transient in check_razorpay_response: orderId $orderId");
1095
  }
1096
 
1097
+ // TODO: Handle redirect
1098
+ if ($order === false)
1099
  {
1100
+ // TODO: Add test mode condition
1101
+ if (is1ccEnabled())
1102
+ {
1103
+ wp_redirect(wc_get_cart_url());
1104
+ exit;
1105
+ }
1106
  wp_redirect(wc_get_checkout_url());
1107
  exit;
1108
  }
1109
 
 
1110
  // If the order has already been paid for
1111
  // redirect user to success page
 
1112
  if ($order->needs_payment() === false)
1113
  {
1114
+ $cartHash = get_transient(RZP_1CC_CART_HASH.$orderId);
1115
+
1116
+ if ($cartHash != false)
1117
+ {
1118
+ // Need to delete the cart hash stored in transient.
1119
+ // Becuase the cart hash will be depending on the cart items so this will cause the issue when order api triggers.
1120
+ $woocommerce->session->__unset(RZP_1CC_CART_HASH.$cartHash);
1121
+ }
1122
+
1123
  $this->redirectUser($order);
1124
  }
1125
 
1135
  $this->verifySignature($orderId);
1136
  $success = true;
1137
  $razorpayPaymentId = sanitize_text_field($_POST[self::RAZORPAY_PAYMENT_ID]);
1138
+
1139
+ $cartHash = get_transient(RZP_1CC_CART_HASH.$orderId);
1140
+
1141
+ if ($cartHash != false)
1142
+ {
1143
+ // Need to delete the cart hash stored in transient.
1144
+ // Becuase the cart hash will be depending on the cart items so this will cause the issue when order api triggers.
1145
+ $woocommerce->session->__unset(RZP_1CC_CART_HASH.$cartHash);
1146
+ }
1147
  }
1148
  catch (Errors\SignatureVerificationError $e)
1149
  {
1152
  }
1153
  else
1154
  {
1155
+ if(isset($_POST[self::RAZORPAY_WC_FORM_SUBMIT]) && $_POST[self::RAZORPAY_WC_FORM_SUBMIT] ==1)
1156
  {
1157
  $success = false;
1158
  $error = 'Customer cancelled the payment';
1163
  $error = "Payment Failed.";
1164
  }
1165
 
1166
+ $is1ccOrder = get_post_meta( $orderId, 'is_magic_checkout_order', true );
1167
+
1168
+ if (is1ccEnabled() && !empty($is1ccOrder) && $is1ccOrder == 'yes')
1169
+ {
1170
+ $api = $this->getRazorpayApiInstance();
1171
+ $sessionKey = $this->getOrderSessionKey($orderId);
1172
+ $razorpayOrderId = get_transient($sessionKey);
1173
+ $razorpayData = $api->order->fetch($razorpayOrderId);
1174
+
1175
+ $this->updateOrderAddress($razorpayData['items'][0], $order);
1176
+ }
1177
+
1178
  $this->handleErrorCase($order);
1179
  $this->updateOrder($order, $success, $error, $razorpayPaymentId, null);
1180
 
1181
+ if (is1ccEnabled())
1182
+ {
1183
+ wp_redirect(wc_get_cart_url());
1184
+ exit;
1185
+ }
1186
+
1187
  wp_redirect(wc_get_checkout_url());
1188
  exit;
1189
  }
1203
 
1204
  protected function verifySignature($orderId)
1205
  {
1206
+ rzpLogInfo("verifySignature orderId: $orderId");
1207
+
1208
  global $woocommerce;
1209
 
1210
  $api = $this->getRazorpayApiInstance();
1215
  );
1216
 
1217
  $sessionKey = $this->getOrderSessionKey($orderId);
 
1218
  //Check the transient data for razorpay order id, if it's not available then look into session data.
1219
  if(get_transient($sessionKey))
1220
  {
1226
  }
1227
 
1228
  $attributes[self::RAZORPAY_ORDER_ID] = $razorpayOrderId?? '';
1229
+ rzpLogInfo("verifySignature attr");
1230
+ rzpLogInfo(json_encode($attributes));
1231
  $api->utility->verifyPaymentSignature($attributes);
1232
  }
1233
 
1239
  protected function getErrorMessage($orderId)
1240
  {
1241
  // We don't have a proper order id
1242
+ rzpLogInfo("getErrorMessage orderId: $orderId");
1243
+
1244
  if ($orderId !== null)
1245
  {
1246
  $message = 'An error occured while processing this payment';
1264
  {
1265
  $message = 'An error occured. Please contact administrator for assistance';
1266
  }
1267
+ rzpLogInfo("returning $getErrorMessage");
1268
  return $message;
1269
  }
1270
 
1279
 
1280
  $orderId = $order->get_order_number();
1281
 
1282
+ rzpLogInfo("updateOrder orderId: $orderId , errorMessage: $errorMessage, razorpayPaymentId: $razorpayPaymentId , success: $success");
1283
+
1284
  if (($success === true) and ($order->needs_payment() === true))
1285
  {
1286
+ try
1287
+ {
1288
+ $wcOrderId = $order->get_id();
1289
+
1290
+ $is1ccOrder = get_post_meta( $wcOrderId, 'is_magic_checkout_order', true );
1291
+
1292
+ if (is1ccEnabled() && !empty($is1ccOrder) && $is1ccOrder == 'yes')
1293
+ {
1294
+ //To verify whether the 1cc update order function already under execution or not
1295
+ if(get_transient('wc_order_under_process_'.$wcOrderId) === false)
1296
+ {
1297
+ $this->update1ccOrderWC($order, $wcOrderId, $razorpayPaymentId);
1298
+ }
1299
+
1300
+ }
1301
+ } catch (Exception $e) {
1302
+ $message = $e->getMessage();
1303
+ rzpLogError("Failed to update 1cc flow with error : $message");
1304
+ }
1305
+
1306
+ $payment_method=$order->get_payment_method();
1307
+
1308
+ // Need to set the status manually to processing incase of COD payment method.
1309
+ if ($payment_method == "cod")
1310
+ {
1311
+ $order->update_status( 'processing' );
1312
+ }
1313
+ else
1314
+ {
1315
+ $order->payment_complete($razorpayPaymentId);
1316
+ }
1317
+
1318
  $order->add_order_note("Razorpay payment successful <br/>Razorpay Id: $razorpayPaymentId");
1319
 
1320
  if($this->getSetting('route_enable') == 'yes')
1353
  if ($webhook === false)
1354
  {
1355
  $this->add_notice($this->msg['message'], $this->msg['class']);
1356
+
1357
+ rzpLogInfo("Woocommerce orderId: $orderId processed through callback");
1358
+ }
1359
+ else
1360
+ {
1361
+ rzpLogInfo("Woocommerce orderId: $orderId processed through webhook");
1362
  }
1363
  }
1364
 
1365
+ public function update1ccOrderWC(& $order, $wcOrderId, $razorpayPaymentId)
1366
+ {
1367
+ $logObj = array();
1368
+ rzpLogInfo("update1ccOrderWC wcOrderId: $wcOrderId, razorpayPaymentId: $razorpayPaymentId");
1369
+
1370
+ //To avoid the symultanious update from callback and webhook
1371
+ set_transient('wc_order_under_process_'.$wcOrderId, true, 300);
1372
+
1373
+ $api = $this->getRazorpayApiInstance();
1374
+ $sessionKey = $this->getOrderSessionKey($wcOrderId);
1375
+ $razorpayOrderId = get_transient($sessionKey);
1376
+ $razorpayData = $api->order->fetch($razorpayOrderId);
1377
+
1378
+ $this->updateOrderAddress($razorpayData, $order);
1379
+
1380
+
1381
+ if (empty($razorpayData['promotions'][0]) === false)
1382
+ {
1383
+ $couponKey = $razorpayData['promotions'][0]['code'];
1384
+ }
1385
+
1386
+ //Apply coupon to woo-order
1387
+ if (empty($couponKey) === false)
1388
+ {
1389
+ //TODO: Convert all razorpay amount in paise to rupees
1390
+ $discount_total = $razorpayData['promotions'][0]['value']/100;
1391
+
1392
+ //TODO: Verify source code implementation
1393
+ // Loop through products and apply the coupon discount
1394
+ foreach($order->get_items() as $order_item)
1395
+ {
1396
+ $total = $order_item->get_total();
1397
+ $order_item->set_subtotal($total);
1398
+ $order_item->set_total($total - $discount_total);
1399
+ $order_item->save();
1400
+ }
1401
+ // TODO: Test if individual use coupon fails by hardcoding here
1402
+ $isApplied = $order->apply_coupon($couponKey);
1403
+ $order->save();
1404
+ }
1405
+
1406
+ //Apply shipping charges to woo-order
1407
+ if(isset($razorpayData['shipping_fee']) === true)
1408
+ {
1409
+ // Get a new instance of the WC_Order_Item_Shipping Object
1410
+ $item = new WC_Order_Item_Shipping();
1411
+
1412
+ // if shipping charges zero
1413
+ if($razorpayData['shipping_fee'] == 0)
1414
+ {
1415
+ $item->set_method_title( 'Free Shipping' );
1416
+ }
1417
+ else
1418
+ {
1419
+ $isStoreShippingEnabled = "";
1420
+ $shippingData = get_post_meta( $wcOrderId, '1cc_shippinginfo', true );
1421
+
1422
+ if (class_exists('WCFMmp'))
1423
+ {
1424
+ $shippingOptions = get_option( 'wcfm_shipping_options', array());
1425
+ // By default store shipping should be consider enable
1426
+ $isStoreShippingEnabled = isset( $shippingOptions['enable_store_shipping'] ) ? $shippingOptions['enable_store_shipping'] : 'yes';
1427
+ }
1428
+
1429
+ if ($isStoreShippingEnabled == 'yes')
1430
+ {
1431
+ foreach ($shippingData as $key => $value)
1432
+ {
1433
+ $item = new WC_Order_Item_Shipping();
1434
+ //$item->set_method_id($test[$key]['rate_id']);
1435
+ $item->set_method_title($shippingData[$key]['name']);
1436
+ $item->set_total($shippingData[$key]['price']/100 );
1437
+ $order->add_item($item);
1438
+ $item->save();
1439
+ $itemId = $item->get_id();
1440
+
1441
+ $wcfmCommissionOptions = get_option( 'wcfm_commission_options', array() );
1442
+
1443
+ $vendorGetShipping = isset( $wcfmCommissionOptions['get_shipping'] ) ? $wcfmCommissionOptions['get_shipping'] : 'yes';
1444
+
1445
+ if (isset($shippingData[$key]['vendor_id']) && $vendorGetShipping == 'yes')
1446
+ {
1447
+ $itemData = array(
1448
+ 'method_id' => $shippingData[$key]['method_id'],
1449
+ 'instance_id' => $shippingData[$key]['instance_id'],
1450
+ 'vendor_id' => $shippingData[$key]['vendor_id'],
1451
+ 'Items' => $shippingData[$key]['meta_data'][0]['value']
1452
+ );
1453
+ updateVendorDetails($shippingData[$key]['price']/100, $shippingData[$key]['vendor_id'], $wcOrderId);
1454
+
1455
+ foreach ($itemData as $itemkey => $itemval)
1456
+ {
1457
+ wc_update_order_item_meta( $itemId, $itemkey, $itemval);
1458
+ }
1459
+ }
1460
+
1461
+ }
1462
+ }
1463
+ else
1464
+ {
1465
+ $item = new WC_Order_Item_Shipping();
1466
+
1467
+ // if shipping charges zero
1468
+ if ($razorpayData['shipping_fee'] == 0)
1469
+ {
1470
+ $item->set_method_title( 'Free Shipping' );
1471
+ }
1472
+ else
1473
+ {
1474
+ $item->set_method_title($shippingData[0]['name']);
1475
+ }
1476
+
1477
+ // set an non existing Shipping method rate ID will mark the order as completed instead of processing status
1478
+ // $item->set_method_id( "flat_rate:1" );
1479
+ $item->set_total( $razorpayData['shipping_fee']/100 );
1480
+
1481
+ $order->add_item( $item );
1482
+
1483
+ $item->save();
1484
+ }
1485
+ // Calculate totals and save
1486
+ $order->calculate_totals();
1487
+
1488
+ }
1489
+ }
1490
+
1491
+ // set default payment method
1492
+ $payment_method = $this->id;
1493
+
1494
+ // To verify the payment method for particular payment id.
1495
+ $razorpayPyamentData = $api->payment->fetch($razorpayPaymentId);
1496
+
1497
+ $paymentDoneBy = $razorpayPyamentData['method'];
1498
+
1499
+ if (($paymentDoneBy === 'cod') && isset($razorpayData['cod_fee']) == true)
1500
+ {
1501
+ $codKey = $razorpayData['cod_fee']/100;
1502
+ $payment_method = 'cod';
1503
+ }
1504
+
1505
+ //update payment method title
1506
+ $order->set_payment_method($payment_method);
1507
+ $order->save();
1508
+
1509
+ if (($paymentDoneBy === 'cod') && isset($razorpayData['cod_fee']) == true)
1510
+ {
1511
+ // Get a new instance of the WC_Order_Item_Fee Object
1512
+ $itemFee = new WC_Order_Item_Fee();
1513
+
1514
+ $itemFee->set_name('COD Fee'); // Generic fee name
1515
+ $itemFee->set_amount($codKey); // Fee amount
1516
+ // $itemFee->set_tax_class(''); // default for ''
1517
+ $itemFee->set_tax_status( 'none' ); // If we don't set tax status then it will consider by dafalut tax class.
1518
+ $itemFee->set_total($codKey); // Fee amount
1519
+
1520
+ // Calculating Fee taxes
1521
+ // $itemFee->calculate_taxes( $calculateTaxFor );
1522
+
1523
+ // Add Fee item to the order
1524
+ $order->add_item($itemFee);
1525
+ $order->calculate_totals();
1526
+ $order->save();
1527
+ }
1528
+
1529
+ $note = __('Order placed through Razorpay Magic Checkout');
1530
+ $order->add_order_note( $note );
1531
+ }
1532
+
1533
+ //To update customer address info to wc order.
1534
+ public function updateOrderAddress($razorpayData, $order)
1535
+ {
1536
+ if (isset($razorpayData['customer_details']['shipping_address']))
1537
+ {
1538
+ $shippingAddressKey = $razorpayData['customer_details']['shipping_address'];
1539
+
1540
+ $shippingAddress = [];
1541
+
1542
+ $shippingAddress['first_name'] = $shippingAddressKey['name'];
1543
+ $shippingAddress['address_1'] = $shippingAddressKey['line1'];
1544
+ $shippingAddress['address_2'] = $shippingAddressKey['line2'];
1545
+ $shippingAddress['city'] = $shippingAddressKey['city'];
1546
+ $shippingAddress['country'] = strtoupper($shippingAddressKey['country']);
1547
+ $shippingAddress['postcode'] = $shippingAddressKey['zipcode'];
1548
+ $shippingAddress['email'] = $razorpayData['customer_details']['email'];
1549
+ $shippingAddress['phone'] = $shippingAddressKey['contact'];
1550
+
1551
+ $order->set_address( $shippingAddress, 'shipping' );
1552
+
1553
+ $shippingState = strtoupper($shippingAddressKey['state']);
1554
+ $shippingStateName = str_replace(" ", '', $shippingState);
1555
+ $shippingStateCode = getWcStateCodeFromName($shippingStateName);
1556
+ $order->set_shipping_state($shippingStateCode);
1557
+
1558
+ $this->updateUserAddressInfo('shipping_', $shippingAddress, $shippingStateCode, $order);
1559
+
1560
+ if (empty($razorpayData['customer_details']['billing_address']) == false)
1561
+ {
1562
+ $billingAddress['first_name'] = $razorpayData['customer_details']['billing_address']['name'];
1563
+ $billingAddress['address_1'] = $razorpayData['customer_details']['billing_address']['line1'];
1564
+ $billingAddress['address_2'] = $razorpayData['customer_details']['billing_address']['line2'];
1565
+ $billingAddress['city'] = $razorpayData['customer_details']['billing_address']['city'];
1566
+ $billingAddress['country'] = strtoupper($razorpayData['customer_details']['billing_address']['country']);
1567
+ $billingAddress['postcode'] = $razorpayData['customer_details']['billing_address']['zipcode'];
1568
+ $billingAddress['email'] = $razorpayData['customer_details']['email'];
1569
+ $billingAddress['phone'] = $razorpayData['customer_details']['billing_address']['contact'];
1570
+ $order->set_address( $billingAddress, 'billing' );
1571
+
1572
+ $billingState = strtoupper($razorpayData['customer_details']['billing_address']['state']);
1573
+ $billingStateName = str_replace(" ", '', $billingState);
1574
+ $billingStateCode = getWcStateCodeFromName($billingStateName);
1575
+ $order->set_billing_state($billingStateCode);
1576
+
1577
+ $this->updateUserAddressInfo('billing_', $billingAddress, $billingStateCode, $order);
1578
+ }
1579
+ else
1580
+ {
1581
+ $order->set_address( $shippingAddress, 'billing' );
1582
+ $order->set_billing_state($shippingStateCode);
1583
+
1584
+ $this->updateUserAddressInfo('billing_', $shippingAddress, $shippingStateCode, $order);
1585
+ }
1586
+
1587
+ $order->save();
1588
+ }
1589
+ }
1590
+
1591
+ /**
1592
+ * Retrieve a Shipping Zone by it's ID.
1593
+ *
1594
+ * @param int $zone_id Shipping Zone ID.
1595
+ * @return WC_Shipping_Zone|WP_Error
1596
+ */
1597
+ // TODO: can't we directly return the statement?
1598
+ protected function getShippingZone($zoneId)
1599
+ {
1600
+ $zone = WC_Shipping_Zones::get_zone_by('zone_id', $zoneId);
1601
+
1602
+ return $zone;
1603
+ }
1604
+
1605
+
1606
+
1607
+
1608
+ // Update user billing and shipping information
1609
+ protected function updateUserAddressInfo($addressKeyPrefix, $addressValue, $stateValue, $order)
1610
+ {
1611
+ foreach ($addressValue as $key => $value)
1612
+ {
1613
+ $metaKey = $addressKeyPrefix;
1614
+ $metaKey .= $key;
1615
+
1616
+ update_user_meta($order->get_user_id(), $metaKey, $value);
1617
+ }
1618
+
1619
+ update_user_meta($order->get_user_id(), $addressKeyPrefix . 'state', $stateValue);
1620
+ }
1621
+
1622
  protected function handleErrorCase(& $order)
1623
  {
1624
  $orderId = $order->get_order_number();
1625
+ rzpLogInfo('handleErrorCase');
1626
  $this->msg['class'] = 'error';
1627
  $this->msg['message'] = $this->getErrorMessage($orderId);
1628
  }
1684
 
1685
  }
1686
 
1687
+ //update vendor data into wp_wcfm_marketplace_orders
1688
+ function updateVendorDetails($shippingFee, $vendorId, $orderId)
1689
+ {
1690
+ global $woocommerce;
1691
+ global $wpdb;
1692
+ $commission = $wpdb->get_results(
1693
+ $wpdb->prepare(
1694
+ 'SELECT * FROM `' . $wpdb->prefix . 'wcfm_marketplace_orders` WHERE vendor_id = %d AND order_id = %d',
1695
+ $vendorId,
1696
+ $orderId
1697
+ )
1698
+ );
1699
+
1700
+ if (count($commission) > 0)
1701
+ {
1702
+ $totalComm = $commission[0]->total_commission+$shippingFee;
1703
+ $wpdb->query(
1704
+ $wpdb->prepare(
1705
+ 'UPDATE `' . $wpdb->prefix . 'wcfm_marketplace_orders` SET shipping = %d, total_commission = %d WHERE vendor_id = %d AND order_id = %d',
1706
+ $shippingFee,
1707
+ $totalComm,
1708
+ $vendorId,
1709
+ $orderId
1710
+ )
1711
+ );
1712
+ }
1713
+ }
1714
+
1715
  /**
1716
  * Add the Gateway to WooCommerce
1717
  **/
1721
  return $methods;
1722
  }
1723
 
1724
+ add_filter('woocommerce_payment_gateways', 'woocommerce_add_razorpay_gateway');
1725
 
1726
  /**
1727
  * Creating the settings link from the plugins page
1749
 
1750
  $rzpWebhook->process();
1751
  }
1752
+
1753
+ define('RZP_PATH', plugin_dir_path( __FILE__ ));
1754
+ define('RZP_CHECKOUTJS_URL', 'https://checkout.razorpay.com/v1/checkout.js');
1755
+ define('RZP_1CC_CSS_SCRIPT', 'RZP_1CC_CSS_SCRIPT');
1756
+
1757
+
1758
+ function enqueueScriptsFor1cc()
1759
+ {
1760
+ $siteurl = get_option('siteurl');
1761
+
1762
+ $domain = parse_url($siteurl, PHP_URL_HOST);
1763
+ $domain_ip = gethostbyname($domain);
1764
+
1765
+ //Consider https if site url is not localhost server.
1766
+ if (filter_var($domain_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE))
1767
+ {
1768
+ $siteurl = str_replace('http://', 'https://', $siteurl);
1769
+ }
1770
+
1771
+ wp_register_script('1cc_razorpay_checkout', RZP_CHECKOUTJS_URL, null, null);
1772
+ wp_enqueue_script('1cc_razorpay_checkout');
1773
+
1774
+ wp_register_style(RZP_1CC_CSS_SCRIPT, plugin_dir_url(__FILE__) . 'public/css/1cc-product-checkout.css', null, null);
1775
+ wp_enqueue_style(RZP_1CC_CSS_SCRIPT);
1776
+
1777
+ wp_register_script('btn_1cc_checkout', plugin_dir_url(__FILE__) . 'btn-1cc-checkout.js', null, null);
1778
+ wp_localize_script('btn_1cc_checkout', 'rzp1ccCheckoutData', array(
1779
+ 'nonce' => wp_create_nonce("wp_rest"),
1780
+ 'siteurl' => $siteurl,
1781
+ 'blogname' => get_bloginfo('name'),
1782
+ ) );
1783
+ wp_enqueue_script('btn_1cc_checkout');
1784
+ }
1785
+
1786
+ add_action('woocommerce_cart_updated', 'enqueueScriptsFor1cc', 10);
1787
+
1788
+ //To add 1CC button on cart page.
1789
+ add_action( 'woocommerce_proceed_to_checkout', 'addCheckoutButton');
1790
+
1791
+ function addCheckoutButton()
1792
+ {
1793
+ add_action('wp_enqueue_scripts', 'enqueueScriptsFor1cc', 0);
1794
+
1795
+ if (isRazorpayPluginEnabled() && is1ccEnabled() )
1796
+ {
1797
+ if (isTestModeEnabled()) {
1798
+ $current_user = wp_get_current_user();
1799
+ if ($current_user->has_cap( 'administrator' ) || preg_match( '/@razorpay.com$/i', $current_user->user_email )) {
1800
+ $tempTest = RZP_PATH . 'templates/rzp-cart-checkout-btn.php';
1801
+ load_template( $tempTest, false, array() );
1802
+ }
1803
+ } else {
1804
+ $tempTest = RZP_PATH . 'templates/rzp-cart-checkout-btn.php';
1805
+ load_template( $tempTest, false, array() );
1806
+ }
1807
+ }
1808
+ else
1809
+ {
1810
+ return;
1811
+ }
1812
+ }
1813
+
1814
+ //To add 1CC Mini cart checkout button
1815
+ if(isRazorpayPluginEnabled() && is1ccEnabled() && isMiniCartCheckoutEnabled())
1816
+ {
1817
+ add_action( 'woocommerce_widget_shopping_cart_buttons', function()
1818
+ {
1819
+ // Removing Buttons
1820
+ remove_action( 'woocommerce_widget_shopping_cart_buttons', 'woocommerce_widget_shopping_cart_proceed_to_checkout', 20 );
1821
+
1822
+ add_action('woocommerce_cart_updated', 'enqueueScriptsFor1cc', 10);
1823
+
1824
+ add_action( 'woocommerce_widget_shopping_cart_buttons', 'addMiniCheckoutButton', 20 );
1825
+ }, 1 );
1826
+ }
1827
+
1828
+ function addMiniCheckoutButton()
1829
+ {
1830
+ add_action('wp_enqueue_scripts', 'enqueueScriptsFor1cc', 0);
1831
+
1832
+ if (isTestModeEnabled()) {
1833
+ $current_user = wp_get_current_user();
1834
+ if ($current_user->has_cap( 'administrator' ) || preg_match( '/@razorpay.com$/i', $current_user->user_email )) {
1835
+ $tempTest = RZP_PATH . 'templates/rzp-mini-checkout-btn.php';
1836
+ load_template( $tempTest, false, array() );
1837
+ }
1838
+ } else {
1839
+ $tempTest = RZP_PATH . 'templates/rzp-mini-checkout-btn.php';
1840
+ load_template( $tempTest, false, array() );
1841
+ }
1842
+
1843
+ }
1844
+
1845
+ //To add 1CC button on product page.
1846
+ if(isRazorpayPluginEnabled() && is1ccEnabled() && isPdpCheckoutEnabled())
1847
+ {
1848
+ add_action( 'woocommerce_after_add_to_cart_button', 'addPdpCheckoutButton');
1849
+ }
1850
+
1851
+ function addPdpCheckoutButton()
1852
+ {
1853
+ add_action('wp_enqueue_scripts', 'enqueueScriptsFor1cc', 0);
1854
+
1855
+ if (isTestModeEnabled()) {
1856
+ $current_user = wp_get_current_user();
1857
+ if ($current_user->has_cap( 'administrator' ) || preg_match( '/@razorpay.com$/i', $current_user->user_email )) {
1858
+ $tempTest = RZP_PATH . 'templates/rzp-pdp-checkout-btn.php';
1859
+ load_template( $tempTest, false, array() );
1860
+ }
1861
+ } else {
1862
+ $tempTest = RZP_PATH . 'templates/rzp-pdp-checkout-btn.php';
1863
+ load_template( $tempTest, false, array() );
1864
+ }
1865
+ }
1866
+
1867
+ // for admin panel custom alerts
1868
+ function addAdminSettingsAlertScript()
1869
+ {
1870
+ if (isRazorpayPluginEnabled()) {
1871
+ wp_enqueue_script('rzpAdminSettingsScript', plugin_dir_url(__FILE__) .'public/js/admin-rzp-settings.js');
1872
+ }
1873
+ }
1874
+
1875
+ add_action('admin_enqueue_scripts', 'addAdminSettingsAlertScript');
1876
+
1877
+ function disable_coupon_field_on_cart($enabled)
1878
+ {
1879
+ if (isTestModeEnabled()) {
1880
+ $current_user = wp_get_current_user();
1881
+ if ($current_user->has_cap( 'administrator' ) || preg_match( '/@razorpay.com$/i', $current_user->user_email )) {
1882
+ if (is_cart() || is_checkout()) {
1883
+ $enabled = false;
1884
+ }
1885
+ }
1886
+ } else {
1887
+ if (is_cart() || is_checkout()) {
1888
+ $enabled = false;
1889
+ }
1890
+ }
1891
+ return $enabled;
1892
+ }
1893
+
1894
+ if(is1ccEnabled())
1895
+ {
1896
+ add_filter( 'woocommerce_coupons_enabled', 'disable_coupon_field_on_cart' );
1897
+ }
1898
+
1899
+ add_filter('woocommerce_order_needs_shipping_address', '__return_true');