Version Description
- Fix - Manual orders return an error for guest users when paying with PayPal Card Processing #530
- Fix - "No PayPal order found in the current WooCommerce session" error for guests on Pay for Order page #605
- Fix - Error on order discount by third-party plugins #548
- Fix - Empty payer data may cause CITY_REQUIRED error for certain checkout countries #632
- Fix - Mini Cart smart buttons visible after adding subscription product to cart from "shop" page while Vaulting is disabled #624
- Fix - Smart buttons not loading when free product is in cart but shipping costs are available #606
- Fix - Smart button & Pay Later messaging disappear on the cart page after changing shipping method #288
- Fix - Disabling PayPal Checkout on the checkout page also removes the button from the Cart and Product Pages #577
- Fix - Partial refunds via PayPal are created twice/double in WooCommerce order #522
- Fix - Emoji in product description causing INVALID_STRING_LENGTH error #491
- Enhancement - Vaulting & Pay Later UI/UX #174
- Enhancement - Redirect after updating settings for DCC sends you to PPCP settings screen #392
- Enhancement - Add Fraud Processor Response as an order note #616
- Enhancement - Add the Paypal Fee to the Meta Custom Field for export purposes #591
Download this release
Release Info
Developer | automattic |
Plugin | WooCommerce PayPal Payments |
Version | 1.8.1 |
Comparing to | |
See all releases |
Code changes from version 1.8.0 to 1.8.1
- changelog.txt +16 -0
- modules/ppcp-api-client/services.php +6 -1
- modules/ppcp-api-client/src/Endpoint/PaymentsEndpoint.php +6 -4
- modules/ppcp-api-client/src/Entity/Capture.php +23 -1
- modules/ppcp-api-client/src/Entity/FraudProcessorResponse.php +74 -0
- modules/ppcp-api-client/src/Entity/PurchaseUnit.php +9 -0
- modules/ppcp-api-client/src/Exception/PayPalApiException.php +9 -0
- modules/ppcp-api-client/src/Factory/AmountFactory.php +47 -9
- modules/ppcp-api-client/src/Factory/CaptureFactory.php +17 -3
- modules/ppcp-api-client/src/Factory/FraudProcessorResponseFactory.php +33 -0
- modules/ppcp-api-client/src/Factory/ItemFactory.php +1 -1
- modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php +12 -2
- modules/ppcp-button/assets/js/button.js +1 -1
- modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js +3 -7
- modules/ppcp-button/resources/js/modules/Renderer/MessageRenderer.js +9 -1
- modules/ppcp-button/src/Assets/SmartButton.php +75 -43
- modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php +48 -8
- modules/ppcp-vaulting/src/CustomerApprovalListener.php +2 -1
- modules/ppcp-vaulting/src/PaymentTokenChecker.php +1 -1
- modules/ppcp-wc-gateway/assets/js/gateway-settings.js +1 -1
- modules/ppcp-wc-gateway/resources/js/gateway-settings.js +44 -9
- modules/ppcp-wc-gateway/services.php +46 -23
- modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php +4 -30
- modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php +1 -1
- modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php +7 -6
- modules/ppcp-wc-gateway/src/Processor/OrderMetaTrait.php +1 -1
- modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php +2 -1
- modules/ppcp-wc-gateway/src/Processor/RefundMetaTrait.php +47 -0
- modules/ppcp-wc-gateway/src/Processor/RefundProcessor.php +7 -3
- modules/ppcp-wc-gateway/src/Settings/SettingsListener.php +1 -14
- modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php +0 -20
- modules/ppcp-wc-gateway/src/WCGatewayModule.php +43 -2
- modules/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php +26 -15
- psalm.xml.dist +6 -0
- readme.txt +21 -5
- vendor/autoload.php +1 -1
- vendor/composer/autoload_real.php +7 -7
- vendor/composer/autoload_static.php +4 -4
- woocommerce-paypal-payments.php +2 -2
changelog.txt
CHANGED
@@ -1,5 +1,21 @@
|
|
1 |
*** Changelog ***
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
= 1.8.0 - 2022-05-03 =
|
4 |
* Add - Allow free trial subscriptions #580
|
5 |
* Fix - The Card Processing does not appear as an available payment method when manually creating an order #562
|
1 |
*** Changelog ***
|
2 |
|
3 |
+
= 1.8.1 - 2022-05-31 =
|
4 |
+
* Fix - Manual orders return an error for guest users when paying with PayPal Card Processing #530
|
5 |
+
* Fix - "No PayPal order found in the current WooCommerce session" error for guests on Pay for Order page #605
|
6 |
+
* Fix - Error on order discount by third-party plugins #548
|
7 |
+
* Fix - Empty payer data may cause CITY_REQUIRED error for certain checkout countries #632
|
8 |
+
* Fix - Mini Cart smart buttons visible after adding subscription product to cart from "shop" page while Vaulting is disabled #624
|
9 |
+
* Fix - Smart buttons not loading when free product is in cart but shipping costs are available #606
|
10 |
+
* Fix - Smart button & Pay Later messaging disappear on the cart page after changing shipping method #288
|
11 |
+
* Fix - Disabling PayPal Checkout on the checkout page also removes the button from the Cart and Product Pages #577
|
12 |
+
* Fix - Partial refunds via PayPal are created twice/double in WooCommerce order #522
|
13 |
+
* Fix - Emoji in product description causing INVALID_STRING_LENGTH error #491
|
14 |
+
* Enhancement - Vaulting & Pay Later UI/UX #174
|
15 |
+
* Enhancement - Redirect after updating settings for DCC sends you to PPCP settings screen #392
|
16 |
+
* Enhancement - Add Fraud Processor Response as an order note #616
|
17 |
+
* Enhancement - Add the Paypal Fee to the Meta Custom Field for export purposes #591
|
18 |
+
|
19 |
= 1.8.0 - 2022-05-03 =
|
20 |
* Add - Allow free trial subscriptions #580
|
21 |
* Fix - The Card Processing does not appear as an available payment method when manually creating an order #562
|
modules/ppcp-api-client/services.php
CHANGED
@@ -27,6 +27,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\ApplicationContextFactory;
|
|
27 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
|
28 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\CaptureFactory;
|
29 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\ExchangeRateFactory;
|
|
|
30 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\ItemFactory;
|
31 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\MoneyFactory;
|
32 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
@@ -257,7 +258,8 @@ return array(
|
|
257 |
$amount_factory = $container->get( 'api.factory.amount' );
|
258 |
return new CaptureFactory(
|
259 |
$amount_factory,
|
260 |
-
$container->get( 'api.factory.seller-receivable-breakdown' )
|
|
|
261 |
);
|
262 |
},
|
263 |
'api.factory.purchase-unit' => static function ( ContainerInterface $container ): PurchaseUnitFactory {
|
@@ -354,6 +356,9 @@ return array(
|
|
354 |
$container->get( 'api.factory.platform-fee' )
|
355 |
);
|
356 |
},
|
|
|
|
|
|
|
357 |
'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies {
|
358 |
return new DccApplies(
|
359 |
$container->get( 'api.dcc-supported-country-currency-matrix' ),
|
27 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\AuthorizationFactory;
|
28 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\CaptureFactory;
|
29 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\ExchangeRateFactory;
|
30 |
+
use WooCommerce\PayPalCommerce\ApiClient\Factory\FraudProcessorResponseFactory;
|
31 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\ItemFactory;
|
32 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\MoneyFactory;
|
33 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
258 |
$amount_factory = $container->get( 'api.factory.amount' );
|
259 |
return new CaptureFactory(
|
260 |
$amount_factory,
|
261 |
+
$container->get( 'api.factory.seller-receivable-breakdown' ),
|
262 |
+
$container->get( 'api.factory.fraud-processor-response' )
|
263 |
);
|
264 |
},
|
265 |
'api.factory.purchase-unit' => static function ( ContainerInterface $container ): PurchaseUnitFactory {
|
356 |
$container->get( 'api.factory.platform-fee' )
|
357 |
);
|
358 |
},
|
359 |
+
'api.factory.fraud-processor-response' => static function ( ContainerInterface $container ): FraudProcessorResponseFactory {
|
360 |
+
return new FraudProcessorResponseFactory();
|
361 |
+
},
|
362 |
'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies {
|
363 |
return new DccApplies(
|
364 |
$container->get( 'api.dcc-supported-country-currency-matrix' ),
|
modules/ppcp-api-client/src/Endpoint/PaymentsEndpoint.php
CHANGED
@@ -198,11 +198,11 @@ class PaymentsEndpoint {
|
|
198 |
*
|
199 |
* @param Refund $refund The refund to be processed.
|
200 |
*
|
201 |
-
* @return
|
202 |
* @throws RuntimeException If the request fails.
|
203 |
* @throws PayPalApiException If the request fails.
|
204 |
*/
|
205 |
-
public function refund( Refund $refund ) :
|
206 |
$bearer = $this->bearer->bearer();
|
207 |
$url = trailingslashit( $this->host ) . 'v2/payments/captures/' . $refund->for_capture()->id() . '/refund';
|
208 |
$args = array(
|
@@ -216,19 +216,21 @@ class PaymentsEndpoint {
|
|
216 |
);
|
217 |
|
218 |
$response = $this->request( $url, $args );
|
219 |
-
$json = json_decode( $response['body'] );
|
220 |
|
221 |
if ( is_wp_error( $response ) ) {
|
222 |
throw new RuntimeException( 'Could not refund payment.' );
|
223 |
}
|
224 |
|
225 |
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
226 |
-
|
|
|
227 |
throw new PayPalApiException(
|
228 |
$json,
|
229 |
$status_code
|
230 |
);
|
231 |
}
|
|
|
|
|
232 |
}
|
233 |
|
234 |
/**
|
198 |
*
|
199 |
* @param Refund $refund The refund to be processed.
|
200 |
*
|
201 |
+
* @return string Refund ID.
|
202 |
* @throws RuntimeException If the request fails.
|
203 |
* @throws PayPalApiException If the request fails.
|
204 |
*/
|
205 |
+
public function refund( Refund $refund ) : string {
|
206 |
$bearer = $this->bearer->bearer();
|
207 |
$url = trailingslashit( $this->host ) . 'v2/payments/captures/' . $refund->for_capture()->id() . '/refund';
|
208 |
$args = array(
|
216 |
);
|
217 |
|
218 |
$response = $this->request( $url, $args );
|
|
|
219 |
|
220 |
if ( is_wp_error( $response ) ) {
|
221 |
throw new RuntimeException( 'Could not refund payment.' );
|
222 |
}
|
223 |
|
224 |
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
225 |
+
$json = json_decode( $response['body'] );
|
226 |
+
if ( 201 !== $status_code || ! is_object( $json ) ) {
|
227 |
throw new PayPalApiException(
|
228 |
$json,
|
229 |
$status_code
|
230 |
);
|
231 |
}
|
232 |
+
|
233 |
+
return $json->id;
|
234 |
}
|
235 |
|
236 |
/**
|
modules/ppcp-api-client/src/Entity/Capture.php
CHANGED
@@ -58,6 +58,13 @@ class Capture {
|
|
58 |
*/
|
59 |
private $seller_receivable_breakdown;
|
60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
/**
|
62 |
* The invoice id.
|
63 |
*
|
@@ -83,6 +90,7 @@ class Capture {
|
|
83 |
* @param string $invoice_id The invoice id.
|
84 |
* @param string $custom_id The custom id.
|
85 |
* @param SellerReceivableBreakdown|null $seller_receivable_breakdown The detailed breakdown of the capture activity (fees, ...).
|
|
|
86 |
*/
|
87 |
public function __construct(
|
88 |
string $id,
|
@@ -92,7 +100,8 @@ class Capture {
|
|
92 |
string $seller_protection,
|
93 |
string $invoice_id,
|
94 |
string $custom_id,
|
95 |
-
?SellerReceivableBreakdown $seller_receivable_breakdown
|
|
|
96 |
) {
|
97 |
|
98 |
$this->id = $id;
|
@@ -103,6 +112,7 @@ class Capture {
|
|
103 |
$this->invoice_id = $invoice_id;
|
104 |
$this->custom_id = $custom_id;
|
105 |
$this->seller_receivable_breakdown = $seller_receivable_breakdown;
|
|
|
106 |
}
|
107 |
|
108 |
/**
|
@@ -177,6 +187,15 @@ class Capture {
|
|
177 |
return $this->seller_receivable_breakdown;
|
178 |
}
|
179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
/**
|
181 |
* Returns the entity as array.
|
182 |
*
|
@@ -199,6 +218,9 @@ class Capture {
|
|
199 |
if ( $this->seller_receivable_breakdown ) {
|
200 |
$data['seller_receivable_breakdown'] = $this->seller_receivable_breakdown->to_array();
|
201 |
}
|
|
|
|
|
|
|
202 |
return $data;
|
203 |
}
|
204 |
}
|
58 |
*/
|
59 |
private $seller_receivable_breakdown;
|
60 |
|
61 |
+
/**
|
62 |
+
* The fraud processor response (AVS, CVV ...).
|
63 |
+
*
|
64 |
+
* @var FraudProcessorResponse|null
|
65 |
+
*/
|
66 |
+
protected $fraud_processor_response;
|
67 |
+
|
68 |
/**
|
69 |
* The invoice id.
|
70 |
*
|
90 |
* @param string $invoice_id The invoice id.
|
91 |
* @param string $custom_id The custom id.
|
92 |
* @param SellerReceivableBreakdown|null $seller_receivable_breakdown The detailed breakdown of the capture activity (fees, ...).
|
93 |
+
* @param FraudProcessorResponse|null $fraud_processor_response The fraud processor response (AVS, CVV ...).
|
94 |
*/
|
95 |
public function __construct(
|
96 |
string $id,
|
100 |
string $seller_protection,
|
101 |
string $invoice_id,
|
102 |
string $custom_id,
|
103 |
+
?SellerReceivableBreakdown $seller_receivable_breakdown,
|
104 |
+
?FraudProcessorResponse $fraud_processor_response
|
105 |
) {
|
106 |
|
107 |
$this->id = $id;
|
112 |
$this->invoice_id = $invoice_id;
|
113 |
$this->custom_id = $custom_id;
|
114 |
$this->seller_receivable_breakdown = $seller_receivable_breakdown;
|
115 |
+
$this->fraud_processor_response = $fraud_processor_response;
|
116 |
}
|
117 |
|
118 |
/**
|
187 |
return $this->seller_receivable_breakdown;
|
188 |
}
|
189 |
|
190 |
+
/**
|
191 |
+
* Returns the fraud processor response (AVS, CVV ...).
|
192 |
+
*
|
193 |
+
* @return FraudProcessorResponse|null
|
194 |
+
*/
|
195 |
+
public function fraud_processor_response() : ?FraudProcessorResponse {
|
196 |
+
return $this->fraud_processor_response;
|
197 |
+
}
|
198 |
+
|
199 |
/**
|
200 |
* Returns the entity as array.
|
201 |
*
|
218 |
if ( $this->seller_receivable_breakdown ) {
|
219 |
$data['seller_receivable_breakdown'] = $this->seller_receivable_breakdown->to_array();
|
220 |
}
|
221 |
+
if ( $this->fraud_processor_response ) {
|
222 |
+
$data['fraud_processor_response'] = $this->fraud_processor_response->to_array();
|
223 |
+
}
|
224 |
return $data;
|
225 |
}
|
226 |
}
|
modules/ppcp-api-client/src/Entity/FraudProcessorResponse.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The FraudProcessorResponse object.
|
4 |
+
*
|
5 |
+
* @package WooCommerce\PayPalCommerce\ApiClient\Entity
|
6 |
+
*/
|
7 |
+
|
8 |
+
declare(strict_types=1);
|
9 |
+
|
10 |
+
namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Class FraudProcessorResponse
|
14 |
+
*/
|
15 |
+
class FraudProcessorResponse {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* The AVS response code.
|
19 |
+
*
|
20 |
+
* @var string|null
|
21 |
+
*/
|
22 |
+
protected $avs_code;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* The CVV response code.
|
26 |
+
*
|
27 |
+
* @var string|null
|
28 |
+
*/
|
29 |
+
protected $cvv_code;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* FraudProcessorResponse constructor.
|
33 |
+
*
|
34 |
+
* @param string|null $avs_code The AVS response code.
|
35 |
+
* @param string|null $cvv_code The CVV response code.
|
36 |
+
*/
|
37 |
+
public function __construct( ?string $avs_code, ?string $cvv_code ) {
|
38 |
+
$this->avs_code = $avs_code;
|
39 |
+
$this->cvv_code = $cvv_code;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Returns the AVS response code.
|
44 |
+
*
|
45 |
+
* @return string|null
|
46 |
+
*/
|
47 |
+
public function avs_code(): ?string {
|
48 |
+
return $this->avs_code;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Returns the CVV response code.
|
53 |
+
*
|
54 |
+
* @return string|null
|
55 |
+
*/
|
56 |
+
public function cvv_code(): ?string {
|
57 |
+
return $this->cvv_code;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Returns the object as array.
|
62 |
+
*
|
63 |
+
* @return array
|
64 |
+
*/
|
65 |
+
public function to_array(): array {
|
66 |
+
return array(
|
67 |
+
'avs_code' => $this->avs_code() ?: '',
|
68 |
+
'address_match' => $this->avs_code() === 'M' ? 'Y' : 'N',
|
69 |
+
'postal_match' => $this->avs_code() === 'M' ? 'Y' : 'N',
|
70 |
+
'cvv_match' => $this->cvv_code() === 'M' ? 'Y' : 'N',
|
71 |
+
);
|
72 |
+
}
|
73 |
+
|
74 |
+
}
|
modules/ppcp-api-client/src/Entity/PurchaseUnit.php
CHANGED
@@ -175,6 +175,15 @@ class PurchaseUnit {
|
|
175 |
return $this->shipping;
|
176 |
}
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
/**
|
179 |
* Returns the reference id.
|
180 |
*
|
175 |
return $this->shipping;
|
176 |
}
|
177 |
|
178 |
+
/**
|
179 |
+
* Sets shipping info.
|
180 |
+
*
|
181 |
+
* @param Shipping|null $shipping The value to set.
|
182 |
+
*/
|
183 |
+
public function set_shipping( ?Shipping $shipping ): void {
|
184 |
+
$this->shipping = $shipping;
|
185 |
+
}
|
186 |
+
|
187 |
/**
|
188 |
* Returns the reference id.
|
189 |
*
|
modules/ppcp-api-client/src/Exception/PayPalApiException.php
CHANGED
@@ -119,4 +119,13 @@ class PayPalApiException extends RuntimeException {
|
|
119 |
public function issues(): array {
|
120 |
return $this->response->issues ?? array();
|
121 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
}
|
119 |
public function issues(): array {
|
120 |
return $this->response->issues ?? array();
|
121 |
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* The HTTP status code.
|
125 |
+
*
|
126 |
+
* @return int
|
127 |
+
*/
|
128 |
+
public function status_code(): int {
|
129 |
+
return $this->status_code;
|
130 |
+
}
|
131 |
}
|
modules/ppcp-api-client/src/Factory/AmountFactory.php
CHANGED
@@ -124,10 +124,31 @@ class AmountFactory {
|
|
124 |
$currency = $order->get_currency();
|
125 |
$items = $this->item_factory->from_wc_order( $order );
|
126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
$total_value = (float) $order->get_total();
|
128 |
if ( (
|
129 |
CreditCardGateway::ID === $order->get_payment_method()
|
130 |
-
|| ( PayPalGateway::ID === $order->get_payment_method() && 'card' === $order->get_meta( PayPalGateway::
|
131 |
)
|
132 |
&& $this->is_free_trial_order( $order )
|
133 |
) {
|
@@ -160,14 +181,6 @@ class AmountFactory {
|
|
160 |
$currency
|
161 |
);
|
162 |
|
163 |
-
$discount = null;
|
164 |
-
if ( (float) $order->get_total_discount( false ) ) {
|
165 |
-
$discount = new Money(
|
166 |
-
(float) $order->get_total_discount( false ),
|
167 |
-
$currency
|
168 |
-
);
|
169 |
-
}
|
170 |
-
|
171 |
$breakdown = new AmountBreakdown(
|
172 |
$item_total,
|
173 |
$shipping,
|
@@ -251,4 +264,29 @@ class AmountFactory {
|
|
251 |
|
252 |
return new AmountBreakdown( ...$money );
|
253 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
}
|
124 |
$currency = $order->get_currency();
|
125 |
$items = $this->item_factory->from_wc_order( $order );
|
126 |
|
127 |
+
$discount_value = array_sum(
|
128 |
+
array(
|
129 |
+
(float) $order->get_total_discount( false ), // Only coupons.
|
130 |
+
$this->discounts_from_items( $items ),
|
131 |
+
)
|
132 |
+
);
|
133 |
+
$discount = null;
|
134 |
+
if ( $discount_value ) {
|
135 |
+
$discount = new Money(
|
136 |
+
(float) $discount_value,
|
137 |
+
$currency
|
138 |
+
);
|
139 |
+
}
|
140 |
+
|
141 |
+
$items = array_filter(
|
142 |
+
$items,
|
143 |
+
function ( Item $item ): bool {
|
144 |
+
return $item->unit_amount()->value() > 0;
|
145 |
+
}
|
146 |
+
);
|
147 |
+
|
148 |
$total_value = (float) $order->get_total();
|
149 |
if ( (
|
150 |
CreditCardGateway::ID === $order->get_payment_method()
|
151 |
+
|| ( PayPalGateway::ID === $order->get_payment_method() && 'card' === $order->get_meta( PayPalGateway::ORDER_PAYMENT_SOURCE_META_KEY ) )
|
152 |
)
|
153 |
&& $this->is_free_trial_order( $order )
|
154 |
) {
|
181 |
$currency
|
182 |
);
|
183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
$breakdown = new AmountBreakdown(
|
185 |
$item_total,
|
186 |
$shipping,
|
264 |
|
265 |
return new AmountBreakdown( ...$money );
|
266 |
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Returns the sum of items with negative amount;
|
270 |
+
*
|
271 |
+
* @param Item[] $items PayPal order items.
|
272 |
+
* @return float
|
273 |
+
*/
|
274 |
+
private function discounts_from_items( array $items ): float {
|
275 |
+
$discounts = array_filter(
|
276 |
+
$items,
|
277 |
+
function ( Item $item ): bool {
|
278 |
+
return $item->unit_amount()->value() < 0;
|
279 |
+
}
|
280 |
+
);
|
281 |
+
return abs(
|
282 |
+
array_sum(
|
283 |
+
array_map(
|
284 |
+
function ( Item $item ): float {
|
285 |
+
return (float) $item->quantity() * $item->unit_amount()->value();
|
286 |
+
},
|
287 |
+
$discounts
|
288 |
+
)
|
289 |
+
)
|
290 |
+
);
|
291 |
+
}
|
292 |
}
|
modules/ppcp-api-client/src/Factory/CaptureFactory.php
CHANGED
@@ -32,19 +32,29 @@ class CaptureFactory {
|
|
32 |
*/
|
33 |
private $seller_receivable_breakdown_factory;
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
/**
|
36 |
* CaptureFactory constructor.
|
37 |
*
|
38 |
* @param AmountFactory $amount_factory The amount factory.
|
39 |
* @param SellerReceivableBreakdownFactory $seller_receivable_breakdown_factory The SellerReceivableBreakdown factory.
|
|
|
40 |
*/
|
41 |
public function __construct(
|
42 |
AmountFactory $amount_factory,
|
43 |
-
SellerReceivableBreakdownFactory $seller_receivable_breakdown_factory
|
|
|
44 |
) {
|
45 |
|
46 |
$this->amount_factory = $amount_factory;
|
47 |
$this->seller_receivable_breakdown_factory = $seller_receivable_breakdown_factory;
|
|
|
48 |
}
|
49 |
|
50 |
/**
|
@@ -55,12 +65,15 @@ class CaptureFactory {
|
|
55 |
* @return Capture
|
56 |
*/
|
57 |
public function from_paypal_response( \stdClass $data ) : Capture {
|
58 |
-
|
59 |
$reason = $data->status_details->reason ?? null;
|
60 |
$seller_receivable_breakdown = isset( $data->seller_receivable_breakdown ) ?
|
61 |
$this->seller_receivable_breakdown_factory->from_paypal_response( $data->seller_receivable_breakdown )
|
62 |
: null;
|
63 |
|
|
|
|
|
|
|
|
|
64 |
return new Capture(
|
65 |
(string) $data->id,
|
66 |
new CaptureStatus(
|
@@ -72,7 +85,8 @@ class CaptureFactory {
|
|
72 |
(string) $data->seller_protection->status,
|
73 |
(string) $data->invoice_id,
|
74 |
(string) $data->custom_id,
|
75 |
-
$seller_receivable_breakdown
|
|
|
76 |
);
|
77 |
}
|
78 |
}
|
32 |
*/
|
33 |
private $seller_receivable_breakdown_factory;
|
34 |
|
35 |
+
/**
|
36 |
+
* The FraudProcessorResponseFactory factory.
|
37 |
+
*
|
38 |
+
* @var FraudProcessorResponseFactory
|
39 |
+
*/
|
40 |
+
protected $fraud_processor_response_factory;
|
41 |
+
|
42 |
/**
|
43 |
* CaptureFactory constructor.
|
44 |
*
|
45 |
* @param AmountFactory $amount_factory The amount factory.
|
46 |
* @param SellerReceivableBreakdownFactory $seller_receivable_breakdown_factory The SellerReceivableBreakdown factory.
|
47 |
+
* @param FraudProcessorResponseFactory $fraud_processor_response_factory The FraudProcessorResponseFactory factory.
|
48 |
*/
|
49 |
public function __construct(
|
50 |
AmountFactory $amount_factory,
|
51 |
+
SellerReceivableBreakdownFactory $seller_receivable_breakdown_factory,
|
52 |
+
FraudProcessorResponseFactory $fraud_processor_response_factory
|
53 |
) {
|
54 |
|
55 |
$this->amount_factory = $amount_factory;
|
56 |
$this->seller_receivable_breakdown_factory = $seller_receivable_breakdown_factory;
|
57 |
+
$this->fraud_processor_response_factory = $fraud_processor_response_factory;
|
58 |
}
|
59 |
|
60 |
/**
|
65 |
* @return Capture
|
66 |
*/
|
67 |
public function from_paypal_response( \stdClass $data ) : Capture {
|
|
|
68 |
$reason = $data->status_details->reason ?? null;
|
69 |
$seller_receivable_breakdown = isset( $data->seller_receivable_breakdown ) ?
|
70 |
$this->seller_receivable_breakdown_factory->from_paypal_response( $data->seller_receivable_breakdown )
|
71 |
: null;
|
72 |
|
73 |
+
$fraud_processor_response = isset( $data->processor_response ) ?
|
74 |
+
$this->fraud_processor_response_factory->from_paypal_response( $data->processor_response )
|
75 |
+
: null;
|
76 |
+
|
77 |
return new Capture(
|
78 |
(string) $data->id,
|
79 |
new CaptureStatus(
|
85 |
(string) $data->seller_protection->status,
|
86 |
(string) $data->invoice_id,
|
87 |
(string) $data->custom_id,
|
88 |
+
$seller_receivable_breakdown,
|
89 |
+
$fraud_processor_response
|
90 |
);
|
91 |
}
|
92 |
}
|
modules/ppcp-api-client/src/Factory/FraudProcessorResponseFactory.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The FraudProcessorResponseFactory Factory.
|
4 |
+
*
|
5 |
+
* @package WooCommerce\PayPalCommerce\ApiClient\Factory
|
6 |
+
*/
|
7 |
+
|
8 |
+
declare(strict_types=1);
|
9 |
+
|
10 |
+
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
11 |
+
|
12 |
+
use stdClass;
|
13 |
+
use WooCommerce\PayPalCommerce\ApiClient\Entity\FraudProcessorResponse;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Class FraudProcessorResponseFactory
|
17 |
+
*/
|
18 |
+
class FraudProcessorResponseFactory {
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Returns a FraudProcessorResponse object based off a PayPal Response.
|
22 |
+
*
|
23 |
+
* @param stdClass $data The JSON object.
|
24 |
+
*
|
25 |
+
* @return FraudProcessorResponse
|
26 |
+
*/
|
27 |
+
public function from_paypal_response( stdClass $data ): FraudProcessorResponse {
|
28 |
+
$avs_code = $data->avs_code ?: null;
|
29 |
+
$cvv_code = $data->cvv_code ?: null;
|
30 |
+
|
31 |
+
return new FraudProcessorResponse( $avs_code, $cvv_code );
|
32 |
+
}
|
33 |
+
}
|
modules/ppcp-api-client/src/Factory/ItemFactory.php
CHANGED
@@ -142,7 +142,7 @@ class ItemFactory {
|
|
142 |
mb_substr( $product->get_name(), 0, 127 ),
|
143 |
new Money( $price_without_tax_rounded, $currency ),
|
144 |
$quantity,
|
145 |
-
|
146 |
$tax,
|
147 |
$product->get_sku(),
|
148 |
( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
|
142 |
mb_substr( $product->get_name(), 0, 127 ),
|
143 |
new Money( $price_without_tax_rounded, $currency ),
|
144 |
$quantity,
|
145 |
+
substr( wp_strip_all_tags( $product->get_description() ), 0, 127 ) ?: '',
|
146 |
$tax,
|
147 |
$product->get_sku(),
|
148 |
( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS
|
modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php
CHANGED
@@ -107,7 +107,12 @@ class PurchaseUnitFactory {
|
|
107 |
*/
|
108 |
public function from_wc_order( \WC_Order $order ): PurchaseUnit {
|
109 |
$amount = $this->amount_factory->from_wc_order( $order );
|
110 |
-
$items =
|
|
|
|
|
|
|
|
|
|
|
111 |
$shipping = $this->shipping_factory->from_wc_order( $order );
|
112 |
if (
|
113 |
! $this->shipping_needed( ... array_values( $items ) ) ||
|
@@ -153,7 +158,12 @@ class PurchaseUnitFactory {
|
|
153 |
*/
|
154 |
public function from_wc_cart( \WC_Cart $cart ): PurchaseUnit {
|
155 |
$amount = $this->amount_factory->from_wc_cart( $cart );
|
156 |
-
$items =
|
|
|
|
|
|
|
|
|
|
|
157 |
|
158 |
$shipping = null;
|
159 |
$customer = \WC()->customer;
|
107 |
*/
|
108 |
public function from_wc_order( \WC_Order $order ): PurchaseUnit {
|
109 |
$amount = $this->amount_factory->from_wc_order( $order );
|
110 |
+
$items = array_filter(
|
111 |
+
$this->item_factory->from_wc_order( $order ),
|
112 |
+
function ( Item $item ): bool {
|
113 |
+
return $item->unit_amount()->value() > 0;
|
114 |
+
}
|
115 |
+
);
|
116 |
$shipping = $this->shipping_factory->from_wc_order( $order );
|
117 |
if (
|
118 |
! $this->shipping_needed( ... array_values( $items ) ) ||
|
158 |
*/
|
159 |
public function from_wc_cart( \WC_Cart $cart ): PurchaseUnit {
|
160 |
$amount = $this->amount_factory->from_wc_cart( $cart );
|
161 |
+
$items = array_filter(
|
162 |
+
$this->item_factory->from_wc_cart( $cart ),
|
163 |
+
function ( Item $item ): bool {
|
164 |
+
return $item->unit_amount()->value() > 0;
|
165 |
+
}
|
166 |
+
);
|
167 |
|
168 |
$shipping = null;
|
169 |
$customer = \WC()->customer;
|
modules/ppcp-button/assets/js/button.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
(()=>{"use strict";var __webpack_modules__={536:()=>{eval("\n;// CONCATENATED MODULE: ./resources/js/modules/ErrorHandler.js\nclass ErrorHandler {\n constructor(genericErrorText) {\n this.genericErrorText = genericErrorText;\n this.wrapper = document.querySelector('.woocommerce-notices-wrapper');\n this.messagesList = document.querySelector('ul.woocommerce-error');\n }\n\n genericError() {\n if (this.wrapper.classList.contains('ppcp-persist')) {\n return;\n }\n\n this.clear();\n this.message(this.genericErrorText);\n }\n\n appendPreparedErrorMessageElement(errorMessageElement) {\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n this.messagesList.replaceWith(errorMessageElement);\n }\n\n message(text, persist = false) {\n if (!typeof String || text.length === 0) {\n throw new Error('A new message text must be a non-empty string.');\n }\n\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n if (persist) {\n this.wrapper.classList.add('ppcp-persist');\n } else {\n this.wrapper.classList.remove('ppcp-persist');\n }\n\n let messageNode = this.prepareMessagesListItem(text);\n this.messagesList.appendChild(messageNode);\n jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'));\n }\n\n prepareMessagesList() {\n if (this.messagesList === null) {\n this.messagesList = document.createElement('ul');\n this.messagesList.setAttribute('class', 'woocommerce-error');\n this.messagesList.setAttribute('role', 'alert');\n this.wrapper.appendChild(this.messagesList);\n }\n }\n\n prepareMessagesListItem(message) {\n const li = document.createElement('li');\n li.innerHTML = message;\n return li;\n }\n\n sanitize(text) {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = text;\n return textarea.value.replace('Error: ', '');\n }\n\n clear() {\n if (this.messagesList === null) {\n return;\n }\n\n this.messagesList.innerHTML = '';\n }\n\n}\n\n/* harmony default export */ const modules_ErrorHandler = (ErrorHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForContinue.js\nconst onApprove = (context, errorHandler) => {\n return (data, actions) => {\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID,\n funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/CheckoutMethodState.js\nconst PaymentMethods = {\n PAYPAL: 'ppcp-gateway',\n CARDS: 'ppcp-credit-card-gateway'\n};\nconst ORDER_BUTTON_SELECTOR = '#place_order';\nconst getCurrentPaymentMethod = () => {\n const el = document.querySelector('input[name=\"payment_method\"]:checked');\n\n if (!el) {\n return null;\n }\n\n return el.value;\n};\nconst isSavedCardSelected = () => {\n const savedCardList = document.querySelector('#saved-credit-card');\n return savedCardList && savedCardList.value !== '';\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CartActionHandler.js\n\n\n\n\nclass CartActionHandler {\n constructor(config, errorHandler) {\n this.config = config;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units: [],\n payment_method: PaymentMethods.PAYPAL,\n funding_source: window.ppcpFundingSource,\n bn_code: bnCode,\n payer,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CartActionHandler = (CartActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/MiniCartBootstap.js\n\n\n\nclass MiniCartBootstap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.actionHandler = null;\n }\n\n init() {\n this.actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.render();\n jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.mini_cart_wrapper) !== null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.renderer.render(this.gateway.button.mini_cart_wrapper, this.gateway.hosted_fields.mini_cart_wrapper, this.actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_MiniCartBootstap = (MiniCartBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/UpdateCart.js\n\n\nclass UpdateCart {\n constructor(endpoint, nonce) {\n this.endpoint = endpoint;\n this.nonce = nonce;\n }\n /**\n *\n * @param onResolve\n * @param {Product[]} products\n * @returns {Promise<unknown>}\n */\n\n\n update(onResolve, products) {\n return new Promise((resolve, reject) => {\n fetch(this.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.nonce,\n products\n })\n }).then(result => {\n return result.json();\n }).then(result => {\n if (!result.success) {\n reject(result.data);\n return;\n }\n\n const resolved = onResolve(result.data);\n resolve(resolved);\n });\n });\n }\n\n}\n\n/* harmony default export */ const Helper_UpdateCart = (UpdateCart);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/ButtonsToggleListener.js\n/**\n * When you can't add something to the cart, the PayPal buttons should not show.\n * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.\n */\nclass ButtonsToggleListener {\n constructor(element, showCallback, hideCallback) {\n this.element = element;\n this.showCallback = showCallback;\n this.hideCallback = hideCallback;\n this.observer = null;\n }\n\n init() {\n const config = {\n attributes: true\n };\n\n const callback = () => {\n if (this.element.classList.contains('disabled')) {\n this.hideCallback();\n return;\n }\n\n this.showCallback();\n };\n\n this.observer = new MutationObserver(callback);\n this.observer.observe(this.element, config);\n callback();\n }\n\n disconnect() {\n this.observer.disconnect();\n }\n\n}\n\n/* harmony default export */ const Helper_ButtonsToggleListener = (ButtonsToggleListener);\n;// CONCATENATED MODULE: ./resources/js/modules/Entity/Product.js\nclass Product {\n constructor(id, quantity, variations) {\n this.id = id;\n this.quantity = quantity;\n this.variations = variations;\n }\n\n data() {\n return {\n id: this.id,\n quantity: this.quantity,\n variations: this.variations\n };\n }\n\n}\n\n/* harmony default export */ const Entity_Product = (Product);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/SingleProductActionHandler.js\n\n\n\n\n\n\nclass SingleProductActionHandler {\n constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler) {\n this.config = config;\n this.updateCart = updateCart;\n this.showButtonCallback = showButtonCallback;\n this.hideButtonCallback = hideButtonCallback;\n this.formElement = formElement;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n if (this.hasVariations()) {\n const observer = new Helper_ButtonsToggleListener(this.formElement.querySelector('.single_add_to_cart_button'), this.showButtonCallback, this.hideButtonCallback);\n observer.init();\n }\n\n return {\n createOrder: this.createOrder(),\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n createOrder() {\n var getProducts = null;\n\n if (!this.isGroupedProduct()) {\n getProducts = () => {\n const id = document.querySelector('[name=\"add-to-cart\"]').value;\n const qty = document.querySelector('[name=\"quantity\"]').value;\n const variations = this.variations();\n return [new Entity_Product(id, qty, variations)];\n };\n } else {\n getProducts = () => {\n const products = [];\n this.formElement.querySelectorAll('input[type=\"number\"]').forEach(element => {\n if (!element.value) {\n return;\n }\n\n const elementName = element.getAttribute('name').match(/quantity\\[([\\d]*)\\]/);\n\n if (elementName.length !== 2) {\n return;\n }\n\n const id = parseInt(elementName[1]);\n const quantity = parseInt(element.value);\n products.push(new Entity_Product(id, quantity, null));\n });\n return products;\n };\n }\n\n const createOrder = (data, actions) => {\n this.errorHandler.clear();\n\n const onResolve = purchase_units => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units,\n payer,\n bn_code: bnCode,\n payment_method: PaymentMethods.PAYPAL,\n funding_source: window.ppcpFundingSource,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n const promise = this.updateCart.update(onResolve, getProducts());\n return promise;\n };\n\n return createOrder;\n }\n\n variations() {\n if (!this.hasVariations()) {\n return null;\n }\n\n const attributes = [...this.formElement.querySelectorAll(\"[name^='attribute_']\")].map(element => {\n return {\n value: element.value,\n name: element.name\n };\n });\n return attributes;\n }\n\n hasVariations() {\n return this.formElement.classList.contains('variations_form');\n }\n\n isGroupedProduct() {\n return this.formElement.classList.contains('grouped_form');\n }\n\n}\n\n/* harmony default export */ const ActionHandler_SingleProductActionHandler = (SingleProductActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/SingleProductBootstap.js\n\n\n\n\nclass SingleProductBootstap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n }\n\n handleChange() {\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n this.renderer.hideButtons(this.gateway.button.wrapper);\n return;\n }\n\n this.render();\n }\n\n init() {\n document.querySelector('form.cart').addEventListener('change', this.handleChange.bind(this));\n\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n return;\n }\n\n this.render();\n }\n\n shouldRender() {\n return document.querySelector('form.cart') !== null && !this.priceAmountIsZero();\n }\n\n priceAmountIsZero() {\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('.product .woocommerce-Price-amount')) {\n priceText = document.querySelector('.product .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseFloat(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n return amount === 0;\n }\n\n render() {\n const actionHandler = new ActionHandler_SingleProductActionHandler(this.gateway, new Helper_UpdateCart(this.gateway.ajax.change_cart.endpoint, this.gateway.ajax.change_cart.nonce), () => {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseInt(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n this.messages.renderWithAmount(amount);\n }, () => {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }, document.querySelector('form.cart'), new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_SingleProductBootstap = (SingleProductBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CartBootstap.js\n\n\n\nclass CartBootstrap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n }\n\n init() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.render();\n jQuery(document.body).on('updated_cart_totals updated_checkout', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n const actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const CartBootstap = (CartBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForPayNow.js\nconst onApproveForPayNow_onApprove = (context, errorHandler, spinner) => {\n return (data, actions) => {\n spinner.block();\n errorHandler.clear();\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID,\n funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\n\nclass CheckoutActionHandler {\n constructor(config, errorHandler, spinner) {\n this.config = config;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n }\n\n configuration() {\n const spinner = this.spinner;\n\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n const errorHandler = this.errorHandler;\n const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';\n const formValues = jQuery(formSelector).serialize();\n const createaccount = jQuery('#createaccount').is(\":checked\") ? true : false;\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n payer,\n bn_code: bnCode,\n context: this.config.context,\n order_id: this.config.order_id,\n payment_method: getCurrentPaymentMethod(),\n funding_source: window.ppcpFundingSource,\n form: formValues,\n createaccount: createaccount\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n spinner.unblock(); //handle both messages sent from Woocommerce (data.messages) and this plugin (data.data.message)\n\n if (typeof data.messages !== 'undefined') {\n const domParser = new DOMParser();\n errorHandler.appendPreparedErrorMessageElement(domParser.parseFromString(data.messages, 'text/html').querySelector('ul'));\n } else {\n errorHandler.clear();\n\n if (data.data.details.length > 0) {\n errorHandler.message(data.data.details.map(d => `${d.issue} ${d.description}`).join('<br/>'), true);\n } else {\n errorHandler.message(data.data.message, true);\n }\n }\n\n return;\n }\n\n const input = document.createElement('input');\n input.setAttribute('type', 'hidden');\n input.setAttribute('name', 'ppcp-resume-order');\n input.setAttribute('value', data.data.purchase_units[0].custom_id);\n document.querySelector(formSelector).append(input);\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForPayNow(this, this.errorHandler, this.spinner),\n onCancel: () => {\n spinner.unblock();\n },\n onError: () => {\n this.errorHandler.genericError();\n spinner.unblock();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CheckoutActionHandler = (CheckoutActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Hiding.js\nconst getElement = selectorOrElement => {\n if (typeof selectorOrElement === 'string') {\n return document.querySelector(selectorOrElement);\n }\n\n return selectorOrElement;\n};\n\nconst isVisible = element => {\n return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);\n};\nconst setVisible = (selectorOrElement, show, important = false) => {\n const element = getElement(selectorOrElement);\n\n if (!element) {\n return;\n }\n\n const currentValue = element.style.getPropertyValue('display');\n\n if (!show) {\n if (currentValue === 'none') {\n return;\n }\n\n element.style.setProperty('display', 'none', important ? 'important' : '');\n } else {\n if (currentValue === 'none') {\n element.style.removeProperty('display');\n } // still not visible (if something else added display: none in CSS)\n\n\n if (!isVisible(element)) {\n element.style.setProperty('display', 'block');\n }\n }\n};\nconst hide = (selectorOrElement, important = false) => {\n setVisible(selectorOrElement, false, important);\n};\nconst show = selectorOrElement => {\n setVisible(selectorOrElement, true);\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CheckoutBootstap.js\n\n\n\n\n\nclass CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n this.standardOrderButtonSelector = ORDER_BUTTON_SELECTOR;\n this.buttonChangeObserver = new MutationObserver(el => {\n this.updateUi();\n });\n }\n\n init() {\n this.render(); // Unselect saved card.\n // WC saves form values, so with our current UI it would be a bit weird\n // if the user paid with saved, then after some time tries to pay again,\n // but wants to enter a new card, and to do that they have to choose “Select payment” in the list.\n\n jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.updateUi();\n });\n jQuery(document).on('hosted_fields_loaded', () => {\n jQuery('#saved-credit-card').on('change', () => {\n this.updateUi();\n });\n });\n this.updateUi();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n this.buttonChangeObserver.observe(document.querySelector(this.standardOrderButtonSelector), {\n attributes: true\n });\n }\n\n updateUi() {\n const currentPaymentMethod = getCurrentPaymentMethod();\n const isPaypal = currentPaymentMethod === PaymentMethods.PAYPAL;\n const isCard = currentPaymentMethod === PaymentMethods.CARDS;\n const isSavedCard = isCard && isSavedCardSelected();\n const isNotOurGateway = !isPaypal && !isCard;\n const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;\n const hasVaultedPaypal = PayPalCommerceGateway.vaulted_paypal_email !== '';\n setVisible(this.standardOrderButtonSelector, isPaypal && isFreeTrial && hasVaultedPaypal || isNotOurGateway || isSavedCard, true);\n setVisible('.ppcp-vaulted-paypal-details', isPaypal);\n setVisible(this.gateway.button.wrapper, isPaypal && !(isFreeTrial && hasVaultedPaypal));\n setVisible(this.gateway.messages.wrapper, isPaypal && !isFreeTrial);\n setVisible(this.gateway.hosted_fields.wrapper, isCard && !isSavedCard);\n\n if (isPaypal && !isFreeTrial) {\n this.messages.render();\n }\n\n if (isCard) {\n if (isSavedCard) {\n this.disableCreditCardFields();\n } else {\n this.enableCreditCardFields();\n }\n }\n }\n\n disableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", true);\n this.renderer.disableCreditCardFields();\n }\n\n enableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", false);\n this.renderer.enableCreditCardFields();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_CheckoutBootstap = (CheckoutBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Subscriptions.js\nconst isChangePaymentPage = () => {\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.has('change_payment_method');\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/PayNowBootstrap.js\n\n\n\nclass PayNowBootstrap extends ContextBootstrap_CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n super(gateway, renderer, messages, spinner);\n }\n\n updateUi() {\n if (isChangePaymentPage()) {\n return;\n }\n\n super.updateUi();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_PayNowBootstrap = (PayNowBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/Renderer.js\nclass Renderer {\n constructor(creditCardRenderer, defaultConfig, onSmartButtonClick, onSmartButtonsInit) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n this.onSmartButtonClick = onSmartButtonClick;\n this.onSmartButtonsInit = onSmartButtonsInit;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig,\n onClick: this.onSmartButtonClick,\n onInit: this.onSmartButtonsInit\n }).render(wrapper);\n }\n\n isAlreadyRendered(wrapper) {\n return document.querySelector(wrapper).hasChildNodes();\n }\n\n hideButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'none';\n return true;\n }\n\n showButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'block';\n return true;\n }\n\n disableCreditCardFields() {\n this.creditCardRenderer.disableFields();\n }\n\n enableCreditCardFields() {\n this.creditCardRenderer.enableFields();\n }\n\n}\n\n/* harmony default export */ const Renderer_Renderer = (Renderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/DccInputFactory.js\nconst dccInputFactory = original => {\n const styles = window.getComputedStyle(original);\n const newElement = document.createElement('span');\n newElement.setAttribute('id', original.id);\n Object.values(styles).forEach(prop => {\n if (!styles[prop] || !isNaN(prop)) {\n return;\n }\n\n newElement.style.setProperty(prop, '' + styles[prop]);\n });\n return newElement;\n};\n\n/* harmony default export */ const DccInputFactory = (dccInputFactory);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/CreditCardRenderer.js\n\n\n\nclass CreditCardRenderer {\n constructor(defaultConfig, errorHandler, spinner) {\n this.defaultConfig = defaultConfig;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n this.cardValid = false;\n this.formValid = false;\n this.currentHostedFieldsInstance = null;\n }\n\n render(wrapper, contextConfig) {\n if (this.defaultConfig.context !== 'checkout' && this.defaultConfig.context !== 'pay-now' || wrapper === null || document.querySelector(wrapper) === null) {\n return;\n }\n\n if (typeof paypal.HostedFields === 'undefined' || !paypal.HostedFields.isEligible()) {\n const wrapperElement = document.querySelector(wrapper);\n wrapperElement.parentNode.removeChild(wrapperElement);\n return;\n }\n\n const buttonSelector = wrapper + ' button';\n\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.teardown().catch(err => console.error(`Hosted fields teardown error: ${err}`));\n this.currentHostedFieldsInstance = null;\n }\n\n const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');\n const oldDisplayStyle = gateWayBox.style.display;\n gateWayBox.style.display = 'block';\n const hideDccGateway = document.querySelector('#ppcp-hide-dcc');\n\n if (hideDccGateway) {\n hideDccGateway.parentNode.removeChild(hideDccGateway);\n }\n\n const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');\n const stylesRaw = window.getComputedStyle(cardNumberField);\n let styles = {};\n Object.values(stylesRaw).forEach(prop => {\n if (!stylesRaw[prop]) {\n return;\n }\n\n styles[prop] = '' + stylesRaw[prop];\n });\n const cardNumber = DccInputFactory(cardNumberField);\n cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);\n const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');\n const cardExpiry = DccInputFactory(cardExpiryField);\n cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);\n const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');\n const cardCode = DccInputFactory(cardCodeField);\n cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);\n gateWayBox.style.display = oldDisplayStyle;\n const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';\n\n if (this.defaultConfig.enforce_vault && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')) {\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);\n }\n\n paypal.HostedFields.render({\n createOrder: contextConfig.createOrder,\n styles: {\n 'input': styles\n },\n fields: {\n number: {\n selector: '#ppcp-credit-card-gateway-card-number',\n placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number\n },\n cvv: {\n selector: '#ppcp-credit-card-gateway-card-cvc',\n placeholder: this.defaultConfig.hosted_fields.labels.cvv\n },\n expirationDate: {\n selector: '#ppcp-credit-card-gateway-card-expiry',\n placeholder: this.defaultConfig.hosted_fields.labels.mm_yy\n }\n }\n }).then(hostedFields => {\n document.dispatchEvent(new CustomEvent(\"hosted_fields_loaded\"));\n this.currentHostedFieldsInstance = hostedFields;\n hostedFields.on('inputSubmitRequest', () => {\n this._submit(contextConfig);\n });\n hostedFields.on('cardTypeChange', event => {\n if (!event.cards.length) {\n this.cardValid = false;\n return;\n }\n\n const validCards = this.defaultConfig.hosted_fields.valid_cards;\n this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;\n });\n hostedFields.on('validityChange', event => {\n const formValid = Object.keys(event.fields).every(function (key) {\n return event.fields[key].isValid;\n });\n this.formValid = formValid;\n });\n show(buttonSelector);\n\n if (document.querySelector(wrapper).getAttribute('data-ppcp-subscribed') !== true) {\n document.querySelector(buttonSelector).addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n document.querySelector(wrapper).setAttribute('data-ppcp-subscribed', true);\n }\n });\n document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener('click', () => {\n document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();\n });\n }\n\n disableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.setAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n enableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n _submit(contextConfig) {\n this.spinner.block();\n this.errorHandler.clear();\n\n if (this.formValid && this.cardValid) {\n const save_card = this.defaultConfig.can_save_vault_token ? true : false;\n let vault = document.getElementById('ppcp-credit-card-vault') ? document.getElementById('ppcp-credit-card-vault').checked : save_card;\n\n if (this.defaultConfig.enforce_vault) {\n vault = true;\n }\n\n const contingency = this.defaultConfig.hosted_fields.contingency;\n const hostedFieldsData = {\n vault: vault\n };\n\n if (contingency !== 'NO_3D_SECURE') {\n hostedFieldsData.contingencies = [contingency];\n }\n\n if (this.defaultConfig.payer) {\n hostedFieldsData.cardholderName = this.defaultConfig.payer.name.given_name + ' ' + this.defaultConfig.payer.name.surname;\n }\n\n if (!hostedFieldsData.cardholderName) {\n const firstName = document.getElementById('billing_first_name') ? document.getElementById('billing_first_name').value : '';\n const lastName = document.getElementById('billing_last_name') ? document.getElementById('billing_last_name').value : '';\n\n if (!firstName || !lastName) {\n this.spinner.unblock();\n this.errorHandler.message(this.defaultConfig.hosted_fields.labels.cardholder_name_required);\n return;\n }\n\n hostedFieldsData.cardholderName = firstName + ' ' + lastName;\n }\n\n this.currentHostedFieldsInstance.submit(hostedFieldsData).then(payload => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n }).catch(err => {\n this.spinner.unblock();\n this.errorHandler.clear();\n\n if (err.details) {\n this.errorHandler.message(err.details.map(d => `${d.issue} ${d.description}`).join('<br/>'), true);\n }\n });\n } else {\n this.spinner.unblock();\n const message = !this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;\n this.errorHandler.message(message);\n }\n }\n\n}\n\n/* harmony default export */ const Renderer_CreditCardRenderer = (CreditCardRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/DataClientIdAttributeHandler.js\nconst storageKey = 'ppcp-data-client-id';\n\nconst validateToken = (token, user) => {\n if (!token) {\n return false;\n }\n\n if (token.user !== user) {\n return false;\n }\n\n const currentTime = new Date().getTime();\n const isExpired = currentTime >= token.expiration * 1000;\n return !isExpired;\n};\n\nconst storedTokenForUser = user => {\n const token = JSON.parse(sessionStorage.getItem(storageKey));\n\n if (validateToken(token, user)) {\n return token.token;\n }\n\n return null;\n};\n\nconst storeToken = token => {\n sessionStorage.setItem(storageKey, JSON.stringify(token));\n};\n\nconst dataClientIdAttributeHandler = (script, config) => {\n fetch(config.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: config.nonce\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n const isValid = validateToken(data, config.user);\n\n if (!isValid) {\n return;\n }\n\n storeToken(data);\n script.setAttribute('data-client-token', data.token);\n document.body.append(script);\n });\n};\n\n/* harmony default export */ const DataClientIdAttributeHandler = (dataClientIdAttributeHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/MessageRenderer.js\nclass MessageRenderer {\n constructor(config) {\n this.config = config;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n renderWithAmount(amount) {\n if (!this.shouldRender()) {\n return;\n }\n\n const newWrapper = document.createElement('div');\n newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));\n const sibling = document.querySelector(this.config.wrapper).nextSibling;\n document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));\n sibling.parentElement.insertBefore(newWrapper, sibling);\n paypal.Messages({\n amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n shouldRender() {\n if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined') {\n return false;\n }\n\n if (!document.querySelector(this.config.wrapper)) {\n return false;\n }\n\n return true;\n }\n\n}\n\n/* harmony default export */ const Renderer_MessageRenderer = (MessageRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Spinner.js\nclass Spinner {\n constructor(target = 'form.woocommerce-checkout') {\n this.target = target;\n }\n\n setTarget(target) {\n this.target = target;\n }\n\n block() {\n jQuery(this.target).block({\n message: null,\n overlayCSS: {\n background: '#fff',\n opacity: 0.6\n }\n });\n }\n\n unblock() {\n jQuery(this.target).unblock();\n }\n\n}\n\n/* harmony default export */ const Helper_Spinner = (Spinner);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/FreeTrialHandler.js\n\n\n\nclass FreeTrialHandler {\n constructor(config, spinner, errorHandler) {\n this.config = config;\n this.spinner = spinner;\n this.errorHandler = errorHandler;\n }\n\n handle() {\n this.spinner.block();\n fetch(this.config.ajax.vault_paypal.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.vault_paypal.nonce,\n return_url: location.href\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n this.spinner.unblock();\n console.error(data);\n this.errorHandler.message(data.data.message);\n throw Error(data.data.message);\n }\n\n location.href = data.data.approve_link;\n }).catch(error => {\n this.spinner.unblock();\n console.error(error);\n this.errorHandler.genericError();\n });\n }\n\n}\n\n/* harmony default export */ const ActionHandler_FreeTrialHandler = (FreeTrialHandler);\n;// CONCATENATED MODULE: ./resources/js/button.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst buttonsSpinner = new Helper_Spinner('.ppc-button-wrapper');\nconst cardsSpinner = new Helper_Spinner('#ppcp-hosted-fields');\n\nconst bootstrap = () => {\n const errorHandler = new modules_ErrorHandler(PayPalCommerceGateway.labels.error.generic);\n const spinner = new Helper_Spinner();\n const creditCardRenderer = new Renderer_CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);\n const freeTrialHandler = new ActionHandler_FreeTrialHandler(PayPalCommerceGateway, spinner, errorHandler);\n\n const onSmartButtonClick = (data, actions) => {\n window.ppcpFundingSource = data.fundingSource;\n const form = document.querySelector('form.woocommerce-checkout');\n\n if (form) {\n jQuery('#ppcp-funding-source-form-input').remove();\n form.insertAdjacentHTML('beforeend', `<input type=\"hidden\" name=\"ppcp-funding-source\" value=\"${data.fundingSource}\" id=\"ppcp-funding-source-form-input\">`);\n }\n\n const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;\n\n if (isFreeTrial && data.fundingSource !== 'card') {\n freeTrialHandler.handle();\n return actions.reject();\n }\n };\n\n const onSmartButtonsInit = () => {\n buttonsSpinner.unblock();\n };\n\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick, onSmartButtonsInit);\n const messageRenderer = new Renderer_MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n\n if (context === 'mini-cart' || context === 'product') {\n if (PayPalCommerceGateway.mini_cart_buttons_enabled === '1') {\n const miniCartBootstrap = new ContextBootstrap_MiniCartBootstap(PayPalCommerceGateway, renderer);\n miniCartBootstrap.init();\n }\n }\n\n if (context === 'product' && PayPalCommerceGateway.single_product_buttons_enabled === '1') {\n const singleProductBootstrap = new ContextBootstrap_SingleProductBootstap(PayPalCommerceGateway, renderer, messageRenderer);\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstap(PayPalCommerceGateway, renderer);\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new ContextBootstrap_CheckoutBootstap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now') {\n const payNowBootstrap = new ContextBootstrap_PayNowBootstrap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (!typeof PayPalCommerceGateway) {\n console.error('PayPal button could not be configured.');\n return;\n }\n\n if (PayPalCommerceGateway.context !== 'checkout' && PayPalCommerceGateway.data_client_id.user === 0 && PayPalCommerceGateway.data_client_id.has_subscriptions) {\n return;\n } // Sometimes PayPal script takes long time to load,\n // so we additionally hide the standard order button here to avoid failed orders.\n // Normally it is hidden later after the script load.\n\n\n const hideOrderButtonIfPpcpGateway = () => {\n // only in checkout and pay now page, otherwise it may break things (e.g. payment via product page),\n // and also the loading spinner may look weird on other pages\n if (!['checkout', 'pay-now'].includes(PayPalCommerceGateway.context) || isChangePaymentPage() || PayPalCommerceGateway.is_free_trial_cart && PayPalCommerceGateway.vaulted_paypal_email !== '') {\n return;\n }\n\n const currentPaymentMethod = getCurrentPaymentMethod();\n const isPaypal = currentPaymentMethod === PaymentMethods.PAYPAL;\n const isCards = currentPaymentMethod === PaymentMethods.CARDS;\n setVisible(ORDER_BUTTON_SELECTOR, !isPaypal && !isCards, true);\n\n if (isPaypal) {\n // stopped after the first rendering of the buttons, in onInit\n buttonsSpinner.block();\n } else {\n buttonsSpinner.unblock();\n }\n\n if (isCards) {\n cardsSpinner.block();\n } else {\n cardsSpinner.unblock();\n }\n };\n\n jQuery(document).on('hosted_fields_loaded', () => {\n cardsSpinner.unblock();\n });\n let bootstrapped = false;\n hideOrderButtonIfPpcpGateway();\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n if (bootstrapped) {\n return;\n }\n\n hideOrderButtonIfPpcpGateway();\n });\n const script = document.createElement('script');\n script.addEventListener('load', event => {\n bootstrapped = true;\n bootstrap();\n });\n script.setAttribute('src', PayPalCommerceGateway.button.url);\n Object.entries(PayPalCommerceGateway.script_attributes).forEach(keyValue => {\n script.setAttribute(keyValue[0], keyValue[1]);\n });\n\n if (PayPalCommerceGateway.data_client_id.set_attribute) {\n DataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);\n return;\n }\n\n document.body.append(script);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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L0IsQ0FBNUI7QUFDQTtBQUNIOztBQUVEM1gsRUFBQUEsUUFBUSxDQUFDMkMsSUFBVCxDQUFjb0osTUFBZCxDQUFxQjBKLE1BQXJCO0FBQ0gsQ0FyRkwiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRXJyb3JIYW5kbGVyLmpzP2U2NWEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanM/YzQ1NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1BheWVyRGF0YS5qcz8yYWYxIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQ2hlY2tvdXRNZXRob2RTdGF0ZS5qcz84MGEzIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyLmpzPzgyY2YiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcC5qcz9kNTUyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvVXBkYXRlQ2FydC5qcz9lNDIyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyLmpzP2UxOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0VudGl0eS9Qcm9kdWN0LmpzPzlmZmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIuanM/ZDliNyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAuanM/N2MxOSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAuanM/NWU5NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanM/OTMwNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXIuanM/ODUxNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0hpZGluZy5qcz8xZDM2Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAuanM/Yzg1NSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1N1YnNjcmlwdGlvbnMuanM/Yjg3MCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9QYXlOb3dCb290c3RyYXAuanM/ZDlmNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvUmVuZGVyZXIuanM/ZmE5MyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0RjY0lucHV0RmFjdG9yeS5qcz8yYTJmIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9DcmVkaXRDYXJkUmVuZGVyZXIuanM/Mzg3YSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlci5qcz9lZTBiIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXIuanM/Y2QwMiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1NwaW5uZXIuanM/MTcwOCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9GcmVlVHJpYWxIYW5kbGVyLmpzP2FiNzciLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9idXR0b24uanM/MDYwZiJdLCJzb3VyY2VzQ29udGVudCI6WyJjbGFzcyBFcnJvckhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoZ2VuZXJpY0Vycm9yVGV4dClcbiAgICB7XG4gICAgICAgIHRoaXMuZ2VuZXJpY0Vycm9yVGV4dCA9IGdlbmVyaWNFcnJvclRleHQ7XG4gICAgICAgIHRoaXMud3JhcHBlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53b29jb21tZXJjZS1ub3RpY2VzLXdyYXBwZXInKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd1bC53b29jb21tZXJjZS1lcnJvcicpO1xuICAgIH1cblxuICAgIGdlbmVyaWNFcnJvcigpIHtcbiAgICAgICAgaWYgKHRoaXMud3JhcHBlci5jbGFzc0xpc3QuY29udGFpbnMoJ3BwY3AtcGVyc2lzdCcpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICB0aGlzLm1lc3NhZ2UodGhpcy5nZW5lcmljRXJyb3JUZXh0KVxuICAgIH1cblxuICAgIGFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudChlcnJvck1lc3NhZ2VFbGVtZW50KVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QucmVwbGFjZVdpdGgoZXJyb3JNZXNzYWdlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgbWVzc2FnZSh0ZXh0LCBwZXJzaXN0ID0gZmFsc2UpXG4gICAge1xuICAgICAgICBpZighIHR5cGVvZiBTdHJpbmcgfHwgdGV4dC5sZW5ndGggPT09IDApe1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIG5ldyBtZXNzYWdlIHRleHQgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCl7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwZXJzaXN0KSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmFkZCgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZSgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbWVzc2FnZU5vZGUgPSB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3RJdGVtKHRleHQpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5hcHBlbmRDaGlsZChtZXNzYWdlTm9kZSk7XG5cbiAgICAgICAgalF1ZXJ5LnNjcm9sbF90b19ub3RpY2VzKGpRdWVyeSgnLndvb2NvbW1lcmNlLW5vdGljZXMtd3JhcHBlcicpKVxuICAgIH1cblxuICAgIHByZXBhcmVNZXNzYWdlc0xpc3QoKVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpe1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdjbGFzcycsICd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdyb2xlJywgJ2FsZXJ0Jyk7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuYXBwZW5kQ2hpbGQodGhpcy5tZXNzYWdlc0xpc3QpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0obWVzc2FnZSlcbiAgICB7XG4gICAgICAgIGNvbnN0IGxpID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgICAgbGkuaW5uZXJIVE1MID0gbWVzc2FnZTtcblxuICAgICAgICByZXR1cm4gbGk7XG4gICAgfVxuXG4gICAgc2FuaXRpemUodGV4dClcbiAgICB7XG4gICAgICAgIGNvbnN0IHRleHRhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcbiAgICAgICAgdGV4dGFyZWEuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgcmV0dXJuIHRleHRhcmVhLnZhbHVlLnJlcGxhY2UoJ0Vycm9yOiAnLCAnJyk7XG4gICAgfVxuXG4gICAgY2xlYXIoKVxuICAgIHtcbiAgICAgICAgaWYgKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5pbm5lckhUTUwgPSAnJztcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEVycm9ySGFuZGxlcjtcbiIsImNvbnN0IG9uQXBwcm92ZSA9IChjb250ZXh0LCBlcnJvckhhbmRsZXIpID0+IHtcbiAgICByZXR1cm4gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgcmV0dXJuIGZldGNoKGNvbnRleHQuY29uZmlnLmFqYXguYXBwcm92ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgbm9uY2U6IGNvbnRleHQuY29uZmlnLmFqYXguYXBwcm92ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICBvcmRlcl9pZDpkYXRhLm9yZGVySUQsXG4gICAgICAgICAgICAgICAgZnVuZGluZ19zb3VyY2U6IHdpbmRvdy5wcGNwRnVuZGluZ1NvdXJjZSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pLnRoZW4oKHJlcyk9PntcbiAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICB9KS50aGVuKChkYXRhKT0+e1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjdGlvbnMucmVzdGFydCgpLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvY2F0aW9uLmhyZWYgPSBjb250ZXh0LmNvbmZpZy5yZWRpcmVjdDtcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImV4cG9ydCBjb25zdCBwYXllckRhdGEgPSAoKSA9PiB7XG4gICAgY29uc3QgcGF5ZXIgPSBQYXlQYWxDb21tZXJjZUdhdGV3YXkucGF5ZXI7XG4gICAgaWYgKCEgcGF5ZXIpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgcGhvbmUgPSAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKSB8fCB0eXBlb2YgcGF5ZXIucGhvbmUgIT09ICd1bmRlZmluZWQnKSA/XG4gICAge1xuICAgICAgICBwaG9uZV90eXBlOlwiSE9NRVwiLFxuICAgICAgICAgICAgcGhvbmVfbnVtYmVyOntcbiAgICAgICAgICAgIG5hdGlvbmFsX251bWJlciA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykudmFsdWUgOiBwYXllci5waG9uZS5waG9uZV9udW1iZXIubmF0aW9uYWxfbnVtYmVyXG4gICAgICAgIH1cbiAgICB9IDogbnVsbDtcbiAgICBjb25zdCBwYXllckRhdGEgPSB7XG4gICAgICAgIGVtYWlsX2FkZHJlc3M6KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2VtYWlsJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKS52YWx1ZSA6IHBheWVyLmVtYWlsX2FkZHJlc3MsXG4gICAgICAgIG5hbWUgOiB7XG4gICAgICAgICAgICBzdXJuYW1lOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfbGFzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfbGFzdF9uYW1lJykudmFsdWUgOiBwYXllci5uYW1lLnN1cm5hbWUsXG4gICAgICAgICAgICBnaXZlbl9uYW1lOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2ZpcnN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuZ2l2ZW5fbmFtZVxuICAgICAgICB9LFxuICAgICAgICBhZGRyZXNzIDoge1xuICAgICAgICAgICAgY291bnRyeV9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jb3VudHJ5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmNvdW50cnlfY29kZSxcbiAgICAgICAgICAgIGFkZHJlc3NfbGluZV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2FkZHJlc3NfMScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2FkZHJlc3NfMScpLnZhbHVlIDogcGF5ZXIuYWRkcmVzcy5hZGRyZXNzX2xpbmVfMSxcbiAgICAgICAgICAgIGFkZHJlc3NfbGluZV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2FkZHJlc3NfMicpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2FkZHJlc3NfMicpLnZhbHVlIDogcGF5ZXIuYWRkcmVzcy5hZGRyZXNzX2xpbmVfMixcbiAgICAgICAgICAgIGFkbWluX2FyZWFfMSA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19zdGF0ZScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMSxcbiAgICAgICAgICAgIGFkbWluX2FyZWFfMiA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY2l0eScpLnZhbHVlIDogcGF5ZXIuYWRkcmVzcy5hZG1pbl9hcmVhXzIsXG4gICAgICAgICAgICBwb3N0YWxfY29kZSA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19wb3N0Y29kZScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykudmFsdWUgOiBwYXllci5hZGRyZXNzLnBvc3RhbF9jb2RlXG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHBob25lKSB7XG4gICAgICAgIHBheWVyRGF0YS5waG9uZSA9IHBob25lO1xuICAgIH1cbiAgICByZXR1cm4gcGF5ZXJEYXRhO1xufVxuIiwiZXhwb3J0IGNvbnN0IFBheW1lbnRNZXRob2RzID0ge1xuICAgIFBBWVBBTDogJ3BwY3AtZ2F0ZXdheScsXG4gICAgQ0FSRFM6ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknLFxufTtcblxuZXhwb3J0IGNvbnN0IE9SREVSX0JVVFRPTl9TRUxFQ1RPUiA9ICcjcGxhY2Vfb3JkZXInO1xuXG5leHBvcnQgY29uc3QgZ2V0Q3VycmVudFBheW1lbnRNZXRob2QgPSAoKSA9PiB7XG4gICAgY29uc3QgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpO1xuICAgIGlmICghZWwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsLnZhbHVlO1xufTtcblxuZXhwb3J0IGNvbnN0IGlzU2F2ZWRDYXJkU2VsZWN0ZWQgPSAoKSA9PiB7XG4gICAgY29uc3Qgc2F2ZWRDYXJkTGlzdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzYXZlZC1jcmVkaXQtY2FyZCcpO1xuICAgIHJldHVybiBzYXZlZENhcmRMaXN0ICYmIHNhdmVkQ2FyZExpc3QudmFsdWUgIT09ICcnO1xufTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JDb250aW51ZS5qcyc7XG5pbXBvcnQge3BheWVyRGF0YX0gZnJvbSBcIi4uL0hlbHBlci9QYXllckRhdGFcIjtcbmltcG9ydCB7UGF5bWVudE1ldGhvZHN9IGZyb20gXCIuLi9IZWxwZXIvQ2hlY2tvdXRNZXRob2RTdGF0ZVwiO1xuXG5jbGFzcyBDYXJ0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHM6IFtdLFxuICAgICAgICAgICAgICAgICAgICBwYXltZW50X21ldGhvZDogUGF5bWVudE1ldGhvZHMuUEFZUEFMLFxuICAgICAgICAgICAgICAgICAgICBmdW5kaW5nX3NvdXJjZTogd2luZG93LnBwY3BGdW5kaW5nU291cmNlLFxuICAgICAgICAgICAgICAgICAgICBibl9jb2RlOmJuQ29kZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6dGhpcy5jb25maWcuY29udGV4dFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihyZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjcmVhdGVPcmRlcixcbiAgICAgICAgICAgIG9uQXBwcm92ZTogb25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyKSxcbiAgICAgICAgICAgIG9uRXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2FydEFjdGlvbkhhbmRsZXI7XG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ2FydEFjdGlvbkhhbmRsZXIgZnJvbSAnLi4vQWN0aW9uSGFuZGxlci9DYXJ0QWN0aW9uSGFuZGxlcic7XG5cbmNsYXNzIE1pbmlDYXJ0Qm9vdHN0YXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyKSB7XG4gICAgICAgIHRoaXMuZ2F0ZXdheSA9IGdhdGV3YXk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIgPSByZW5kZXJlcjtcbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBpbml0KCkge1xuXG4gICAgICAgIHRoaXMuYWN0aW9uSGFuZGxlciA9IG5ldyBDYXJ0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3djX2ZyYWdtZW50c19sb2FkZWQgd2NfZnJhZ21lbnRzX3JlZnJlc2hlZCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcikgIT09IG51bGxcbiAgICAgICAgICAgIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMubWluaV9jYXJ0X3dyYXBwZXIpICE9PSBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5idXR0b24ubWluaV9jYXJ0X3dyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKClcbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE1pbmlDYXJ0Qm9vdHN0YXA7XG4iLCJpbXBvcnQgUHJvZHVjdCBmcm9tIFwiLi4vRW50aXR5L1Byb2R1Y3RcIjtcbmNsYXNzIFVwZGF0ZUNhcnQge1xuXG4gICAgY29uc3RydWN0b3IoZW5kcG9pbnQsIG5vbmNlKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludCA9IGVuZHBvaW50O1xuICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25SZXNvbHZlXG4gICAgICogQHBhcmFtIHtQcm9kdWN0W119IHByb2R1Y3RzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAgICovXG4gICAgdXBkYXRlKG9uUmVzb2x2ZSwgcHJvZHVjdHMpXG4gICAge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZmV0Y2goXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qc29uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gb25SZXNvbHZlKHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVcGRhdGVDYXJ0OyIsIi8qKlxuICogV2hlbiB5b3UgY2FuJ3QgYWRkIHNvbWV0aGluZyB0byB0aGUgY2FydCwgdGhlIFBheVBhbCBidXR0b25zIHNob3VsZCBub3Qgc2hvdy5cbiAqIFRoZXJlZm9yZSB3ZSBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiBhbmQgc2hvdy9oaWRlIHRoZSBidXR0b25zIGFjY29yZGluZ2x5LlxuICovXG5cbmNsYXNzIEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2hvd0NhbGxiYWNrLCBoaWRlQ2FsbGJhY2spXG4gICAge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnNob3dDYWxsYmFjayA9IHNob3dDYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2sgPSBoaWRlQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKVxuICAgIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0geyBhdHRyaWJ1dGVzIDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNob3dDYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgZGlzY29ubmVjdCgpXG4gICAge1xuICAgICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcjsiLCJjbGFzcyBQcm9kdWN0IHtcblxuICAgIGNvbnN0cnVjdG9yKGlkLCBxdWFudGl0eSwgdmFyaWF0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMucXVhbnRpdHkgPSBxdWFudGl0eTtcbiAgICAgICAgdGhpcy52YXJpYXRpb25zID0gdmFyaWF0aW9ucztcbiAgICB9XG5cbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6dGhpcy5pZCxcbiAgICAgICAgICAgIHF1YW50aXR5OnRoaXMucXVhbnRpdHksXG4gICAgICAgICAgICB2YXJpYXRpb25zOnRoaXMudmFyaWF0aW9uc1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0OyIsImltcG9ydCBCdXR0b25zVG9nZ2xlTGlzdGVuZXIgZnJvbSAnLi4vSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lcic7XG5pbXBvcnQgUHJvZHVjdCBmcm9tICcuLi9FbnRpdHkvUHJvZHVjdCc7XG5pbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5pbXBvcnQge1BheW1lbnRNZXRob2RzfSBmcm9tIFwiLi4vSGVscGVyL0NoZWNrb3V0TWV0aG9kU3RhdGVcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgdXBkYXRlQ2FydCxcbiAgICAgICAgc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICBoaWRlQnV0dG9uQ2FsbGJhY2ssXG4gICAgICAgIGZvcm1FbGVtZW50LFxuICAgICAgICBlcnJvckhhbmRsZXJcbiAgICApIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgICAgIHRoaXMudXBkYXRlQ2FydCA9IHVwZGF0ZUNhcnQ7XG4gICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrID0gc2hvd0J1dHRvbkNhbGxiYWNrO1xuICAgICAgICB0aGlzLmhpZGVCdXR0b25DYWxsYmFjayA9IGhpZGVCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5mb3JtRWxlbWVudCA9IGZvcm1FbGVtZW50O1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKClcbiAgICB7XG5cbiAgICAgICAgaWYgKCB0aGlzLmhhc1ZhcmlhdGlvbnMoKSApIHtcbiAgICAgICAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaW5nbGVfYWRkX3RvX2NhcnRfYnV0dG9uJyksXG4gICAgICAgICAgICAgICAgdGhpcy5zaG93QnV0dG9uQ2FsbGJhY2ssXG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2tcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBvYnNlcnZlci5pbml0KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IHRoaXMuY3JlYXRlT3JkZXIoKSxcbiAgICAgICAgICAgIG9uQXBwcm92ZTogb25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyKSxcbiAgICAgICAgICAgIG9uRXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY3JlYXRlT3JkZXIoKVxuICAgIHtcbiAgICAgICAgdmFyIGdldFByb2R1Y3RzID0gbnVsbDtcbiAgICAgICAgaWYgKCEgdGhpcy5pc0dyb3VwZWRQcm9kdWN0KCkgKSB7XG4gICAgICAgICAgICBnZXRQcm9kdWN0cyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tuYW1lPVwiYWRkLXRvLWNhcnRcIl0nKS52YWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBxdHkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cInF1YW50aXR5XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFyaWF0aW9ucyA9IHRoaXMudmFyaWF0aW9ucygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBbbmV3IFByb2R1Y3QoaWQsIHF0eSwgdmFyaWF0aW9ucyldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvZHVjdHMgPSBbXTtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W3R5cGU9XCJudW1iZXJcIl0nKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIGVsZW1lbnQudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbGVtZW50TmFtZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCduYW1lJykubWF0Y2goL3F1YW50aXR5XFxbKFtcXGRdKilcXF0vKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnROYW1lLmxlbmd0aCAhPT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gcGFyc2VJbnQoZWxlbWVudE5hbWVbMV0pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWFudGl0eSA9IHBhcnNlSW50KGVsZW1lbnQudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICBwcm9kdWN0cy5wdXNoKG5ldyBQcm9kdWN0KGlkLCBxdWFudGl0eSwgbnVsbCkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb2R1Y3RzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNyZWF0ZU9yZGVyID0gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgICAgIGNvbnN0IG9uUmVzb2x2ZSA9IChwdXJjaGFzZV91bml0cykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBheWVyID0gcGF5ZXJEYXRhKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZldGNoKHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgYm5fY29kZTpibkNvZGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXltZW50X21ldGhvZDogUGF5bWVudE1ldGhvZHMuUEFZUEFMLFxuICAgICAgICAgICAgICAgICAgICAgICAgZnVuZGluZ19zb3VyY2U6IHdpbmRvdy5wcGNwRnVuZGluZ1NvdXJjZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6dGhpcy5jb25maWcuY29udGV4dFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwcm9taXNlID0gdGhpcy51cGRhdGVDYXJ0LnVwZGF0ZShvblJlc29sdmUsIGdldFByb2R1Y3RzKCkpO1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBjcmVhdGVPcmRlcjtcbiAgICB9XG5cbiAgICB2YXJpYXRpb25zKClcbiAgICB7XG5cbiAgICAgICAgaWYgKCEgdGhpcy5oYXNWYXJpYXRpb25zKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBbLi4udGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiW25hbWVePSdhdHRyaWJ1dGVfJ11cIildLm1hcChcbiAgICAgICAgICAgIChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTplbGVtZW50LnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBuYW1lOmVsZW1lbnQubmFtZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXM7XG4gICAgfVxuXG4gICAgaGFzVmFyaWF0aW9ucygpXG4gICAge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ3ZhcmlhdGlvbnNfZm9ybScpO1xuICAgIH1cblxuICAgIGlzR3JvdXBlZFByb2R1Y3QoKVxuICAgIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybUVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdncm91cGVkX2Zvcm0nKTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBTaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBVcGRhdGVDYXJ0IGZyb20gXCIuLi9IZWxwZXIvVXBkYXRlQ2FydFwiO1xuaW1wb3J0IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIGZyb20gXCIuLi9BY3Rpb25IYW5kbGVyL1NpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIsIG1lc3NhZ2VzKSB7XG4gICAgICAgIHRoaXMuZ2F0ZXdheSA9IGdhdGV3YXk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIgPSByZW5kZXJlcjtcbiAgICAgICAgdGhpcy5tZXNzYWdlcyA9IG1lc3NhZ2VzO1xuICAgIH1cblxuXG4gICAgaGFuZGxlQ2hhbmdlKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JykuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5oYW5kbGVDaGFuZ2UuYmluZCh0aGlzKSlcblxuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuXG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQnKSAhPT0gbnVsbCAmJiAhdGhpcy5wcmljZUFtb3VudElzWmVybygpO1xuXG4gICAgfVxuXG4gICAgcHJpY2VBbW91bnRJc1plcm8oKSB7XG5cbiAgICAgICAgbGV0IHByaWNlVGV4dCA9IFwiMFwiO1xuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IGlucyAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgIHByaWNlVGV4dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCBpbnMgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpLmlubmVyVGV4dDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpKSB7XG4gICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpLmlubmVyVGV4dDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucHJvZHVjdCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgIHByaWNlVGV4dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wcm9kdWN0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYW1vdW50ID0gcGFyc2VGbG9hdChwcmljZVRleHQucmVwbGFjZSgvKFteXFxkLFxcLlxcc10qKS9nLCAnJykpO1xuICAgICAgICByZXR1cm4gYW1vdW50ID09PSAwO1xuXG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LFxuICAgICAgICAgICAgbmV3IFVwZGF0ZUNhcnQoXG4gICAgICAgICAgICAgICAgdGhpcy5nYXRld2F5LmFqYXguY2hhbmdlX2NhcnQuZW5kcG9pbnQsXG4gICAgICAgICAgICAgICAgdGhpcy5nYXRld2F5LmFqYXguY2hhbmdlX2NhcnQubm9uY2UsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIGxldCBwcmljZVRleHQgPSBcIjBcIjtcbiAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IGlucyAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IGlucyAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykuaW5uZXJUZXh0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIHByaWNlVGV4dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykuaW5uZXJUZXh0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBhbW91bnQgPSBwYXJzZUludChwcmljZVRleHQucmVwbGFjZSgvKFteXFxkLFxcLlxcc10qKS9nLCAnJykpO1xuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyV2l0aEFtb3VudChhbW91bnQpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpLFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgU2luZ2xlUHJvZHVjdEJvb3RzdGFwO1xuIiwiaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuXG5jbGFzcyBDYXJ0Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscyB1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0Qm9vdHN0cmFwO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICBzcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIGVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklELFxuICAgICAgICAgICAgICAgIGZ1bmRpbmdfc291cmNlOiB3aW5kb3cucHBjcEZ1bmRpbmdTb3VyY2UsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmNvZGUgPT09IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbnMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhY3Rpb25zLnJlc3RhcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwbGFjZV9vcmRlcicpLmNsaWNrKClcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5pbXBvcnQge2dldEN1cnJlbnRQYXltZW50TWV0aG9kfSBmcm9tIFwiLi4vSGVscGVyL0NoZWNrb3V0TWV0aG9kU3RhdGVcIjtcblxuY2xhc3MgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICAgICAgdGhpcy5zcGlubmVyID0gc3Bpbm5lcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBzcGlubmVyID0gdGhpcy5zcGlubmVyO1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JIYW5kbGVyID0gdGhpcy5lcnJvckhhbmRsZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IGZvcm1TZWxlY3RvciA9IHRoaXMuY29uZmlnLmNvbnRleHQgPT09ICdjaGVja291dCcgPyAnZm9ybS5jaGVja291dCcgOiAnZm9ybSNvcmRlcl9yZXZpZXcnO1xuICAgICAgICAgICAgY29uc3QgZm9ybVZhbHVlcyA9IGpRdWVyeShmb3JtU2VsZWN0b3IpLnNlcmlhbGl6ZSgpO1xuXG4gICAgICAgICAgICBjb25zdCBjcmVhdGVhY2NvdW50ID0galF1ZXJ5KCcjY3JlYXRlYWNjb3VudCcpLmlzKFwiOmNoZWNrZWRcIikgPyB0cnVlIDogZmFsc2U7XG5cbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgYm5fY29kZTpibkNvZGUsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6dGhpcy5jb25maWcuY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgb3JkZXJfaWQ6dGhpcy5jb25maWcub3JkZXJfaWQsXG4gICAgICAgICAgICAgICAgICAgIHBheW1lbnRfbWV0aG9kOiBnZXRDdXJyZW50UGF5bWVudE1ldGhvZCgpLFxuICAgICAgICAgICAgICAgICAgICBmdW5kaW5nX3NvdXJjZTogd2luZG93LnBwY3BGdW5kaW5nU291cmNlLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOmZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWFjY291bnQ6IGNyZWF0ZWFjY291bnRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vaGFuZGxlIGJvdGggbWVzc2FnZXMgc2VudCBmcm9tIFdvb2NvbW1lcmNlIChkYXRhLm1lc3NhZ2VzKSBhbmQgdGhpcyBwbHVnaW4gKGRhdGEuZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKGRhdGEubWVzc2FnZXMpICE9PSAndW5kZWZpbmVkJyApXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5hcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhkYXRhLm1lc3NhZ2VzLCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJ3VsJylcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmRhdGEuZGV0YWlscy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLm1lc3NhZ2UoZGF0YS5kYXRhLmRldGFpbHMubWFwKGQgPT4gYCR7ZC5pc3N1ZX0gJHtkLmRlc2NyaXB0aW9ufWApLmpvaW4oJzxici8+JyksIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3BwY3AtcmVzdW1lLW9yZGVyJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGRhdGEuZGF0YS5wdXJjaGFzZV91bml0c1swXS5jdXN0b21faWQpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVNlbGVjdG9yKS5hcHBlbmQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6b25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyLCB0aGlzLnNwaW5uZXIpLFxuICAgICAgICAgICAgb25DYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QWN0aW9uSGFuZGxlcjtcbiIsImNvbnN0IGdldEVsZW1lbnQgPSAoc2VsZWN0b3JPckVsZW1lbnQpID0+IHtcbiAgICBpZiAodHlwZW9mIHNlbGVjdG9yT3JFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvck9yRWxlbWVudCk7XG4gICAgfVxuICAgIHJldHVybiBzZWxlY3Rvck9yRWxlbWVudDtcbn1cblxuZXhwb3J0IGNvbnN0IGlzVmlzaWJsZSA9IChlbGVtZW50KSA9PiB7XG4gICAgcmV0dXJuICEhKGVsZW1lbnQub2Zmc2V0V2lkdGggfHwgZWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgZWxlbWVudC5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCk7XG59XG5cbmV4cG9ydCBjb25zdCBzZXRWaXNpYmxlID0gKHNlbGVjdG9yT3JFbGVtZW50LCBzaG93LCBpbXBvcnRhbnQgPSBmYWxzZSkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBnZXRFbGVtZW50KHNlbGVjdG9yT3JFbGVtZW50KTtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGVsZW1lbnQuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgnZGlzcGxheScpO1xuXG4gICAgaWYgKCFzaG93KSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPT09ICdub25lJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnZGlzcGxheScsICdub25lJywgaW1wb3J0YW50ID8gJ2ltcG9ydGFudCcgOiAnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA9PT0gJ25vbmUnKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnJlbW92ZVByb3BlcnR5KCdkaXNwbGF5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzdGlsbCBub3QgdmlzaWJsZSAoaWYgc29tZXRoaW5nIGVsc2UgYWRkZWQgZGlzcGxheTogbm9uZSBpbiBDU1MpXG4gICAgICAgIGlmICghaXNWaXNpYmxlKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCdkaXNwbGF5JywgJ2Jsb2NrJyk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5leHBvcnQgY29uc3QgaGlkZSA9IChzZWxlY3Rvck9yRWxlbWVudCwgaW1wb3J0YW50ID0gZmFsc2UpID0+IHtcbiAgICBzZXRWaXNpYmxlKHNlbGVjdG9yT3JFbGVtZW50LCBmYWxzZSwgaW1wb3J0YW50KTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaG93ID0gKHNlbGVjdG9yT3JFbGVtZW50KSA9PiB7XG4gICAgc2V0VmlzaWJsZShzZWxlY3Rvck9yRWxlbWVudCwgdHJ1ZSk7XG59O1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENoZWNrb3V0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NoZWNrb3V0QWN0aW9uSGFuZGxlcic7XG5pbXBvcnQgeyBzZXRWaXNpYmxlIH0gZnJvbSAnLi4vSGVscGVyL0hpZGluZyc7XG5pbXBvcnQge1xuICAgIGdldEN1cnJlbnRQYXltZW50TWV0aG9kLFxuICAgIGlzU2F2ZWRDYXJkU2VsZWN0ZWQsIE9SREVSX0JVVFRPTl9TRUxFQ1RPUixcbiAgICBQYXltZW50TWV0aG9kc1xufSBmcm9tIFwiLi4vSGVscGVyL0NoZWNrb3V0TWV0aG9kU3RhdGVcIjtcblxuY2xhc3MgQ2hlY2tvdXRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIsIG1lc3NhZ2VzLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuZ2F0ZXdheSA9IGdhdGV3YXk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIgPSByZW5kZXJlcjtcbiAgICAgICAgdGhpcy5tZXNzYWdlcyA9IG1lc3NhZ2VzO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuXG4gICAgICAgIHRoaXMuc3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yID0gT1JERVJfQlVUVE9OX1NFTEVDVE9SO1xuXG4gICAgICAgIHRoaXMuYnV0dG9uQ2hhbmdlT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoZWwpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgICAgICAvLyBVbnNlbGVjdCBzYXZlZCBjYXJkLlxuICAgICAgICAvLyBXQyBzYXZlcyBmb3JtIHZhbHVlcywgc28gd2l0aCBvdXIgY3VycmVudCBVSSBpdCB3b3VsZCBiZSBhIGJpdCB3ZWlyZFxuICAgICAgICAvLyBpZiB0aGUgdXNlciBwYWlkIHdpdGggc2F2ZWQsIHRoZW4gYWZ0ZXIgc29tZSB0aW1lIHRyaWVzIHRvIHBheSBhZ2FpbixcbiAgICAgICAgLy8gYnV0IHdhbnRzIHRvIGVudGVyIGEgbmV3IGNhcmQsIGFuZCB0byBkbyB0aGF0IHRoZXkgaGF2ZSB0byBjaG9vc2Ug4oCcU2VsZWN0IHBheW1lbnTigJ0gaW4gdGhlIGxpc3QuXG4gICAgICAgIGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkJykudmFsKGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkIG9wdGlvbjpmaXJzdCcpLnZhbCgpKTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3VwZGF0ZWRfY2hlY2tvdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCBwYXltZW50X21ldGhvZF9zZWxlY3RlZCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50KS5vbignaG9zdGVkX2ZpZWxkc19sb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi5jYW5jZWxfd3JhcHBlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcikgIT09IG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKSAhPT0gbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIgKyAnPmRpdicpKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIgKyAnPmRpdicpLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYWN0aW9uSGFuZGxlciA9IG5ldyBDaGVja291dEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICAgICB0aGlzLnNwaW5uZXJcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsXG4gICAgICAgICAgICBhY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmJ1dHRvbkNoYW5nZU9ic2VydmVyLm9ic2VydmUoXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuc3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yKSxcbiAgICAgICAgICAgIHthdHRyaWJ1dGVzOiB0cnVlfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHVwZGF0ZVVpKCkge1xuICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IGdldEN1cnJlbnRQYXltZW50TWV0aG9kKCk7XG4gICAgICAgIGNvbnN0IGlzUGF5cGFsID0gY3VycmVudFBheW1lbnRNZXRob2QgPT09IFBheW1lbnRNZXRob2RzLlBBWVBBTDtcbiAgICAgICAgY29uc3QgaXNDYXJkID0gY3VycmVudFBheW1lbnRNZXRob2QgPT09IFBheW1lbnRNZXRob2RzLkNBUkRTO1xuICAgICAgICBjb25zdCBpc1NhdmVkQ2FyZCA9IGlzQ2FyZCAmJiBpc1NhdmVkQ2FyZFNlbGVjdGVkKCk7XG4gICAgICAgIGNvbnN0IGlzTm90T3VyR2F0ZXdheSA9ICFpc1BheXBhbCAmJiAhaXNDYXJkO1xuICAgICAgICBjb25zdCBpc0ZyZWVUcmlhbCA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5pc19mcmVlX3RyaWFsX2NhcnQ7XG4gICAgICAgIGNvbnN0IGhhc1ZhdWx0ZWRQYXlwYWwgPSBQYXlQYWxDb21tZXJjZUdhdGV3YXkudmF1bHRlZF9wYXlwYWxfZW1haWwgIT09ICcnO1xuXG4gICAgICAgIHNldFZpc2libGUodGhpcy5zdGFuZGFyZE9yZGVyQnV0dG9uU2VsZWN0b3IsICAoaXNQYXlwYWwgJiYgaXNGcmVlVHJpYWwgJiYgaGFzVmF1bHRlZFBheXBhbCkgfHwgaXNOb3RPdXJHYXRld2F5IHx8IGlzU2F2ZWRDYXJkLCB0cnVlKTtcbiAgICAgICAgc2V0VmlzaWJsZSgnLnBwY3AtdmF1bHRlZC1wYXlwYWwtZGV0YWlscycsIGlzUGF5cGFsKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsIGlzUGF5cGFsICYmICEoaXNGcmVlVHJpYWwgJiYgaGFzVmF1bHRlZFBheXBhbCkpO1xuICAgICAgICBzZXRWaXNpYmxlKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyLCBpc1BheXBhbCAmJiAhaXNGcmVlVHJpYWwpO1xuICAgICAgICBzZXRWaXNpYmxlKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsIGlzQ2FyZCAmJiAhaXNTYXZlZENhcmQpO1xuXG4gICAgICAgIGlmIChpc1BheXBhbCAmJiAhaXNGcmVlVHJpYWwpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNDYXJkKSB7XG4gICAgICAgICAgICBpZiAoaXNTYXZlZENhcmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgZmFsc2UpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEJvb3RzdGFwXG4iLCJleHBvcnQgY29uc3QgaXNDaGFuZ2VQYXltZW50UGFnZSA9ICgpID0+IHtcbiAgICBjb25zdCB1cmxQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpXG4gICAgcmV0dXJuIHVybFBhcmFtcy5oYXMoJ2NoYW5nZV9wYXltZW50X21ldGhvZCcpO1xufVxuIiwiaW1wb3J0IENoZWNrb3V0Qm9vdHN0YXAgZnJvbSAnLi9DaGVja291dEJvb3RzdGFwJ1xuaW1wb3J0IHtpc0NoYW5nZVBheW1lbnRQYWdlfSBmcm9tIFwiLi4vSGVscGVyL1N1YnNjcmlwdGlvbnNcIjtcblxuY2xhc3MgUGF5Tm93Qm9vdHN0cmFwIGV4dGVuZHMgQ2hlY2tvdXRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIsIG1lc3NhZ2VzLCBzcGlubmVyKSB7XG4gICAgICAgIHN1cGVyKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcywgc3Bpbm5lcilcbiAgICB9XG5cbiAgICB1cGRhdGVVaSgpIHtcbiAgICAgICAgaWYgKGlzQ2hhbmdlUGF5bWVudFBhZ2UoKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBzdXBlci51cGRhdGVVaSgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUGF5Tm93Qm9vdHN0cmFwO1xuIiwiY2xhc3MgUmVuZGVyZXIge1xuICAgIGNvbnN0cnVjdG9yKGNyZWRpdENhcmRSZW5kZXJlciwgZGVmYXVsdENvbmZpZywgb25TbWFydEJ1dHRvbkNsaWNrLCBvblNtYXJ0QnV0dG9uc0luaXQpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIgPSBjcmVkaXRDYXJkUmVuZGVyZXI7XG4gICAgICAgIHRoaXMub25TbWFydEJ1dHRvbkNsaWNrID0gb25TbWFydEJ1dHRvbkNsaWNrO1xuICAgICAgICB0aGlzLm9uU21hcnRCdXR0b25zSW5pdCA9IG9uU21hcnRCdXR0b25zSW5pdDtcbiAgICB9XG5cbiAgICByZW5kZXIod3JhcHBlciwgaG9zdGVkRmllbGRzV3JhcHBlciwgY29udGV4dENvbmZpZykge1xuXG4gICAgICAgIHRoaXMucmVuZGVyQnV0dG9ucyh3cmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIucmVuZGVyKGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpO1xuICAgIH1cblxuICAgIHJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZykge1xuICAgICAgICBpZiAoISBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpIHx8IHRoaXMuaXNBbHJlYWR5UmVuZGVyZWQod3JhcHBlcikgfHwgJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiBwYXlwYWwuQnV0dG9ucyApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0eWxlID0gd3JhcHBlciA9PT0gdGhpcy5kZWZhdWx0Q29uZmlnLmJ1dHRvbi53cmFwcGVyID8gdGhpcy5kZWZhdWx0Q29uZmlnLmJ1dHRvbi5zdHlsZSA6IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ubWluaV9jYXJ0X3N0eWxlO1xuICAgICAgICBwYXlwYWwuQnV0dG9ucyh7XG4gICAgICAgICAgICBzdHlsZSxcbiAgICAgICAgICAgIC4uLmNvbnRleHRDb25maWcsXG4gICAgICAgICAgICBvbkNsaWNrOiB0aGlzLm9uU21hcnRCdXR0b25DbGljayxcbiAgICAgICAgICAgIG9uSW5pdDogdGhpcy5vblNtYXJ0QnV0dG9uc0luaXQsXG4gICAgICAgIH0pLnJlbmRlcih3cmFwcGVyKTtcbiAgICB9XG5cbiAgICBpc0FscmVhZHlSZW5kZXJlZCh3cmFwcGVyKSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpLmhhc0NoaWxkTm9kZXMoKTtcbiAgICB9XG5cbiAgICBoaWRlQnV0dG9ucyhlbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGRvbUVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsZW1lbnQpO1xuICAgICAgICBpZiAoISBkb21FbGVtZW50ICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGRvbUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgc2hvd0J1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBkaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcygpIHtcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIuZGlzYWJsZUZpZWxkcygpO1xuICAgIH1cblxuICAgIGVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmVuYWJsZUZpZWxkcygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmVuZGVyZXI7XG4iLCJjb25zdCBkY2NJbnB1dEZhY3RvcnkgPSAob3JpZ2luYWwpID0+IHtcbiAgICBjb25zdCBzdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShvcmlnaW5hbCk7XG4gICAgY29uc3QgbmV3RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBuZXdFbGVtZW50LnNldEF0dHJpYnV0ZSgnaWQnLCBvcmlnaW5hbC5pZCk7XG4gICAgT2JqZWN0LnZhbHVlcyhzdHlsZXMpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgIGlmICghIHN0eWxlc1twcm9wXSB8fCAhIGlzTmFOKHByb3ApICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIG5ld0VsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkocHJvcCwnJyArIHN0eWxlc1twcm9wXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ld0VsZW1lbnQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRjY0lucHV0RmFjdG9yeTsiLCJpbXBvcnQgZGNjSW5wdXRGYWN0b3J5IGZyb20gXCIuLi9IZWxwZXIvRGNjSW5wdXRGYWN0b3J5XCI7XG5pbXBvcnQge3Nob3d9IGZyb20gXCIuLi9IZWxwZXIvSGlkaW5nXCI7XG5cbmNsYXNzIENyZWRpdENhcmRSZW5kZXJlciB7XG5cbiAgICBjb25zdHJ1Y3RvcihkZWZhdWx0Q29uZmlnLCBlcnJvckhhbmRsZXIsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgICAgIHRoaXMuY2FyZFZhbGlkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZm9ybVZhbGlkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlID0gbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIod3JhcHBlciwgY29udGV4dENvbmZpZykge1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcuY29udGV4dCAhPT0gJ2NoZWNrb3V0J1xuICAgICAgICAgICAgICAgICYmIHRoaXMuZGVmYXVsdENvbmZpZy5jb250ZXh0ICE9PSAncGF5LW5vdydcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIHx8IHdyYXBwZXIgPT09IG51bGxcbiAgICAgICAgICAgIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikgPT09IG51bGxcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdHlwZW9mIHBheXBhbC5Ib3N0ZWRGaWVsZHMgPT09ICd1bmRlZmluZWQnXG4gICAgICAgICAgICB8fCAhIHBheXBhbC5Ib3N0ZWRGaWVsZHMuaXNFbGlnaWJsZSgpXG4gICAgICAgICkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlckVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpO1xuICAgICAgICAgICAgd3JhcHBlckVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh3cmFwcGVyRWxlbWVudCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBidXR0b25TZWxlY3RvciA9IHdyYXBwZXIgKyAnIGJ1dHRvbic7XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS50ZWFyZG93bigpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmVycm9yKGBIb3N0ZWQgZmllbGRzIHRlYXJkb3duIGVycm9yOiAke2Vycn1gKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBnYXRlV2F5Qm94ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBheW1lbnRfYm94LnBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpO1xuICAgICAgICBjb25zdCBvbGREaXNwbGF5U3R5bGUgPSBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXk7XG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgICAgY29uc3QgaGlkZURjY0dhdGV3YXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1oaWRlLWRjYycpO1xuICAgICAgICBpZiAoaGlkZURjY0dhdGV3YXkpIHtcbiAgICAgICAgICAgIGhpZGVEY2NHYXRld2F5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaGlkZURjY0dhdGV3YXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlckZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpO1xuXG4gICAgICAgIGNvbnN0IHN0eWxlc1JhdyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNhcmROdW1iZXJGaWVsZCk7XG4gICAgICAgIGxldCBzdHlsZXMgPSB7fTtcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzdHlsZXNSYXcpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgICAgICBpZiAoISBzdHlsZXNSYXdbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHlsZXNbcHJvcF0gPSAnJyArIHN0eWxlc1Jhd1twcm9wXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlciA9IGRjY0lucHV0RmFjdG9yeShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBjYXJkTnVtYmVyRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZE51bWJlciwgY2FyZE51bWJlckZpZWxkKTtcblxuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5RmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5Jyk7XG4gICAgICAgIGNvbnN0IGNhcmRFeHBpcnkgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZEV4cGlyeUZpZWxkKTtcbiAgICAgICAgY2FyZEV4cGlyeUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRFeHBpcnksIGNhcmRFeHBpcnlGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZENvZGVGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKTtcbiAgICAgICAgY29uc3QgY2FyZENvZGUgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZENvZGVGaWVsZCk7XG4gICAgICAgIGNhcmRDb2RlRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZENvZGUsIGNhcmRDb2RlRmllbGQpO1xuXG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9IG9sZERpc3BsYXlTdHlsZTtcblxuICAgICAgICBjb25zdCBmb3JtV3JhcHBlciA9ICcucGF5bWVudF9ib3ggcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHRcbiAgICAgICAgICAgICYmIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0JylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5cGFsLkhvc3RlZEZpZWxkcy5yZW5kZXIoe1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IGNvbnRleHRDb25maWcuY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBzdHlsZXM6IHtcbiAgICAgICAgICAgICAgICAnaW5wdXQnOiBzdHlsZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICAgICAgICBudW1iZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jcmVkaXRfY2FyZF9udW1iZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjdnY6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jdnYsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBleHBpcmF0aW9uRGF0ZToge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLm1tX3l5LFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkudGhlbihob3N0ZWRGaWVsZHMgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJob3N0ZWRfZmllbGRzX2xvYWRlZFwiKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IGhvc3RlZEZpZWxkcztcblxuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdpbnB1dFN1Ym1pdFJlcXVlc3QnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ2NhcmRUeXBlQ2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCAhIGV2ZW50LmNhcmRzLmxlbmd0aCApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZENhcmRzID0gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMudmFsaWRfY2FyZHM7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSB2YWxpZENhcmRzLmluZGV4T2YoZXZlbnQuY2FyZHNbMF0udHlwZSkgIT09IC0xO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbigndmFsaWRpdHlDaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtVmFsaWQgPSBPYmplY3Qua2V5cyhldmVudC5maWVsZHMpLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmZpZWxkc1trZXldLmlzVmFsaWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZvcm1WYWxpZDtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHNob3coYnV0dG9uU2VsZWN0b3IpO1xuXG4gICAgICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5nZXRBdHRyaWJ1dGUoJ2RhdGEtcHBjcC1zdWJzY3JpYmVkJykgIT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGJ1dHRvblNlbGVjdG9yKS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgICAgICAgICBldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikuc2V0QXR0cmlidXRlKCdkYXRhLXBwY3Atc3Vic2NyaWJlZCcsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JykuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbGFiZWxbZm9yPXBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcl0nKS5jbGljaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICApXG4gICAgfVxuXG4gICAgZGlzYWJsZUZpZWxkcygpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zZXRBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnbnVtYmVyJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zZXRBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnY3Z2JyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zZXRBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnZXhwaXJhdGlvbkRhdGUnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGVuYWJsZUZpZWxkcygpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5yZW1vdmVBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnbnVtYmVyJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5yZW1vdmVBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnY3Z2JyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5yZW1vdmVBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnZXhwaXJhdGlvbkRhdGUnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9zdWJtaXQoY29udGV4dENvbmZpZykge1xuICAgICAgICB0aGlzLnNwaW5uZXIuYmxvY2soKTtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuY2xlYXIoKTtcblxuICAgICAgICBpZiAodGhpcy5mb3JtVmFsaWQgJiYgdGhpcy5jYXJkVmFsaWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHNhdmVfY2FyZCA9IHRoaXMuZGVmYXVsdENvbmZpZy5jYW5fc2F2ZV92YXVsdF90b2tlbiA/IHRydWUgOiBmYWxzZTtcbiAgICAgICAgICAgIGxldCB2YXVsdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykgP1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuY2hlY2tlZCA6IHNhdmVfY2FyZDtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlZmF1bHRDb25maWcuZW5mb3JjZV92YXVsdCkge1xuICAgICAgICAgICAgICAgIHZhdWx0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGNvbnRpbmdlbmN5ID0gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMuY29udGluZ2VuY3k7XG4gICAgICAgICAgICBjb25zdCBob3N0ZWRGaWVsZHNEYXRhID0ge1xuICAgICAgICAgICAgICAgIHZhdWx0OiB2YXVsdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChjb250aW5nZW5jeSAhPT0gJ05PXzNEX1NFQ1VSRScpIHtcbiAgICAgICAgICAgICAgICBob3N0ZWRGaWVsZHNEYXRhLmNvbnRpbmdlbmNpZXMgPSBbY29udGluZ2VuY3ldO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0Q29uZmlnLnBheWVyKSB7XG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jYXJkaG9sZGVyTmFtZSA9IHRoaXMuZGVmYXVsdENvbmZpZy5wYXllci5uYW1lLmdpdmVuX25hbWUgKyAnICcgKyB0aGlzLmRlZmF1bHRDb25maWcucGF5ZXIubmFtZS5zdXJuYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFob3N0ZWRGaWVsZHNEYXRhLmNhcmRob2xkZXJOYW1lKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlyc3ROYW1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JpbGxpbmdfZmlyc3RfbmFtZScpID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogJyc7XG4gICAgICAgICAgICAgICAgY29uc3QgbGFzdE5hbWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZ19sYXN0X25hbWUnKSA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2xhc3RfbmFtZScpLnZhbHVlIDogJyc7XG5cbiAgICAgICAgICAgICAgICBpZiAoIWZpcnN0TmFtZSB8fCAhbGFzdE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubWVzc2FnZSh0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuY2FyZGhvbGRlcl9uYW1lX3JlcXVpcmVkKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY2FyZGhvbGRlck5hbWUgPSBmaXJzdE5hbWUgKyAnICcgKyBsYXN0TmFtZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc3VibWl0KGhvc3RlZEZpZWxkc0RhdGEpLnRoZW4oKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLm9yZGVySUQgPSBwYXlsb2FkLm9yZGVySWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dENvbmZpZy5vbkFwcHJvdmUocGF5bG9hZCk7XG4gICAgICAgICAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuY2xlYXIoKTtcblxuICAgICAgICAgICAgICAgIGlmIChlcnIuZGV0YWlscykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5tZXNzYWdlKGVyci5kZXRhaWxzLm1hcChkID0+IGAke2QuaXNzdWV9ICR7ZC5kZXNjcmlwdGlvbn1gKS5qb2luKCc8YnIvPicpLCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gISB0aGlzLmNhcmRWYWxpZCA/IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jYXJkX25vdF9zdXBwb3J0ZWQgOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuZmllbGRzX25vdF92YWxpZDtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBDcmVkaXRDYXJkUmVuZGVyZXI7XG4iLCJjb25zdCBzdG9yYWdlS2V5ID0gJ3BwY3AtZGF0YS1jbGllbnQtaWQnO1xuXG5jb25zdCB2YWxpZGF0ZVRva2VuID0gKHRva2VuLCB1c2VyKSA9PiB7XG4gICAgaWYgKCEgdG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodG9rZW4udXNlciAhPT0gdXNlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgY29uc3QgaXNFeHBpcmVkID0gY3VycmVudFRpbWUgPj0gdG9rZW4uZXhwaXJhdGlvbiAqIDEwMDA7XG4gICAgcmV0dXJuICEgaXNFeHBpcmVkO1xufVxuXG5jb25zdCBzdG9yZWRUb2tlbkZvclVzZXIgPSAodXNlcikgPT4ge1xuICAgIGNvbnN0IHRva2VuID0gSlNPTi5wYXJzZShzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHN0b3JhZ2VLZXkpKTtcbiAgICBpZiAodmFsaWRhdGVUb2tlbih0b2tlbiwgdXNlcikpIHtcbiAgICAgICAgcmV0dXJuIHRva2VuLnRva2VuO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuY29uc3Qgc3RvcmVUb2tlbiA9ICh0b2tlbikgPT4ge1xuICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oc3RvcmFnZUtleSwgSlNPTi5zdHJpbmdpZnkodG9rZW4pKTtcbn1cblxuY29uc3QgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciA9IChzY3JpcHQsIGNvbmZpZykgPT4ge1xuICAgIGZldGNoKGNvbmZpZy5lbmRwb2ludCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgbm9uY2U6IGNvbmZpZy5ub25jZVxuICAgICAgICB9KVxuICAgIH0pLnRoZW4oKHJlcyk9PntcbiAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgY29uc3QgaXNWYWxpZCA9IHZhbGlkYXRlVG9rZW4oZGF0YSwgY29uZmlnLnVzZXIpO1xuICAgICAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdG9yZVRva2VuKGRhdGEpO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdkYXRhLWNsaWVudC10b2tlbicsIGRhdGEudG9rZW4pO1xuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChzY3JpcHQpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyO1xuIiwiY2xhc3MgTWVzc2FnZVJlbmRlcmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQ6IHRoaXMuY29uZmlnLmFtb3VudCxcbiAgICAgICAgICAgIHBsYWNlbWVudDogdGhpcy5jb25maWcucGxhY2VtZW50LFxuICAgICAgICAgICAgc3R5bGU6IHRoaXMuY29uZmlnLnN0eWxlXG4gICAgICAgIH0pLnJlbmRlcih0aGlzLmNvbmZpZy53cmFwcGVyKTtcbiAgICB9XG5cbiAgICByZW5kZXJXaXRoQW1vdW50KGFtb3VudCkge1xuXG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5ld1dyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgbmV3V3JhcHBlci5zZXRBdHRyaWJ1dGUoJ2lkJywgdGhpcy5jb25maWcud3JhcHBlci5yZXBsYWNlKCcjJywgJycpKTtcblxuICAgICAgICBjb25zdCBzaWJsaW5nID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5uZXh0U2libGluZztcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpO1xuICAgICAgICBzaWJsaW5nLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKG5ld1dyYXBwZXIsIHNpYmxpbmcpO1xuICAgICAgICBwYXlwYWwuTWVzc2FnZXMoe1xuICAgICAgICAgICAgYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcblxuICAgICAgICBpZiAodHlwZW9mIHBheXBhbC5NZXNzYWdlcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHRoaXMuY29uZmlnLndyYXBwZXIgPT09ICd1bmRlZmluZWQnICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBNZXNzYWdlUmVuZGVyZXI7IiwiY2xhc3MgU3Bpbm5lciB7XG5cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQgPSAnZm9ybS53b29jb21tZXJjZS1jaGVja291dCcpIHtcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gICAgfVxuXG4gICAgc2V0VGFyZ2V0KHRhcmdldCkge1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICB9XG5cbiAgICBibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkuYmxvY2soe1xuICAgICAgICAgICAgbWVzc2FnZTogbnVsbCxcbiAgICAgICAgICAgIG92ZXJsYXlDU1M6IHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAnI2ZmZicsXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC42XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVuYmxvY2soKSB7XG5cbiAgICAgICAgalF1ZXJ5KCB0aGlzLnRhcmdldCApLnVuYmxvY2soKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNwaW5uZXI7XG4iLCJpbXBvcnQge1BheW1lbnRNZXRob2RzfSBmcm9tIFwiLi4vSGVscGVyL0NoZWNrb3V0TWV0aG9kU3RhdGVcIjtcbmltcG9ydCBlcnJvckhhbmRsZXIgZnJvbSBcIi4uL0Vycm9ySGFuZGxlclwiO1xuXG5jbGFzcyBGcmVlVHJpYWxIYW5kbGVyIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBzcGlubmVyLFxuICAgICAgICBlcnJvckhhbmRsZXJcbiAgICApIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgIH1cblxuICAgIGhhbmRsZSgpXG4gICAge1xuICAgICAgICB0aGlzLnNwaW5uZXIuYmxvY2soKTtcblxuICAgICAgICBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LnZhdWx0X3BheXBhbC5lbmRwb2ludCwge1xuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXgudmF1bHRfcGF5cGFsLm5vbmNlLFxuICAgICAgICAgICAgICAgIHJldHVybl91cmw6IGxvY2F0aW9uLmhyZWZcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KS50aGVuKHJlcyA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbihkYXRhID0+IHtcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGRhdGEpO1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGRhdGEuZGF0YS5hcHByb3ZlX2xpbms7XG4gICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBGcmVlVHJpYWxIYW5kbGVyO1xuIiwiaW1wb3J0IE1pbmlDYXJ0Qm9vdHN0YXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcCc7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1NpbmdsZVByb2R1Y3RCb290c3RhcCc7XG5pbXBvcnQgQ2FydEJvb3RzdHJhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAnO1xuaW1wb3J0IENoZWNrb3V0Qm9vdHN0YXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2hlY2tvdXRCb290c3RhcCc7XG5pbXBvcnQgUGF5Tm93Qm9vdHN0cmFwIGZyb20gXCIuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9QYXlOb3dCb290c3RyYXBcIjtcbmltcG9ydCBSZW5kZXJlciBmcm9tICcuL21vZHVsZXMvUmVuZGVyZXIvUmVuZGVyZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuL21vZHVsZXMvRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDcmVkaXRDYXJkUmVuZGVyZXIgZnJvbSBcIi4vbW9kdWxlcy9SZW5kZXJlci9DcmVkaXRDYXJkUmVuZGVyZXJcIjtcbmltcG9ydCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyIGZyb20gXCIuL21vZHVsZXMvRGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlclwiO1xuaW1wb3J0IE1lc3NhZ2VSZW5kZXJlciBmcm9tIFwiLi9tb2R1bGVzL1JlbmRlcmVyL01lc3NhZ2VSZW5kZXJlclwiO1xuaW1wb3J0IFNwaW5uZXIgZnJvbSBcIi4vbW9kdWxlcy9IZWxwZXIvU3Bpbm5lclwiO1xuaW1wb3J0IHtcbiAgICBnZXRDdXJyZW50UGF5bWVudE1ldGhvZCxcbiAgICBPUkRFUl9CVVRUT05fU0VMRUNUT1IsXG4gICAgUGF5bWVudE1ldGhvZHNcbn0gZnJvbSBcIi4vbW9kdWxlcy9IZWxwZXIvQ2hlY2tvdXRNZXRob2RTdGF0ZVwiO1xuaW1wb3J0IHtoaWRlLCBzZXRWaXNpYmxlfSBmcm9tIFwiLi9tb2R1bGVzL0hlbHBlci9IaWRpbmdcIjtcbmltcG9ydCB7aXNDaGFuZ2VQYXltZW50UGFnZX0gZnJvbSBcIi4vbW9kdWxlcy9IZWxwZXIvU3Vic2NyaXB0aW9uc1wiO1xuaW1wb3J0IEZyZWVUcmlhbEhhbmRsZXIgZnJvbSBcIi4vbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0ZyZWVUcmlhbEhhbmRsZXJcIjtcblxuY29uc3QgYnV0dG9uc1NwaW5uZXIgPSBuZXcgU3Bpbm5lcignLnBwYy1idXR0b24td3JhcHBlcicpO1xuY29uc3QgY2FyZHNTcGlubmVyID0gbmV3IFNwaW5uZXIoJyNwcGNwLWhvc3RlZC1maWVsZHMnKTtcblxuY29uc3QgYm9vdHN0cmFwID0gKCkgPT4ge1xuICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IG5ldyBFcnJvckhhbmRsZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKTtcbiAgICBjb25zdCBzcGlubmVyID0gbmV3IFNwaW5uZXIoKTtcbiAgICBjb25zdCBjcmVkaXRDYXJkUmVuZGVyZXIgPSBuZXcgQ3JlZGl0Q2FyZFJlbmRlcmVyKFBheVBhbENvbW1lcmNlR2F0ZXdheSwgZXJyb3JIYW5kbGVyLCBzcGlubmVyKTtcblxuICAgIGNvbnN0IGZyZWVUcmlhbEhhbmRsZXIgPSBuZXcgRnJlZVRyaWFsSGFuZGxlcihQYXlQYWxDb21tZXJjZUdhdGV3YXksIHNwaW5uZXIsIGVycm9ySGFuZGxlcik7XG5cbiAgICBjb25zdCBvblNtYXJ0QnV0dG9uQ2xpY2sgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICB3aW5kb3cucHBjcEZ1bmRpbmdTb3VyY2UgPSBkYXRhLmZ1bmRpbmdTb3VyY2U7XG5cbiAgICAgICAgY29uc3QgZm9ybSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0ud29vY29tbWVyY2UtY2hlY2tvdXQnKTtcbiAgICAgICAgaWYgKGZvcm0pIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BwY3AtZnVuZGluZy1zb3VyY2UtZm9ybS1pbnB1dCcpLnJlbW92ZSgpO1xuICAgICAgICAgICAgZm9ybS5pbnNlcnRBZGphY2VudEhUTUwoXG4gICAgICAgICAgICAgICAgJ2JlZm9yZWVuZCcsXG4gICAgICAgICAgICAgICAgYDxpbnB1dCB0eXBlPVwiaGlkZGVuXCIgbmFtZT1cInBwY3AtZnVuZGluZy1zb3VyY2VcIiB2YWx1ZT1cIiR7ZGF0YS5mdW5kaW5nU291cmNlfVwiIGlkPVwicHBjcC1mdW5kaW5nLXNvdXJjZS1mb3JtLWlucHV0XCI+YFxuICAgICAgICAgICAgKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNGcmVlVHJpYWwgPSBQYXlQYWxDb21tZXJjZUdhdGV3YXkuaXNfZnJlZV90cmlhbF9jYXJ0O1xuICAgICAgICBpZiAoaXNGcmVlVHJpYWwgJiYgZGF0YS5mdW5kaW5nU291cmNlICE9PSAnY2FyZCcpIHtcbiAgICAgICAgICAgIGZyZWVUcmlhbEhhbmRsZXIuaGFuZGxlKCk7XG4gICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5yZWplY3QoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgY29uc3Qgb25TbWFydEJ1dHRvbnNJbml0ID0gKCkgPT4ge1xuICAgICAgICBidXR0b25zU3Bpbm5lci51bmJsb2NrKCk7XG4gICAgfTtcbiAgICBjb25zdCByZW5kZXJlciA9IG5ldyBSZW5kZXJlcihjcmVkaXRDYXJkUmVuZGVyZXIsIFBheVBhbENvbW1lcmNlR2F0ZXdheSwgb25TbWFydEJ1dHRvbkNsaWNrLCBvblNtYXJ0QnV0dG9uc0luaXQpO1xuICAgIGNvbnN0IG1lc3NhZ2VSZW5kZXJlciA9IG5ldyBNZXNzYWdlUmVuZGVyZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1lc3NhZ2VzKTtcbiAgICBjb25zdCBjb250ZXh0ID0gUGF5UGFsQ29tbWVyY2VHYXRld2F5LmNvbnRleHQ7XG4gICAgaWYgKGNvbnRleHQgPT09ICdtaW5pLWNhcnQnIHx8IGNvbnRleHQgPT09ICdwcm9kdWN0Jykge1xuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQgPT09ICcxJykge1xuICAgICAgICAgICAgY29uc3QgbWluaUNhcnRCb290c3RyYXAgPSBuZXcgTWluaUNhcnRCb290c3RhcChcbiAgICAgICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICAgICAgcmVuZGVyZXJcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIG1pbmlDYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncHJvZHVjdCcgJiYgUGF5UGFsQ29tbWVyY2VHYXRld2F5LnNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgIGNvbnN0IHNpbmdsZVByb2R1Y3RCb290c3RyYXAgPSBuZXcgU2luZ2xlUHJvZHVjdEJvb3RzdGFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICk7XG5cbiAgICAgICAgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdjYXJ0Jykge1xuICAgICAgICBjb25zdCBjYXJ0Qm9vdHN0cmFwID0gbmV3IENhcnRCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBjYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBjb25zdCBjaGVja291dEJvb3RzdGFwID0gbmV3IENoZWNrb3V0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcblxuICAgICAgICBjaGVja291dEJvb3RzdGFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ3BheS1ub3cnICkge1xuICAgICAgICBjb25zdCBwYXlOb3dCb290c3RyYXAgPSBuZXcgUGF5Tm93Qm9vdHN0cmFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICAgICBzcGlubmVyXG4gICAgICAgICk7XG4gICAgICAgIHBheU5vd0Jvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgIT09ICdjaGVja291dCcpIHtcbiAgICAgICAgbWVzc2FnZVJlbmRlcmVyLnJlbmRlcigpO1xuICAgIH1cbn07XG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICdET01Db250ZW50TG9hZGVkJyxcbiAgICAoKSA9PiB7XG4gICAgICAgIGlmICghdHlwZW9mIChQYXlQYWxDb21tZXJjZUdhdGV3YXkpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdQYXlQYWwgYnV0dG9uIGNvdWxkIG5vdCBiZSBjb25maWd1cmVkLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmNvbnRleHQgIT09ICdjaGVja291dCdcbiAgICAgICAgICAgICYmIFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZC51c2VyID09PSAwXG4gICAgICAgICAgICAmJiBQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQuaGFzX3N1YnNjcmlwdGlvbnNcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb21ldGltZXMgUGF5UGFsIHNjcmlwdCB0YWtlcyBsb25nIHRpbWUgdG8gbG9hZCxcbiAgICAgICAgLy8gc28gd2UgYWRkaXRpb25hbGx5IGhpZGUgdGhlIHN0YW5kYXJkIG9yZGVyIGJ1dHRvbiBoZXJlIHRvIGF2b2lkIGZhaWxlZCBvcmRlcnMuXG4gICAgICAgIC8vIE5vcm1hbGx5IGl0IGlzIGhpZGRlbiBsYXRlciBhZnRlciB0aGUgc2NyaXB0IGxvYWQuXG4gICAgICAgIGNvbnN0IGhpZGVPcmRlckJ1dHRvbklmUHBjcEdhdGV3YXkgPSAoKSA9PiB7XG4gICAgICAgICAgICAvLyBvbmx5IGluIGNoZWNrb3V0IGFuZCBwYXkgbm93IHBhZ2UsIG90aGVyd2lzZSBpdCBtYXkgYnJlYWsgdGhpbmdzIChlLmcuIHBheW1lbnQgdmlhIHByb2R1Y3QgcGFnZSksXG4gICAgICAgICAgICAvLyBhbmQgYWxzbyB0aGUgbG9hZGluZyBzcGlubmVyIG1heSBsb29rIHdlaXJkIG9uIG90aGVyIHBhZ2VzXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgIVsnY2hlY2tvdXQnLCAncGF5LW5vdyddLmluY2x1ZGVzKFBheVBhbENvbW1lcmNlR2F0ZXdheS5jb250ZXh0KVxuICAgICAgICAgICAgICAgIHx8IGlzQ2hhbmdlUGF5bWVudFBhZ2UoKVxuICAgICAgICAgICAgICAgIHx8IChQYXlQYWxDb21tZXJjZUdhdGV3YXkuaXNfZnJlZV90cmlhbF9jYXJ0ICYmIFBheVBhbENvbW1lcmNlR2F0ZXdheS52YXVsdGVkX3BheXBhbF9lbWFpbCAhPT0gJycpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0gZ2V0Q3VycmVudFBheW1lbnRNZXRob2QoKTtcbiAgICAgICAgICAgIGNvbnN0IGlzUGF5cGFsID0gY3VycmVudFBheW1lbnRNZXRob2QgPT09IFBheW1lbnRNZXRob2RzLlBBWVBBTDtcbiAgICAgICAgICAgIGNvbnN0IGlzQ2FyZHMgPSBjdXJyZW50UGF5bWVudE1ldGhvZCA9PT0gUGF5bWVudE1ldGhvZHMuQ0FSRFM7XG5cbiAgICAgICAgICAgIHNldFZpc2libGUoT1JERVJfQlVUVE9OX1NFTEVDVE9SLCAhaXNQYXlwYWwgJiYgIWlzQ2FyZHMsIHRydWUpO1xuXG4gICAgICAgICAgICBpZiAoaXNQYXlwYWwpIHtcbiAgICAgICAgICAgICAgICAvLyBzdG9wcGVkIGFmdGVyIHRoZSBmaXJzdCByZW5kZXJpbmcgb2YgdGhlIGJ1dHRvbnMsIGluIG9uSW5pdFxuICAgICAgICAgICAgICAgIGJ1dHRvbnNTcGlubmVyLmJsb2NrKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJ1dHRvbnNTcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzQ2FyZHMpIHtcbiAgICAgICAgICAgICAgICBjYXJkc1NwaW5uZXIuYmxvY2soKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FyZHNTcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudCkub24oJ2hvc3RlZF9maWVsZHNfbG9hZGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgY2FyZHNTcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IGJvb3RzdHJhcHBlZCA9IGZhbHNlO1xuXG4gICAgICAgIGhpZGVPcmRlckJ1dHRvbklmUHBjcEdhdGV3YXkoKTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3VwZGF0ZWRfY2hlY2tvdXQgcGF5bWVudF9tZXRob2Rfc2VsZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoYm9vdHN0cmFwcGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBoaWRlT3JkZXJCdXR0b25JZlBwY3BHYXRld2F5KCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICBzY3JpcHQuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgYm9vdHN0cmFwcGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgYm9vdHN0cmFwKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdzcmMnLCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuYnV0dG9uLnVybCk7XG4gICAgICAgIE9iamVjdC5lbnRyaWVzKFBheVBhbENvbW1lcmNlR2F0ZXdheS5zY3JpcHRfYXR0cmlidXRlcykuZm9yRWFjaChcbiAgICAgICAgICAgIChrZXlWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoa2V5VmFsdWVbMF0sIGtleVZhbHVlWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkLnNldF9hdHRyaWJ1dGUpIHtcbiAgICAgICAgICAgIGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIoc2NyaXB0LCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoc2NyaXB0KTtcbiAgICB9LFxuKTtcbiJdLCJuYW1lcyI6WyJFcnJvckhhbmRsZXIiLCJjb25zdHJ1Y3RvciIsImdlbmVyaWNFcnJvclRleHQiLCJ3cmFwcGVyIiwiZG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwibWVzc2FnZXNMaXN0IiwiZ2VuZXJpY0Vycm9yIiwiY2xhc3NMaXN0IiwiY29udGFpbnMiLCJjbGVhciIsIm1lc3NhZ2UiLCJhcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQiLCJlcnJvck1lc3NhZ2VFbGVtZW50IiwicHJlcGFyZU1lc3NhZ2VzTGlzdCIsInJlcGxhY2VXaXRoIiwidGV4dCIsInBlcnNpc3QiLCJTdHJpbmciLCJsZW5ndGgiLCJFcnJvciIsImFkZCIsInJlbW92ZSIsIm1lc3NhZ2VOb2RlIiwicHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0iLCJhcHBlbmRDaGlsZCIsImpRdWVyeSIsInNjcm9sbF90b19ub3RpY2VzIiwiY3JlYXRlRWxlbWVudCIsInNldEF0dHJpYnV0ZSIsImxpIiwiaW5uZXJIVE1MIiwic2FuaXRpemUiLCJ0ZXh0YXJlYSIsInZhbHVlIiwicmVwbGFjZSIsIm9uQXBwcm92ZSIsImNvbnRleHQiLCJlcnJvckhhbmRsZXIiLCJkYXRhIiwiYWN0aW9ucyIsImZldGNoIiwiY29uZmlnIiwiYWpheCIsImFwcHJvdmVfb3JkZXIiLCJlbmRwb2ludCIsIm1ldGhvZCIsImJvZHkiLCJKU09OIiwic3RyaW5naWZ5Iiwibm9uY2UiLCJvcmRlcl9pZCIsIm9yZGVySUQiLCJmdW5kaW5nX3NvdXJjZSIsIndpbmRvdyIsInBwY3BGdW5kaW5nU291cmNlIiwidGhlbiIsInJlcyIsImpzb24iLCJzdWNjZXNzIiwicmVzdGFydCIsImNhdGNoIiwiZXJyIiwibG9jYXRpb24iLCJocmVmIiwicmVkaXJlY3QiLCJwYXllckRhdGEiLCJwYXllciIsIlBheVBhbENvbW1lcmNlR2F0ZXdheSIsInBob25lIiwicGhvbmVfdHlwZSIsInBob25lX251bWJlciIsIm5hdGlvbmFsX251bWJlciIsImVtYWlsX2FkZHJlc3MiLCJuYW1lIiwic3VybmFtZSIsImdpdmVuX25hbWUiLCJhZGRyZXNzIiwiY291bnRyeV9jb2RlIiwiYWRkcmVzc19saW5lXzEiLCJhZGRyZXNzX2xpbmVfMiIsImFkbWluX2FyZWFfMSIsImFkbWluX2FyZWFfMiIsInBvc3RhbF9jb2RlIiwiUGF5bWVudE1ldGhvZHMiLCJQQVlQQUwiLCJDQVJEUyIsIk9SREVSX0JVVFRPTl9TRUxFQ1RPUiIsImdldEN1cnJlbnRQYXltZW50TWV0aG9kIiwiZWwiLCJpc1NhdmVkQ2FyZFNlbGVjdGVkIiwic2F2ZWRDYXJkTGlzdCIsIkNhcnRBY3Rpb25IYW5kbGVyIiwiY29uZmlndXJhdGlvbiIsImNyZWF0ZU9yZGVyIiwiYm5Db2RlIiwiYm5fY29kZXMiLCJjcmVhdGVfb3JkZXIiLCJwdXJjaGFzZV91bml0cyIsInBheW1lbnRfbWV0aG9kIiwiYm5fY29kZSIsImNvbnNvbGUiLCJlcnJvciIsImlkIiwib25FcnJvciIsIk1pbmlDYXJ0Qm9vdHN0YXAiLCJnYXRld2F5IiwicmVuZGVyZXIiLCJhY3Rpb25IYW5kbGVyIiwiaW5pdCIsImxhYmVscyIsImdlbmVyaWMiLCJyZW5kZXIiLCJvbiIsInNob3VsZFJlbmRlciIsImJ1dHRvbiIsIm1pbmlfY2FydF93cmFwcGVyIiwiaG9zdGVkX2ZpZWxkcyIsIlByb2R1Y3QiLCJVcGRhdGVDYXJ0IiwidXBkYXRlIiwib25SZXNvbHZlIiwicHJvZHVjdHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlc3VsdCIsInJlc29sdmVkIiwiQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIiwiZWxlbWVudCIsInNob3dDYWxsYmFjayIsImhpZGVDYWxsYmFjayIsIm9ic2VydmVyIiwiYXR0cmlidXRlcyIsImNhbGxiYWNrIiwiTXV0YXRpb25PYnNlcnZlciIsIm9ic2VydmUiLCJkaXNjb25uZWN0IiwicXVhbnRpdHkiLCJ2YXJpYXRpb25zIiwiU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIiLCJ1cGRhdGVDYXJ0Iiwic2hvd0J1dHRvbkNhbGxiYWNrIiwiaGlkZUJ1dHRvbkNhbGxiYWNrIiwiZm9ybUVsZW1lbnQiLCJoYXNWYXJpYXRpb25zIiwiZ2V0UHJvZHVjdHMiLCJpc0dyb3VwZWRQcm9kdWN0IiwicXR5IiwicXVlcnlTZWxlY3RvckFsbCIsImZvckVhY2giLCJlbGVtZW50TmFtZSIsImdldEF0dHJpYnV0ZSIsIm1hdGNoIiwicGFyc2VJbnQiLCJwdXNoIiwicHJvbWlzZSIsIm1hcCIsIlNpbmdsZVByb2R1Y3RCb290c3RhcCIsIm1lc3NhZ2VzIiwiaGFuZGxlQ2hhbmdlIiwiaGlkZUJ1dHRvbnMiLCJhZGRFdmVudExpc3RlbmVyIiwiYmluZCIsInByaWNlQW1vdW50SXNaZXJvIiwicHJpY2VUZXh0IiwiaW5uZXJUZXh0IiwiYW1vdW50IiwicGFyc2VGbG9hdCIsImNoYW5nZV9jYXJ0Iiwic2hvd0J1dHRvbnMiLCJyZW5kZXJXaXRoQW1vdW50IiwiQ2FydEJvb3RzdHJhcCIsInNwaW5uZXIiLCJibG9jayIsInVuYmxvY2siLCJjb2RlIiwiY2xpY2siLCJDaGVja291dEFjdGlvbkhhbmRsZXIiLCJmb3JtU2VsZWN0b3IiLCJmb3JtVmFsdWVzIiwic2VyaWFsaXplIiwiY3JlYXRlYWNjb3VudCIsImlzIiwiZm9ybSIsImRvbVBhcnNlciIsIkRPTVBhcnNlciIsInBhcnNlRnJvbVN0cmluZyIsImRldGFpbHMiLCJkIiwiaXNzdWUiLCJkZXNjcmlwdGlvbiIsImpvaW4iLCJpbnB1dCIsImN1c3RvbV9pZCIsImFwcGVuZCIsIm9uQ2FuY2VsIiwiZ2V0RWxlbWVudCIsInNlbGVjdG9yT3JFbGVtZW50IiwiaXNWaXNpYmxlIiwib2Zmc2V0V2lkdGgiLCJvZmZzZXRIZWlnaHQiLCJnZXRDbGllbnRSZWN0cyIsInNldFZpc2libGUiLCJzaG93IiwiaW1wb3J0YW50IiwiY3VycmVudFZhbHVlIiwic3R5bGUiLCJnZXRQcm9wZXJ0eVZhbHVlIiwic2V0UHJvcGVydHkiLCJyZW1vdmVQcm9wZXJ0eSIsImhpZGUiLCJDaGVja291dEJvb3RzdGFwIiwic3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yIiwiYnV0dG9uQ2hhbmdlT2JzZXJ2ZXIiLCJ1cGRhdGVVaSIsInZhbCIsImNhbmNlbF93cmFwcGVyIiwiY3VycmVudFBheW1lbnRNZXRob2QiLCJpc1BheXBhbCIsImlzQ2FyZCIsImlzU2F2ZWRDYXJkIiwiaXNOb3RPdXJHYXRld2F5IiwiaXNGcmVlVHJpYWwiLCJpc19mcmVlX3RyaWFsX2NhcnQiLCJoYXNWYXVsdGVkUGF5cGFsIiwidmF1bHRlZF9wYXlwYWxfZW1haWwiLCJkaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcyIsImVuYWJsZUNyZWRpdENhcmRGaWVsZHMiLCJhZGRDbGFzcyIsImF0dHIiLCJyZW1vdmVDbGFzcyIsImlzQ2hhbmdlUGF5bWVudFBhZ2UiLCJ1cmxQYXJhbXMiLCJVUkxTZWFyY2hQYXJhbXMiLCJzZWFyY2giLCJoYXMiLCJQYXlOb3dCb290c3RyYXAiLCJSZW5kZXJlciIsImNyZWRpdENhcmRSZW5kZXJlciIsImRlZmF1bHRDb25maWciLCJvblNtYXJ0QnV0dG9uQ2xpY2siLCJvblNtYXJ0QnV0dG9uc0luaXQiLCJob3N0ZWRGaWVsZHNXcmFwcGVyIiwiY29udGV4dENvbmZpZyIsInJlbmRlckJ1dHRvbnMiLCJpc0FscmVhZHlSZW5kZXJlZCIsInBheXBhbCIsIkJ1dHRvbnMiLCJtaW5pX2NhcnRfc3R5bGUiLCJvbkNsaWNrIiwib25Jbml0IiwiaGFzQ2hpbGROb2RlcyIsImRvbUVsZW1lbnQiLCJkaXNwbGF5IiwiZGlzYWJsZUZpZWxkcyIsImVuYWJsZUZpZWxkcyIsImRjY0lucHV0RmFjdG9yeSIsIm9yaWdpbmFsIiwic3R5bGVzIiwiZ2V0Q29tcHV0ZWRTdHlsZSIsIm5ld0VsZW1lbnQiLCJPYmplY3QiLCJ2YWx1ZXMiLCJwcm9wIiwiaXNOYU4iLCJDcmVkaXRDYXJkUmVuZGVyZXIiLCJjYXJkVmFsaWQiLCJmb3JtVmFsaWQiLCJjdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UiLCJIb3N0ZWRGaWVsZHMiLCJpc0VsaWdpYmxlIiwid3JhcHBlckVsZW1lbnQiLCJwYXJlbnROb2RlIiwicmVtb3ZlQ2hpbGQiLCJidXR0b25TZWxlY3RvciIsInRlYXJkb3duIiwiZ2F0ZVdheUJveCIsIm9sZERpc3BsYXlTdHlsZSIsImhpZGVEY2NHYXRld2F5IiwiY2FyZE51bWJlckZpZWxkIiwic3R5bGVzUmF3IiwiY2FyZE51bWJlciIsInJlcGxhY2VDaGlsZCIsImNhcmRFeHBpcnlGaWVsZCIsImNhcmRFeHBpcnkiLCJjYXJkQ29kZUZpZWxkIiwiY2FyZENvZGUiLCJmb3JtV3JhcHBlciIsImVuZm9yY2VfdmF1bHQiLCJjaGVja2VkIiwiZmllbGRzIiwibnVtYmVyIiwic2VsZWN0b3IiLCJwbGFjZWhvbGRlciIsImNyZWRpdF9jYXJkX251bWJlciIsImN2diIsImV4cGlyYXRpb25EYXRlIiwibW1feXkiLCJob3N0ZWRGaWVsZHMiLCJkaXNwYXRjaEV2ZW50IiwiQ3VzdG9tRXZlbnQiLCJfc3VibWl0IiwiZXZlbnQiLCJjYXJkcyIsInZhbGlkQ2FyZHMiLCJ2YWxpZF9jYXJkcyIsImluZGV4T2YiLCJ0eXBlIiwia2V5cyIsImV2ZXJ5Iiwia2V5IiwiaXNWYWxpZCIsInByZXZlbnREZWZhdWx0IiwiZmllbGQiLCJhdHRyaWJ1dGUiLCJyZW1vdmVBdHRyaWJ1dGUiLCJzYXZlX2NhcmQiLCJjYW5fc2F2ZV92YXVsdF90b2tlbiIsInZhdWx0IiwiZ2V0RWxlbWVudEJ5SWQiLCJjb250aW5nZW5jeSIsImhvc3RlZEZpZWxkc0RhdGEiLCJjb250aW5nZW5jaWVzIiwiY2FyZGhvbGRlck5hbWUiLCJmaXJzdE5hbWUiLCJsYXN0TmFtZSIsImNhcmRob2xkZXJfbmFtZV9yZXF1aXJlZCIsInN1Ym1pdCIsInBheWxvYWQiLCJvcmRlcklkIiwiY2FyZF9ub3Rfc3VwcG9ydGVkIiwiZmllbGRzX25vdF92YWxpZCIsInN0b3JhZ2VLZXkiLCJ2YWxpZGF0ZVRva2VuIiwidG9rZW4iLCJ1c2VyIiwiY3VycmVudFRpbWUiLCJEYXRlIiwiZ2V0VGltZSIsImlzRXhwaXJlZCIsImV4cGlyYXRpb24iLCJzdG9yZWRUb2tlbkZvclVzZXIiLCJwYXJzZSIsInNlc3Npb25TdG9yYWdlIiwiZ2V0SXRlbSIsInN0b3JlVG9rZW4iLCJzZXRJdGVtIiwiZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciIsInNjcmlwdCIsIk1lc3NhZ2VSZW5kZXJlciIsIk1lc3NhZ2VzIiwicGxhY2VtZW50IiwibmV3V3JhcHBlciIsInNpYmxpbmciLCJuZXh0U2libGluZyIsInBhcmVudEVsZW1lbnQiLCJpbnNlcnRCZWZvcmUiLCJTcGlubmVyIiwidGFyZ2V0Iiwic2V0VGFyZ2V0Iiwib3ZlcmxheUNTUyIsImJhY2tncm91bmQiLCJvcGFjaXR5IiwiRnJlZVRyaWFsSGFuZGxlciIsImhhbmRsZSIsInZhdWx0X3BheXBhbCIsInJldHVybl91cmwiLCJhcHByb3ZlX2xpbmsiLCJidXR0b25zU3Bpbm5lciIsImNhcmRzU3Bpbm5lciIsImJvb3RzdHJhcCIsImZyZWVUcmlhbEhhbmRsZXIiLCJmdW5kaW5nU291cmNlIiwiaW5zZXJ0QWRqYWNlbnRIVE1MIiwibWVzc2FnZVJlbmRlcmVyIiwibWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCIsIm1pbmlDYXJ0Qm9vdHN0cmFwIiwic2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkIiwic2luZ2xlUHJvZHVjdEJvb3RzdHJhcCIsImNhcnRCb290c3RyYXAiLCJjaGVja291dEJvb3RzdGFwIiwicGF5Tm93Qm9vdHN0cmFwIiwiZGF0YV9jbGllbnRfaWQiLCJoYXNfc3Vic2NyaXB0aW9ucyIsImhpZGVPcmRlckJ1dHRvbklmUHBjcEdhdGV3YXkiLCJpbmNsdWRlcyIsImlzQ2FyZHMiLCJib290c3RyYXBwZWQiLCJ1cmwiLCJlbnRyaWVzIiwic2NyaXB0X2F0dHJpYnV0ZXMiLCJrZXlWYWx1ZSIsInNldF9hdHRyaWJ1dGUiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///536\n")}},__webpack_exports__={};__webpack_modules__[536]()})();
|
1 |
+
(()=>{"use strict";var __webpack_modules__={536:()=>{eval("\n;// CONCATENATED MODULE: ./resources/js/modules/ErrorHandler.js\nclass ErrorHandler {\n constructor(genericErrorText) {\n this.genericErrorText = genericErrorText;\n this.wrapper = document.querySelector('.woocommerce-notices-wrapper');\n this.messagesList = document.querySelector('ul.woocommerce-error');\n }\n\n genericError() {\n if (this.wrapper.classList.contains('ppcp-persist')) {\n return;\n }\n\n this.clear();\n this.message(this.genericErrorText);\n }\n\n appendPreparedErrorMessageElement(errorMessageElement) {\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n this.messagesList.replaceWith(errorMessageElement);\n }\n\n message(text, persist = false) {\n if (!typeof String || text.length === 0) {\n throw new Error('A new message text must be a non-empty string.');\n }\n\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n if (persist) {\n this.wrapper.classList.add('ppcp-persist');\n } else {\n this.wrapper.classList.remove('ppcp-persist');\n }\n\n let messageNode = this.prepareMessagesListItem(text);\n this.messagesList.appendChild(messageNode);\n jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'));\n }\n\n prepareMessagesList() {\n if (this.messagesList === null) {\n this.messagesList = document.createElement('ul');\n this.messagesList.setAttribute('class', 'woocommerce-error');\n this.messagesList.setAttribute('role', 'alert');\n this.wrapper.appendChild(this.messagesList);\n }\n }\n\n prepareMessagesListItem(message) {\n const li = document.createElement('li');\n li.innerHTML = message;\n return li;\n }\n\n sanitize(text) {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = text;\n return textarea.value.replace('Error: ', '');\n }\n\n clear() {\n if (this.messagesList === null) {\n return;\n }\n\n this.messagesList.innerHTML = '';\n }\n\n}\n\n/* harmony default export */ const modules_ErrorHandler = (ErrorHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForContinue.js\nconst onApprove = (context, errorHandler) => {\n return (data, actions) => {\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID,\n funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/CheckoutMethodState.js\nconst PaymentMethods = {\n PAYPAL: 'ppcp-gateway',\n CARDS: 'ppcp-credit-card-gateway'\n};\nconst ORDER_BUTTON_SELECTOR = '#place_order';\nconst getCurrentPaymentMethod = () => {\n const el = document.querySelector('input[name=\"payment_method\"]:checked');\n\n if (!el) {\n return null;\n }\n\n return el.value;\n};\nconst isSavedCardSelected = () => {\n const savedCardList = document.querySelector('#saved-credit-card');\n return savedCardList && savedCardList.value !== '';\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CartActionHandler.js\n\n\n\n\nclass CartActionHandler {\n constructor(config, errorHandler) {\n this.config = config;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units: [],\n payment_method: PaymentMethods.PAYPAL,\n funding_source: window.ppcpFundingSource,\n bn_code: bnCode,\n payer,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CartActionHandler = (CartActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/MiniCartBootstap.js\n\n\n\nclass MiniCartBootstap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.actionHandler = null;\n }\n\n init() {\n this.actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.render();\n jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.mini_cart_wrapper) !== null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.renderer.render(this.gateway.button.mini_cart_wrapper, this.gateway.hosted_fields.mini_cart_wrapper, this.actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_MiniCartBootstap = (MiniCartBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/UpdateCart.js\n\n\nclass UpdateCart {\n constructor(endpoint, nonce) {\n this.endpoint = endpoint;\n this.nonce = nonce;\n }\n /**\n *\n * @param onResolve\n * @param {Product[]} products\n * @returns {Promise<unknown>}\n */\n\n\n update(onResolve, products) {\n return new Promise((resolve, reject) => {\n fetch(this.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.nonce,\n products\n })\n }).then(result => {\n return result.json();\n }).then(result => {\n if (!result.success) {\n reject(result.data);\n return;\n }\n\n const resolved = onResolve(result.data);\n resolve(resolved);\n });\n });\n }\n\n}\n\n/* harmony default export */ const Helper_UpdateCart = (UpdateCart);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/ButtonsToggleListener.js\n/**\n * When you can't add something to the cart, the PayPal buttons should not show.\n * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.\n */\nclass ButtonsToggleListener {\n constructor(element, showCallback, hideCallback) {\n this.element = element;\n this.showCallback = showCallback;\n this.hideCallback = hideCallback;\n this.observer = null;\n }\n\n init() {\n const config = {\n attributes: true\n };\n\n const callback = () => {\n if (this.element.classList.contains('disabled')) {\n this.hideCallback();\n return;\n }\n\n this.showCallback();\n };\n\n this.observer = new MutationObserver(callback);\n this.observer.observe(this.element, config);\n callback();\n }\n\n disconnect() {\n this.observer.disconnect();\n }\n\n}\n\n/* harmony default export */ const Helper_ButtonsToggleListener = (ButtonsToggleListener);\n;// CONCATENATED MODULE: ./resources/js/modules/Entity/Product.js\nclass Product {\n constructor(id, quantity, variations) {\n this.id = id;\n this.quantity = quantity;\n this.variations = variations;\n }\n\n data() {\n return {\n id: this.id,\n quantity: this.quantity,\n variations: this.variations\n };\n }\n\n}\n\n/* harmony default export */ const Entity_Product = (Product);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/SingleProductActionHandler.js\n\n\n\n\n\n\nclass SingleProductActionHandler {\n constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler) {\n this.config = config;\n this.updateCart = updateCart;\n this.showButtonCallback = showButtonCallback;\n this.hideButtonCallback = hideButtonCallback;\n this.formElement = formElement;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n if (this.hasVariations()) {\n const observer = new Helper_ButtonsToggleListener(this.formElement.querySelector('.single_add_to_cart_button'), this.showButtonCallback, this.hideButtonCallback);\n observer.init();\n }\n\n return {\n createOrder: this.createOrder(),\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n createOrder() {\n var getProducts = null;\n\n if (!this.isGroupedProduct()) {\n getProducts = () => {\n const id = document.querySelector('[name=\"add-to-cart\"]').value;\n const qty = document.querySelector('[name=\"quantity\"]').value;\n const variations = this.variations();\n return [new Entity_Product(id, qty, variations)];\n };\n } else {\n getProducts = () => {\n const products = [];\n this.formElement.querySelectorAll('input[type=\"number\"]').forEach(element => {\n if (!element.value) {\n return;\n }\n\n const elementName = element.getAttribute('name').match(/quantity\\[([\\d]*)\\]/);\n\n if (elementName.length !== 2) {\n return;\n }\n\n const id = parseInt(elementName[1]);\n const quantity = parseInt(element.value);\n products.push(new Entity_Product(id, quantity, null));\n });\n return products;\n };\n }\n\n const createOrder = (data, actions) => {\n this.errorHandler.clear();\n\n const onResolve = purchase_units => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units,\n payer,\n bn_code: bnCode,\n payment_method: PaymentMethods.PAYPAL,\n funding_source: window.ppcpFundingSource,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n const promise = this.updateCart.update(onResolve, getProducts());\n return promise;\n };\n\n return createOrder;\n }\n\n variations() {\n if (!this.hasVariations()) {\n return null;\n }\n\n const attributes = [...this.formElement.querySelectorAll(\"[name^='attribute_']\")].map(element => {\n return {\n value: element.value,\n name: element.name\n };\n });\n return attributes;\n }\n\n hasVariations() {\n return this.formElement.classList.contains('variations_form');\n }\n\n isGroupedProduct() {\n return this.formElement.classList.contains('grouped_form');\n }\n\n}\n\n/* harmony default export */ const ActionHandler_SingleProductActionHandler = (SingleProductActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/SingleProductBootstap.js\n\n\n\n\nclass SingleProductBootstap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n }\n\n handleChange() {\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n this.renderer.hideButtons(this.gateway.button.wrapper);\n return;\n }\n\n this.render();\n }\n\n init() {\n document.querySelector('form.cart').addEventListener('change', this.handleChange.bind(this));\n\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n return;\n }\n\n this.render();\n }\n\n shouldRender() {\n return document.querySelector('form.cart') !== null && !this.priceAmountIsZero();\n }\n\n priceAmountIsZero() {\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('.product .woocommerce-Price-amount')) {\n priceText = document.querySelector('.product .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseFloat(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n return amount === 0;\n }\n\n render() {\n const actionHandler = new ActionHandler_SingleProductActionHandler(this.gateway, new Helper_UpdateCart(this.gateway.ajax.change_cart.endpoint, this.gateway.ajax.change_cart.nonce), () => {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseInt(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n this.messages.renderWithAmount(amount);\n }, () => {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }, document.querySelector('form.cart'), new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_SingleProductBootstap = (SingleProductBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CartBootstap.js\n\n\n\nclass CartBootstrap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n }\n\n init() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.render();\n jQuery(document.body).on('updated_cart_totals updated_checkout', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n const actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const CartBootstap = (CartBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForPayNow.js\nconst onApproveForPayNow_onApprove = (context, errorHandler, spinner) => {\n return (data, actions) => {\n spinner.block();\n errorHandler.clear();\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID,\n funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\n\nclass CheckoutActionHandler {\n constructor(config, errorHandler, spinner) {\n this.config = config;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n }\n\n configuration() {\n const spinner = this.spinner;\n\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n const errorHandler = this.errorHandler;\n const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';\n const formValues = jQuery(formSelector).serialize();\n const createaccount = jQuery('#createaccount').is(\":checked\") ? true : false;\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n payer,\n bn_code: bnCode,\n context: this.config.context,\n order_id: this.config.order_id,\n payment_method: getCurrentPaymentMethod(),\n funding_source: window.ppcpFundingSource,\n form: formValues,\n createaccount: createaccount\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n spinner.unblock(); //handle both messages sent from Woocommerce (data.messages) and this plugin (data.data.message)\n\n if (typeof data.messages !== 'undefined') {\n const domParser = new DOMParser();\n errorHandler.appendPreparedErrorMessageElement(domParser.parseFromString(data.messages, 'text/html').querySelector('ul'));\n } else {\n errorHandler.clear();\n\n if (data.data.details.length > 0) {\n errorHandler.message(data.data.details.map(d => `${d.issue} ${d.description}`).join('<br/>'), true);\n } else {\n errorHandler.message(data.data.message, true);\n }\n }\n\n return;\n }\n\n const input = document.createElement('input');\n input.setAttribute('type', 'hidden');\n input.setAttribute('name', 'ppcp-resume-order');\n input.setAttribute('value', data.data.purchase_units[0].custom_id);\n document.querySelector(formSelector).append(input);\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForPayNow(this, this.errorHandler, this.spinner),\n onCancel: () => {\n spinner.unblock();\n },\n onError: () => {\n this.errorHandler.genericError();\n spinner.unblock();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CheckoutActionHandler = (CheckoutActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Hiding.js\nconst getElement = selectorOrElement => {\n if (typeof selectorOrElement === 'string') {\n return document.querySelector(selectorOrElement);\n }\n\n return selectorOrElement;\n};\n\nconst isVisible = element => {\n return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);\n};\nconst setVisible = (selectorOrElement, show, important = false) => {\n const element = getElement(selectorOrElement);\n\n if (!element) {\n return;\n }\n\n const currentValue = element.style.getPropertyValue('display');\n\n if (!show) {\n if (currentValue === 'none') {\n return;\n }\n\n element.style.setProperty('display', 'none', important ? 'important' : '');\n } else {\n if (currentValue === 'none') {\n element.style.removeProperty('display');\n } // still not visible (if something else added display: none in CSS)\n\n\n if (!isVisible(element)) {\n element.style.setProperty('display', 'block');\n }\n }\n};\nconst hide = (selectorOrElement, important = false) => {\n setVisible(selectorOrElement, false, important);\n};\nconst show = selectorOrElement => {\n setVisible(selectorOrElement, true);\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CheckoutBootstap.js\n\n\n\n\n\nclass CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n this.standardOrderButtonSelector = ORDER_BUTTON_SELECTOR;\n this.buttonChangeObserver = new MutationObserver(el => {\n this.updateUi();\n });\n }\n\n init() {\n this.render(); // Unselect saved card.\n // WC saves form values, so with our current UI it would be a bit weird\n // if the user paid with saved, then after some time tries to pay again,\n // but wants to enter a new card, and to do that they have to choose “Select payment” in the list.\n\n jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.updateUi();\n });\n jQuery(document).on('hosted_fields_loaded', () => {\n jQuery('#saved-credit-card').on('change', () => {\n this.updateUi();\n });\n });\n this.updateUi();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n this.buttonChangeObserver.observe(document.querySelector(this.standardOrderButtonSelector), {\n attributes: true\n });\n }\n\n updateUi() {\n const currentPaymentMethod = getCurrentPaymentMethod();\n const isPaypal = currentPaymentMethod === PaymentMethods.PAYPAL;\n const isCard = currentPaymentMethod === PaymentMethods.CARDS;\n const isSavedCard = isCard && isSavedCardSelected();\n const isNotOurGateway = !isPaypal && !isCard;\n const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;\n const hasVaultedPaypal = PayPalCommerceGateway.vaulted_paypal_email !== '';\n setVisible(this.standardOrderButtonSelector, isPaypal && isFreeTrial && hasVaultedPaypal || isNotOurGateway || isSavedCard, true);\n setVisible('.ppcp-vaulted-paypal-details', isPaypal);\n setVisible(this.gateway.button.wrapper, isPaypal && !(isFreeTrial && hasVaultedPaypal));\n setVisible(this.gateway.messages.wrapper, isPaypal && !isFreeTrial);\n setVisible(this.gateway.hosted_fields.wrapper, isCard && !isSavedCard);\n\n if (isPaypal && !isFreeTrial) {\n this.messages.render();\n }\n\n if (isCard) {\n if (isSavedCard) {\n this.disableCreditCardFields();\n } else {\n this.enableCreditCardFields();\n }\n }\n }\n\n disableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", true);\n this.renderer.disableCreditCardFields();\n }\n\n enableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", false);\n this.renderer.enableCreditCardFields();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_CheckoutBootstap = (CheckoutBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Subscriptions.js\nconst isChangePaymentPage = () => {\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.has('change_payment_method');\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/PayNowBootstrap.js\n\n\n\nclass PayNowBootstrap extends ContextBootstrap_CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n super(gateway, renderer, messages, spinner);\n }\n\n updateUi() {\n if (isChangePaymentPage()) {\n return;\n }\n\n super.updateUi();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_PayNowBootstrap = (PayNowBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/Renderer.js\nclass Renderer {\n constructor(creditCardRenderer, defaultConfig, onSmartButtonClick, onSmartButtonsInit) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n this.onSmartButtonClick = onSmartButtonClick;\n this.onSmartButtonsInit = onSmartButtonsInit;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig,\n onClick: this.onSmartButtonClick,\n onInit: this.onSmartButtonsInit\n }).render(wrapper);\n }\n\n isAlreadyRendered(wrapper) {\n return document.querySelector(wrapper).hasChildNodes();\n }\n\n hideButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'none';\n return true;\n }\n\n showButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'block';\n return true;\n }\n\n disableCreditCardFields() {\n this.creditCardRenderer.disableFields();\n }\n\n enableCreditCardFields() {\n this.creditCardRenderer.enableFields();\n }\n\n}\n\n/* harmony default export */ const Renderer_Renderer = (Renderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/DccInputFactory.js\nconst dccInputFactory = original => {\n const styles = window.getComputedStyle(original);\n const newElement = document.createElement('span');\n newElement.setAttribute('id', original.id);\n Object.values(styles).forEach(prop => {\n if (!styles[prop] || !isNaN(prop)) {\n return;\n }\n\n newElement.style.setProperty(prop, '' + styles[prop]);\n });\n return newElement;\n};\n\n/* harmony default export */ const DccInputFactory = (dccInputFactory);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/CreditCardRenderer.js\n\n\n\nclass CreditCardRenderer {\n constructor(defaultConfig, errorHandler, spinner) {\n this.defaultConfig = defaultConfig;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n this.cardValid = false;\n this.formValid = false;\n this.currentHostedFieldsInstance = null;\n }\n\n render(wrapper, contextConfig) {\n if (this.defaultConfig.context !== 'checkout' && this.defaultConfig.context !== 'pay-now' || wrapper === null || document.querySelector(wrapper) === null) {\n return;\n }\n\n if (typeof paypal.HostedFields === 'undefined' || !paypal.HostedFields.isEligible()) {\n const wrapperElement = document.querySelector(wrapper);\n wrapperElement.parentNode.removeChild(wrapperElement);\n return;\n }\n\n const buttonSelector = wrapper + ' button';\n\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.teardown().catch(err => console.error(`Hosted fields teardown error: ${err}`));\n this.currentHostedFieldsInstance = null;\n }\n\n const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');\n\n if (!gateWayBox) {\n return;\n }\n\n const oldDisplayStyle = gateWayBox.style.display;\n gateWayBox.style.display = 'block';\n const hideDccGateway = document.querySelector('#ppcp-hide-dcc');\n\n if (hideDccGateway) {\n hideDccGateway.parentNode.removeChild(hideDccGateway);\n }\n\n const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');\n const stylesRaw = window.getComputedStyle(cardNumberField);\n let styles = {};\n Object.values(stylesRaw).forEach(prop => {\n if (!stylesRaw[prop]) {\n return;\n }\n\n styles[prop] = '' + stylesRaw[prop];\n });\n const cardNumber = DccInputFactory(cardNumberField);\n cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);\n const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');\n const cardExpiry = DccInputFactory(cardExpiryField);\n cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);\n const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');\n const cardCode = DccInputFactory(cardCodeField);\n cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);\n gateWayBox.style.display = oldDisplayStyle;\n const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';\n\n if (this.defaultConfig.enforce_vault && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')) {\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);\n }\n\n paypal.HostedFields.render({\n createOrder: contextConfig.createOrder,\n styles: {\n 'input': styles\n },\n fields: {\n number: {\n selector: '#ppcp-credit-card-gateway-card-number',\n placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number\n },\n cvv: {\n selector: '#ppcp-credit-card-gateway-card-cvc',\n placeholder: this.defaultConfig.hosted_fields.labels.cvv\n },\n expirationDate: {\n selector: '#ppcp-credit-card-gateway-card-expiry',\n placeholder: this.defaultConfig.hosted_fields.labels.mm_yy\n }\n }\n }).then(hostedFields => {\n document.dispatchEvent(new CustomEvent(\"hosted_fields_loaded\"));\n this.currentHostedFieldsInstance = hostedFields;\n hostedFields.on('inputSubmitRequest', () => {\n this._submit(contextConfig);\n });\n hostedFields.on('cardTypeChange', event => {\n if (!event.cards.length) {\n this.cardValid = false;\n return;\n }\n\n const validCards = this.defaultConfig.hosted_fields.valid_cards;\n this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;\n });\n hostedFields.on('validityChange', event => {\n const formValid = Object.keys(event.fields).every(function (key) {\n return event.fields[key].isValid;\n });\n this.formValid = formValid;\n });\n show(buttonSelector);\n\n if (document.querySelector(wrapper).getAttribute('data-ppcp-subscribed') !== true) {\n document.querySelector(buttonSelector).addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n document.querySelector(wrapper).setAttribute('data-ppcp-subscribed', true);\n }\n });\n document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener('click', () => {\n document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();\n });\n }\n\n disableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.setAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n enableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n _submit(contextConfig) {\n this.spinner.block();\n this.errorHandler.clear();\n\n if (this.formValid && this.cardValid) {\n const save_card = this.defaultConfig.can_save_vault_token ? true : false;\n let vault = document.getElementById('ppcp-credit-card-vault') ? document.getElementById('ppcp-credit-card-vault').checked : save_card;\n\n if (this.defaultConfig.enforce_vault) {\n vault = true;\n }\n\n const contingency = this.defaultConfig.hosted_fields.contingency;\n const hostedFieldsData = {\n vault: vault\n };\n\n if (contingency !== 'NO_3D_SECURE') {\n hostedFieldsData.contingencies = [contingency];\n }\n\n if (this.defaultConfig.payer) {\n hostedFieldsData.cardholderName = this.defaultConfig.payer.name.given_name + ' ' + this.defaultConfig.payer.name.surname;\n }\n\n if (!hostedFieldsData.cardholderName) {\n const firstName = document.getElementById('billing_first_name') ? document.getElementById('billing_first_name').value : '';\n const lastName = document.getElementById('billing_last_name') ? document.getElementById('billing_last_name').value : '';\n hostedFieldsData.cardholderName = firstName + ' ' + lastName;\n }\n\n this.currentHostedFieldsInstance.submit(hostedFieldsData).then(payload => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n }).catch(err => {\n this.spinner.unblock();\n this.errorHandler.clear();\n\n if (err.details) {\n this.errorHandler.message(err.details.map(d => `${d.issue} ${d.description}`).join('<br/>'), true);\n }\n });\n } else {\n this.spinner.unblock();\n const message = !this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;\n this.errorHandler.message(message);\n }\n }\n\n}\n\n/* harmony default export */ const Renderer_CreditCardRenderer = (CreditCardRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/DataClientIdAttributeHandler.js\nconst storageKey = 'ppcp-data-client-id';\n\nconst validateToken = (token, user) => {\n if (!token) {\n return false;\n }\n\n if (token.user !== user) {\n return false;\n }\n\n const currentTime = new Date().getTime();\n const isExpired = currentTime >= token.expiration * 1000;\n return !isExpired;\n};\n\nconst storedTokenForUser = user => {\n const token = JSON.parse(sessionStorage.getItem(storageKey));\n\n if (validateToken(token, user)) {\n return token.token;\n }\n\n return null;\n};\n\nconst storeToken = token => {\n sessionStorage.setItem(storageKey, JSON.stringify(token));\n};\n\nconst dataClientIdAttributeHandler = (script, config) => {\n fetch(config.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: config.nonce\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n const isValid = validateToken(data, config.user);\n\n if (!isValid) {\n return;\n }\n\n storeToken(data);\n script.setAttribute('data-client-token', data.token);\n document.body.append(script);\n });\n};\n\n/* harmony default export */ const DataClientIdAttributeHandler = (dataClientIdAttributeHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/MessageRenderer.js\nclass MessageRenderer {\n constructor(config) {\n this.config = config;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n jQuery(document.body).on('updated_cart_totals', () => {\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n });\n }\n\n renderWithAmount(amount) {\n if (!this.shouldRender()) {\n return;\n }\n\n const newWrapper = document.createElement('div');\n newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));\n const sibling = document.querySelector(this.config.wrapper).nextSibling;\n document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));\n sibling.parentElement.insertBefore(newWrapper, sibling);\n paypal.Messages({\n amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n shouldRender() {\n if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined') {\n return false;\n }\n\n if (!document.querySelector(this.config.wrapper)) {\n return false;\n }\n\n return true;\n }\n\n}\n\n/* harmony default export */ const Renderer_MessageRenderer = (MessageRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Spinner.js\nclass Spinner {\n constructor(target = 'form.woocommerce-checkout') {\n this.target = target;\n }\n\n setTarget(target) {\n this.target = target;\n }\n\n block() {\n jQuery(this.target).block({\n message: null,\n overlayCSS: {\n background: '#fff',\n opacity: 0.6\n }\n });\n }\n\n unblock() {\n jQuery(this.target).unblock();\n }\n\n}\n\n/* harmony default export */ const Helper_Spinner = (Spinner);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/FreeTrialHandler.js\n\n\n\nclass FreeTrialHandler {\n constructor(config, spinner, errorHandler) {\n this.config = config;\n this.spinner = spinner;\n this.errorHandler = errorHandler;\n }\n\n handle() {\n this.spinner.block();\n fetch(this.config.ajax.vault_paypal.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.vault_paypal.nonce,\n return_url: location.href\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n this.spinner.unblock();\n console.error(data);\n this.errorHandler.message(data.data.message);\n throw Error(data.data.message);\n }\n\n location.href = data.data.approve_link;\n }).catch(error => {\n this.spinner.unblock();\n console.error(error);\n this.errorHandler.genericError();\n });\n }\n\n}\n\n/* harmony default export */ const ActionHandler_FreeTrialHandler = (FreeTrialHandler);\n;// CONCATENATED MODULE: ./resources/js/button.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst buttonsSpinner = new Helper_Spinner('.ppc-button-wrapper');\nconst cardsSpinner = new Helper_Spinner('#ppcp-hosted-fields');\n\nconst bootstrap = () => {\n const errorHandler = new modules_ErrorHandler(PayPalCommerceGateway.labels.error.generic);\n const spinner = new Helper_Spinner();\n const creditCardRenderer = new Renderer_CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);\n const freeTrialHandler = new ActionHandler_FreeTrialHandler(PayPalCommerceGateway, spinner, errorHandler);\n\n const onSmartButtonClick = (data, actions) => {\n window.ppcpFundingSource = data.fundingSource;\n const form = document.querySelector('form.woocommerce-checkout');\n\n if (form) {\n jQuery('#ppcp-funding-source-form-input').remove();\n form.insertAdjacentHTML('beforeend', `<input type=\"hidden\" name=\"ppcp-funding-source\" value=\"${data.fundingSource}\" id=\"ppcp-funding-source-form-input\">`);\n }\n\n const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;\n\n if (isFreeTrial && data.fundingSource !== 'card') {\n freeTrialHandler.handle();\n return actions.reject();\n }\n };\n\n const onSmartButtonsInit = () => {\n buttonsSpinner.unblock();\n };\n\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick, onSmartButtonsInit);\n const messageRenderer = new Renderer_MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n\n if (context === 'mini-cart' || context === 'product') {\n if (PayPalCommerceGateway.mini_cart_buttons_enabled === '1') {\n const miniCartBootstrap = new ContextBootstrap_MiniCartBootstap(PayPalCommerceGateway, renderer);\n miniCartBootstrap.init();\n }\n }\n\n if (context === 'product' && PayPalCommerceGateway.single_product_buttons_enabled === '1') {\n const singleProductBootstrap = new ContextBootstrap_SingleProductBootstap(PayPalCommerceGateway, renderer, messageRenderer);\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstap(PayPalCommerceGateway, renderer);\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new ContextBootstrap_CheckoutBootstap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now') {\n const payNowBootstrap = new ContextBootstrap_PayNowBootstrap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (!typeof PayPalCommerceGateway) {\n console.error('PayPal button could not be configured.');\n return;\n }\n\n if (PayPalCommerceGateway.context !== 'checkout' && PayPalCommerceGateway.data_client_id.user === 0 && PayPalCommerceGateway.data_client_id.has_subscriptions) {\n return;\n } // Sometimes PayPal script takes long time to load,\n // so we additionally hide the standard order button here to avoid failed orders.\n // Normally it is hidden later after the script load.\n\n\n const hideOrderButtonIfPpcpGateway = () => {\n // only in checkout and pay now page, otherwise it may break things (e.g. payment via product page),\n // and also the loading spinner may look weird on other pages\n if (!['checkout', 'pay-now'].includes(PayPalCommerceGateway.context) || isChangePaymentPage() || PayPalCommerceGateway.is_free_trial_cart && PayPalCommerceGateway.vaulted_paypal_email !== '') {\n return;\n }\n\n const currentPaymentMethod = getCurrentPaymentMethod();\n const isPaypal = currentPaymentMethod === PaymentMethods.PAYPAL;\n const isCards = currentPaymentMethod === PaymentMethods.CARDS;\n setVisible(ORDER_BUTTON_SELECTOR, !isPaypal && !isCards, true);\n\n if (isPaypal) {\n // stopped after the first rendering of the buttons, in onInit\n buttonsSpinner.block();\n } else {\n buttonsSpinner.unblock();\n }\n\n if (isCards) {\n cardsSpinner.block();\n } else {\n cardsSpinner.unblock();\n }\n };\n\n jQuery(document).on('hosted_fields_loaded', () => {\n cardsSpinner.unblock();\n });\n let bootstrapped = false;\n hideOrderButtonIfPpcpGateway();\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n if (bootstrapped) {\n return;\n }\n\n hideOrderButtonIfPpcpGateway();\n });\n const script = document.createElement('script');\n script.addEventListener('load', event => {\n bootstrapped = true;\n bootstrap();\n });\n script.setAttribute('src', PayPalCommerceGateway.button.url);\n Object.entries(PayPalCommerceGateway.script_attributes).forEach(keyValue => {\n script.setAttribute(keyValue[0], keyValue[1]);\n });\n\n if (PayPalCommerceGateway.data_client_id.set_attribute) {\n DataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);\n return;\n }\n\n document.body.append(script);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Qy9ULFlBQVAsQ0FBb0IwVyxRQUFRLENBQUMsQ0FBRCxDQUE1QixFQUFpQ0EsUUFBUSxDQUFDLENBQUQsQ0FBekM7QUFDSCxHQUhMOztBQU1BLE1BQUluVSxxQkFBcUIsQ0FBQzBULGNBQXRCLENBQXFDVSxhQUF6QyxFQUF3RDtBQUNwRDdDLElBQUFBLDRCQUE0QixDQUFDQyxNQUFELEVBQVN4UixxQkFBcUIsQ0FBQzBULGNBQS9CLENBQTVCO0FBQ0E7QUFDSDs7QUFFRDFYLEVBQUFBLFFBQVEsQ0FBQzJDLElBQVQsQ0FBY29KLE1BQWQsQ0FBcUJ5SixNQUFyQjtBQUNILENBckZMIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0Vycm9ySGFuZGxlci5qcz9lNjVhIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9PbkFwcHJvdmVIYW5kbGVyL29uQXBwcm92ZUZvckNvbnRpbnVlLmpzP2M0NTQiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9QYXllckRhdGEuanM/MmFmMSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0NoZWNrb3V0TWV0aG9kU3RhdGUuanM/ODBhMyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DYXJ0QWN0aW9uSGFuZGxlci5qcz84MmNmIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL01pbmlDYXJ0Qm9vdHN0YXAuanM/ZDU1MiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1VwZGF0ZUNhcnQuanM/ZTQyMiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lci5qcz9lMTkzIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9FbnRpdHkvUHJvZHVjdC5qcz85ZmZmIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL1NpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyLmpzP2Q5YjciLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvU2luZ2xlUHJvZHVjdEJvb3RzdGFwLmpzPzdjMTkiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2FydEJvb3RzdGFwLmpzPzVlOTQiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yUGF5Tm93LmpzPzkzMDUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvQ2hlY2tvdXRBY3Rpb25IYW5kbGVyLmpzPzg1MTUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9IaWRpbmcuanM/MWQzNiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwLmpzP2M4NTUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9TdWJzY3JpcHRpb25zLmpzP2I4NzAiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwLmpzP2Q5ZjUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyLmpzP2ZhOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9EY2NJbnB1dEZhY3RvcnkuanM/MmEyZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyLmpzPzM4N2EiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIuanM/ZWUwYiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyLmpzP2NkMDIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9TcGlubmVyLmpzPzE3MDgiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvRnJlZVRyaWFsSGFuZGxlci5qcz9hYjc3Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvYnV0dG9uLmpzPzA2MGYiXSwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgRXJyb3JIYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGdlbmVyaWNFcnJvclRleHQpXG4gICAge1xuICAgICAgICB0aGlzLmdlbmVyaWNFcnJvclRleHQgPSBnZW5lcmljRXJyb3JUZXh0O1xuICAgICAgICB0aGlzLndyYXBwZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcud29vY29tbWVyY2Utbm90aWNlcy13cmFwcGVyJyk7XG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcigndWwud29vY29tbWVyY2UtZXJyb3InKTtcbiAgICB9XG5cbiAgICBnZW5lcmljRXJyb3IoKSB7XG4gICAgICAgIGlmICh0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCdwcGNwLXBlcnNpc3QnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlKHRoaXMuZ2VuZXJpY0Vycm9yVGV4dClcbiAgICB9XG5cbiAgICBhcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoZXJyb3JNZXNzYWdlRWxlbWVudClcbiAgICB7XG4gICAgICAgIGlmKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LnJlcGxhY2VXaXRoKGVycm9yTWVzc2FnZUVsZW1lbnQpO1xuICAgIH1cblxuICAgIG1lc3NhZ2UodGV4dCwgcGVyc2lzdCA9IGZhbHNlKVxuICAgIHtcbiAgICAgICAgaWYoISB0eXBlb2YgU3RyaW5nIHx8IHRleHQubGVuZ3RoID09PSAwKXtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQSBuZXcgbWVzc2FnZSB0ZXh0IG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpe1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlTWVzc2FnZXNMaXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGVyc2lzdCkge1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5hZGQoJ3BwY3AtcGVyc2lzdCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5yZW1vdmUoJ3BwY3AtcGVyc2lzdCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG1lc3NhZ2VOb2RlID0gdGhpcy5wcmVwYXJlTWVzc2FnZXNMaXN0SXRlbSh0ZXh0KTtcbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QuYXBwZW5kQ2hpbGQobWVzc2FnZU5vZGUpO1xuXG4gICAgICAgIGpRdWVyeS5zY3JvbGxfdG9fbm90aWNlcyhqUXVlcnkoJy53b29jb21tZXJjZS1ub3RpY2VzLXdyYXBwZXInKSlcbiAgICB9XG5cbiAgICBwcmVwYXJlTWVzc2FnZXNMaXN0KClcbiAgICB7XG4gICAgICAgIGlmKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKXtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXNMaXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndWwnKTtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnd29vY29tbWVyY2UtZXJyb3InKTtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LnNldEF0dHJpYnV0ZSgncm9sZScsICdhbGVydCcpO1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyLmFwcGVuZENoaWxkKHRoaXMubWVzc2FnZXNMaXN0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByZXBhcmVNZXNzYWdlc0xpc3RJdGVtKG1lc3NhZ2UpXG4gICAge1xuICAgICAgICBjb25zdCBsaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7XG4gICAgICAgIGxpLmlubmVySFRNTCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgcmV0dXJuIGxpO1xuICAgIH1cblxuICAgIHNhbml0aXplKHRleHQpXG4gICAge1xuICAgICAgICBjb25zdCB0ZXh0YXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgICAgIHRleHRhcmVhLmlubmVySFRNTCA9IHRleHQ7XG4gICAgICAgIHJldHVybiB0ZXh0YXJlYS52YWx1ZS5yZXBsYWNlKCdFcnJvcjogJywgJycpO1xuICAgIH1cblxuICAgIGNsZWFyKClcbiAgICB7XG4gICAgICAgIGlmICh0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QuaW5uZXJIVE1MID0gJyc7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFcnJvckhhbmRsZXI7XG4iLCJjb25zdCBvbkFwcHJvdmUgPSAoY29udGV4dCwgZXJyb3JIYW5kbGVyKSA9PiB7XG4gICAgcmV0dXJuIChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklELFxuICAgICAgICAgICAgICAgIGZ1bmRpbmdfc291cmNlOiB3aW5kb3cucHBjcEZ1bmRpbmdTb3VyY2UsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhdGlvbi5ocmVmID0gY29udGV4dC5jb25maWcucmVkaXJlY3Q7XG4gICAgICAgIH0pO1xuXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBvbkFwcHJvdmU7XG4iLCJleHBvcnQgY29uc3QgcGF5ZXJEYXRhID0gKCkgPT4ge1xuICAgIGNvbnN0IHBheWVyID0gUGF5UGFsQ29tbWVyY2VHYXRld2F5LnBheWVyO1xuICAgIGlmICghIHBheWVyKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHBob25lID0gKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykgfHwgdHlwZW9mIHBheWVyLnBob25lICE9PSAndW5kZWZpbmVkJykgP1xuICAgIHtcbiAgICAgICAgcGhvbmVfdHlwZTpcIkhPTUVcIixcbiAgICAgICAgICAgIHBob25lX251bWJlcjp7XG4gICAgICAgICAgICBuYXRpb25hbF9udW1iZXIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpLnZhbHVlIDogcGF5ZXIucGhvbmUucGhvbmVfbnVtYmVyLm5hdGlvbmFsX251bWJlclxuICAgICAgICB9XG4gICAgfSA6IG51bGw7XG4gICAgY29uc3QgcGF5ZXJEYXRhID0ge1xuICAgICAgICBlbWFpbF9hZGRyZXNzOihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2VtYWlsJykudmFsdWUgOiBwYXllci5lbWFpbF9hZGRyZXNzLFxuICAgICAgICBuYW1lIDoge1xuICAgICAgICAgICAgc3VybmFtZTogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2xhc3RfbmFtZScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2xhc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5zdXJuYW1lLFxuICAgICAgICAgICAgZ2l2ZW5fbmFtZTogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2ZpcnN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykudmFsdWUgOiBwYXllci5uYW1lLmdpdmVuX25hbWVcbiAgICAgICAgfSxcbiAgICAgICAgYWRkcmVzcyA6IHtcbiAgICAgICAgICAgIGNvdW50cnlfY29kZSA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jb3VudHJ5JykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpLnZhbHVlIDogcGF5ZXIuYWRkcmVzcy5jb3VudHJ5X2NvZGUsXG4gICAgICAgICAgICBhZGRyZXNzX2xpbmVfMSA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19hZGRyZXNzXzEnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19hZGRyZXNzXzEnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRkcmVzc19saW5lXzEsXG4gICAgICAgICAgICBhZGRyZXNzX2xpbmVfMiA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19hZGRyZXNzXzInKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19hZGRyZXNzXzInKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRkcmVzc19saW5lXzIsXG4gICAgICAgICAgICBhZG1pbl9hcmVhXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19zdGF0ZScpLnZhbHVlIDogcGF5ZXIuYWRkcmVzcy5hZG1pbl9hcmVhXzEsXG4gICAgICAgICAgICBhZG1pbl9hcmVhXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY2l0eScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8yLFxuICAgICAgICAgICAgcG9zdGFsX2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19wb3N0Y29kZScpLnZhbHVlIDogcGF5ZXIuYWRkcmVzcy5wb3N0YWxfY29kZVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmIChwaG9uZSkge1xuICAgICAgICBwYXllckRhdGEucGhvbmUgPSBwaG9uZTtcbiAgICB9XG4gICAgcmV0dXJuIHBheWVyRGF0YTtcbn1cbiIsImV4cG9ydCBjb25zdCBQYXltZW50TWV0aG9kcyA9IHtcbiAgICBQQVlQQUw6ICdwcGNwLWdhdGV3YXknLFxuICAgIENBUkRTOiAncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5Jyxcbn07XG5cbmV4cG9ydCBjb25zdCBPUkRFUl9CVVRUT05fU0VMRUNUT1IgPSAnI3BsYWNlX29yZGVyJztcblxuZXhwb3J0IGNvbnN0IGdldEN1cnJlbnRQYXltZW50TWV0aG9kID0gKCkgPT4ge1xuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cInBheW1lbnRfbWV0aG9kXCJdOmNoZWNrZWQnKTtcbiAgICBpZiAoIWVsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBlbC52YWx1ZTtcbn07XG5cbmV4cG9ydCBjb25zdCBpc1NhdmVkQ2FyZFNlbGVjdGVkID0gKCkgPT4ge1xuICAgIGNvbnN0IHNhdmVkQ2FyZExpc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2F2ZWQtY3JlZGl0LWNhcmQnKTtcbiAgICByZXR1cm4gc2F2ZWRDYXJkTGlzdCAmJiBzYXZlZENhcmRMaXN0LnZhbHVlICE9PSAnJztcbn07XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5pbXBvcnQge1BheW1lbnRNZXRob2RzfSBmcm9tIFwiLi4vSGVscGVyL0NoZWNrb3V0TWV0aG9kU3RhdGVcIjtcblxuY2xhc3MgQ2FydEFjdGlvbkhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnLCBlcnJvckhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgIH1cblxuICAgIGNvbmZpZ3VyYXRpb24oKSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZU9yZGVyID0gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWVyID0gcGF5ZXJEYXRhKCk7XG4gICAgICAgICAgICBjb25zdCBibkNvZGUgPSB0eXBlb2YgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gIT09ICd1bmRlZmluZWQnID9cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgcmV0dXJuIGZldGNoKHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgICAgIHB1cmNoYXNlX3VuaXRzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgcGF5bWVudF9tZXRob2Q6IFBheW1lbnRNZXRob2RzLlBBWVBBTCxcbiAgICAgICAgICAgICAgICAgICAgZnVuZGluZ19zb3VyY2U6IHdpbmRvdy5wcGNwRnVuZGluZ1NvdXJjZSxcbiAgICAgICAgICAgICAgICAgICAgYm5fY29kZTpibkNvZGUsXG4gICAgICAgICAgICAgICAgICAgIHBheWVyLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHRcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24ocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENhcnRBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuXG5jbGFzcyBNaW5pQ2FydEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIHRoaXMuYWN0aW9uSGFuZGxlciA9IG51bGw7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLm9uKCd3Y19mcmFnbWVudHNfbG9hZGVkIHdjX2ZyYWdtZW50c19yZWZyZXNoZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24ubWluaV9jYXJ0X3dyYXBwZXIpICE9PSBudWxsXG4gICAgICAgICAgICB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyKSAhPT0gbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMubWluaV9jYXJ0X3dyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBNaW5pQ2FydEJvb3RzdGFwO1xuIiwiaW1wb3J0IFByb2R1Y3QgZnJvbSBcIi4uL0VudGl0eS9Qcm9kdWN0XCI7XG5jbGFzcyBVcGRhdGVDYXJ0IHtcblxuICAgIGNvbnN0cnVjdG9yKGVuZHBvaW50LCBub25jZSlcbiAgICB7XG4gICAgICAgIHRoaXMuZW5kcG9pbnQgPSBlbmRwb2ludDtcbiAgICAgICAgdGhpcy5ub25jZSA9IG5vbmNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIG9uUmVzb2x2ZVxuICAgICAqIEBwYXJhbSB7UHJvZHVjdFtdfSBwcm9kdWN0c1xuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHVua25vd24+fVxuICAgICAqL1xuICAgIHVwZGF0ZShvblJlc29sdmUsIHByb2R1Y3RzKVxuICAgIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGZldGNoKFxuICAgICAgICAgICAgICAgIHRoaXMuZW5kcG9pbnQsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMubm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0cyxcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApLnRoZW4oXG4gICAgICAgICAgICAgICAgKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQuanNvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEgcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlZCA9IG9uUmVzb2x2ZShyZXN1bHQuZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzb2x2ZWQpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVXBkYXRlQ2FydDsiLCIvKipcbiAqIFdoZW4geW91IGNhbid0IGFkZCBzb21ldGhpbmcgdG8gdGhlIGNhcnQsIHRoZSBQYXlQYWwgYnV0dG9ucyBzaG91bGQgbm90IHNob3cuXG4gKiBUaGVyZWZvcmUgd2UgbGlzdGVuIGZvciBjaGFuZ2VzIG9uIHRoZSBhZGQgdG8gY2FydCBidXR0b24gYW5kIHNob3cvaGlkZSB0aGUgYnV0dG9ucyBhY2NvcmRpbmdseS5cbiAqL1xuXG5jbGFzcyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIge1xuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnQsIHNob3dDYWxsYmFjaywgaGlkZUNhbGxiYWNrKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgdGhpcy5zaG93Q2FsbGJhY2sgPSBzaG93Q2FsbGJhY2s7XG4gICAgICAgIHRoaXMuaGlkZUNhbGxiYWNrID0gaGlkZUNhbGxiYWNrO1xuICAgICAgICB0aGlzLm9ic2VydmVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBpbml0KClcbiAgICB7XG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IHsgYXR0cmlidXRlcyA6IHRydWUgfTtcbiAgICAgICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5lbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnZGlzYWJsZWQnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zaG93Q2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoY2FsbGJhY2spO1xuICAgICAgICB0aGlzLm9ic2VydmVyLm9ic2VydmUodGhpcy5lbGVtZW50LCBjb25maWcpO1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH1cblxuICAgIGRpc2Nvbm5lY3QoKVxuICAgIHtcbiAgICAgICAgdGhpcy5vYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBCdXR0b25zVG9nZ2xlTGlzdGVuZXI7IiwiY2xhc3MgUHJvZHVjdCB7XG5cbiAgICBjb25zdHJ1Y3RvcihpZCwgcXVhbnRpdHksIHZhcmlhdGlvbnMpIHtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICB0aGlzLnF1YW50aXR5ID0gcXVhbnRpdHk7XG4gICAgICAgIHRoaXMudmFyaWF0aW9ucyA9IHZhcmlhdGlvbnM7XG4gICAgfVxuXG4gICAgZGF0YSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlkOnRoaXMuaWQsXG4gICAgICAgICAgICBxdWFudGl0eTp0aGlzLnF1YW50aXR5LFxuICAgICAgICAgICAgdmFyaWF0aW9uczp0aGlzLnZhcmlhdGlvbnNcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHJvZHVjdDsiLCJpbXBvcnQgQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIGZyb20gJy4uL0hlbHBlci9CdXR0b25zVG9nZ2xlTGlzdGVuZXInO1xuaW1wb3J0IFByb2R1Y3QgZnJvbSAnLi4vRW50aXR5L1Byb2R1Y3QnO1xuaW1wb3J0IG9uQXBwcm92ZSBmcm9tICcuLi9PbkFwcHJvdmVIYW5kbGVyL29uQXBwcm92ZUZvckNvbnRpbnVlJztcbmltcG9ydCB7cGF5ZXJEYXRhfSBmcm9tIFwiLi4vSGVscGVyL1BheWVyRGF0YVwiO1xuaW1wb3J0IHtQYXltZW50TWV0aG9kc30gZnJvbSBcIi4uL0hlbHBlci9DaGVja291dE1ldGhvZFN0YXRlXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHVwZGF0ZUNhcnQsXG4gICAgICAgIHNob3dCdXR0b25DYWxsYmFjayxcbiAgICAgICAgaGlkZUJ1dHRvbkNhbGxiYWNrLFxuICAgICAgICBmb3JtRWxlbWVudCxcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhcnQgPSB1cGRhdGVDYXJ0O1xuICAgICAgICB0aGlzLnNob3dCdXR0b25DYWxsYmFjayA9IHNob3dCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2sgPSBoaWRlQnV0dG9uQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnQgPSBmb3JtRWxlbWVudDtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpXG4gICAge1xuXG4gICAgICAgIGlmICggdGhpcy5oYXNWYXJpYXRpb25zKCkgKSB7XG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlX2FkZF90b19jYXJ0X2J1dHRvbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUJ1dHRvbkNhbGxiYWNrXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuaW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiB0aGlzLmNyZWF0ZU9yZGVyKCksXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU9yZGVyKClcbiAgICB7XG4gICAgICAgIHZhciBnZXRQcm9kdWN0cyA9IG51bGw7XG4gICAgICAgIGlmICghIHRoaXMuaXNHcm91cGVkUHJvZHVjdCgpICkge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cImFkZC10by1jYXJ0XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcXR5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25hbWU9XCJxdWFudGl0eVwiXScpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhdGlvbnMgPSB0aGlzLnZhcmlhdGlvbnMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBQcm9kdWN0KGlkLCBxdHksIHZhcmlhdGlvbnMpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFByb2R1Y3RzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwibnVtYmVyXCJdJykuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBlbGVtZW50LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpLm1hdGNoKC9xdWFudGl0eVxcWyhbXFxkXSopXFxdLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50TmFtZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHBhcnNlSW50KGVsZW1lbnROYW1lWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMucHVzaChuZXcgUHJvZHVjdChpZCwgcXVhbnRpdHksIG51bGwpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICBjb25zdCBvblJlc29sdmUgPSAocHVyY2hhc2VfdW5pdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bWVudF9tZXRob2Q6IFBheW1lbnRNZXRob2RzLlBBWVBBTCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmRpbmdfc291cmNlOiB3aW5kb3cucHBjcEZ1bmRpbmdTb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHRcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMudXBkYXRlQ2FydC51cGRhdGUob25SZXNvbHZlLCBnZXRQcm9kdWN0cygpKTtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gY3JlYXRlT3JkZXI7XG4gICAgfVxuXG4gICAgdmFyaWF0aW9ucygpXG4gICAge1xuXG4gICAgICAgIGlmICghIHRoaXMuaGFzVmFyaWF0aW9ucygpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0gWy4uLnRoaXMuZm9ybUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltuYW1lXj0nYXR0cmlidXRlXyddXCIpXS5tYXAoXG4gICAgICAgICAgICAoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6ZWxlbWVudC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTplbGVtZW50Lm5hbWVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgIH1cblxuICAgIGhhc1ZhcmlhdGlvbnMoKVxuICAgIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybUVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCd2YXJpYXRpb25zX2Zvcm0nKTtcbiAgICB9XG5cbiAgICBpc0dyb3VwZWRQcm9kdWN0KClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnZ3JvdXBlZF9mb3JtJyk7XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXI7XG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgVXBkYXRlQ2FydCBmcm9tIFwiLi4vSGVscGVyL1VwZGF0ZUNhcnRcIjtcbmltcG9ydCBTaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlciBmcm9tIFwiLi4vQWN0aW9uSGFuZGxlci9TaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlclwiO1xuXG5jbGFzcyBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcykge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlcztcbiAgICB9XG5cblxuICAgIGhhbmRsZUNoYW5nZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG5cbiAgICBpbml0KCkge1xuXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuaGFuZGxlQ2hhbmdlLmJpbmQodGhpcykpXG5cbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcblxuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JykgIT09IG51bGwgJiYgIXRoaXMucHJpY2VBbW91bnRJc1plcm8oKTtcblxuICAgIH1cblxuICAgIHByaWNlQW1vdW50SXNaZXJvKCkge1xuXG4gICAgICAgIGxldCBwcmljZVRleHQgPSBcIjBcIjtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCBpbnMgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpKSB7XG4gICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnByb2R1Y3QgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpKSB7XG4gICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucHJvZHVjdCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykuaW5uZXJUZXh0O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlRmxvYXQocHJpY2VUZXh0LnJlcGxhY2UoLyhbXlxcZCxcXC5cXHNdKikvZywgJycpKTtcbiAgICAgICAgcmV0dXJuIGFtb3VudCA9PT0gMDtcblxuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgYWN0aW9uSGFuZGxlciA9IG5ldyBTaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBVcGRhdGVDYXJ0KFxuICAgICAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5hamF4LmNoYW5nZV9jYXJ0LmVuZHBvaW50LFxuICAgICAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5hamF4LmNoYW5nZV9jYXJ0Lm5vbmNlLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICBsZXQgcHJpY2VUZXh0ID0gXCIwXCI7XG4gICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCBpbnMgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIHByaWNlVGV4dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCBpbnMgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpLmlubmVyVGV4dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpLmlubmVyVGV4dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgYW1vdW50ID0gcGFyc2VJbnQocHJpY2VUZXh0LnJlcGxhY2UoLyhbXlxcZCxcXC5cXHNdKikvZywgJycpKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnJlbmRlcldpdGhBbW91bnQoYW1vdW50KVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQnKSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsXG4gICAgICAgICAgICBhY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RCb290c3RhcDtcbiIsImltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcbmltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcblxuY2xhc3MgQ2FydEJvb3RzdHJhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG4gICAgICAgIGlmICghdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3VwZGF0ZWRfY2FydF90b3RhbHMgdXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2FydEJvb3RzdHJhcDtcbiIsImNvbnN0IG9uQXBwcm92ZSA9IChjb250ZXh0LCBlcnJvckhhbmRsZXIsIHNwaW5uZXIpID0+IHtcbiAgICByZXR1cm4gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgc3Bpbm5lci5ibG9jaygpO1xuICAgICAgICBlcnJvckhhbmRsZXIuY2xlYXIoKTtcblxuICAgICAgICByZXR1cm4gZmV0Y2goY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICBub25jZTogY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgIG9yZGVyX2lkOmRhdGEub3JkZXJJRCxcbiAgICAgICAgICAgICAgICBmdW5kaW5nX3NvdXJjZTogd2luZG93LnBwY3BGdW5kaW5nU291cmNlLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgIH0pLnRoZW4oKGRhdGEpPT57XG4gICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuZGF0YS5jb2RlID09PSAxMDApIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLm1lc3NhZ2UoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhY3Rpb25zICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgYWN0aW9ucy5yZXN0YXJ0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5yZXN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcGxhY2Vfb3JkZXInKS5jbGljaygpXG4gICAgICAgIH0pO1xuXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBvbkFwcHJvdmU7XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yUGF5Tm93LmpzJztcbmltcG9ydCB7cGF5ZXJEYXRhfSBmcm9tIFwiLi4vSGVscGVyL1BheWVyRGF0YVwiO1xuaW1wb3J0IHtnZXRDdXJyZW50UGF5bWVudE1ldGhvZH0gZnJvbSBcIi4uL0hlbHBlci9DaGVja291dE1ldGhvZFN0YXRlXCI7XG5cbmNsYXNzIENoZWNrb3V0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMuc3Bpbm5lcjtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IHRoaXMuZXJyb3JIYW5kbGVyO1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtU2VsZWN0b3IgPSB0aGlzLmNvbmZpZy5jb250ZXh0ID09PSAnY2hlY2tvdXQnID8gJ2Zvcm0uY2hlY2tvdXQnIDogJ2Zvcm0jb3JkZXJfcmV2aWV3JztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSBqUXVlcnkoZm9ybVNlbGVjdG9yKS5zZXJpYWxpemUoKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlYWNjb3VudCA9IGpRdWVyeSgnI2NyZWF0ZWFjY291bnQnKS5pcyhcIjpjaGVja2VkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyX2lkOnRoaXMuY29uZmlnLm9yZGVyX2lkLFxuICAgICAgICAgICAgICAgICAgICBwYXltZW50X21ldGhvZDogZ2V0Q3VycmVudFBheW1lbnRNZXRob2QoKSxcbiAgICAgICAgICAgICAgICAgICAgZnVuZGluZ19zb3VyY2U6IHdpbmRvdy5wcGNwRnVuZGluZ1NvdXJjZSxcbiAgICAgICAgICAgICAgICAgICAgZm9ybTpmb3JtVmFsdWVzLFxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVhY2NvdW50OiBjcmVhdGVhY2NvdW50XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgICAgICAvL2hhbmRsZSBib3RoIG1lc3NhZ2VzIHNlbnQgZnJvbSBXb29jb21tZXJjZSAoZGF0YS5tZXNzYWdlcykgYW5kIHRoaXMgcGx1Z2luIChkYXRhLmRhdGEubWVzc2FnZSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZihkYXRhLm1lc3NhZ2VzKSAhPT0gJ3VuZGVmaW5lZCcgKVxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkb21QYXJzZXIgPSBuZXcgRE9NUGFyc2VyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuYXBwZW5kUHJlcGFyZWRFcnJvck1lc3NhZ2VFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbVBhcnNlci5wYXJzZUZyb21TdHJpbmcoZGF0YS5tZXNzYWdlcywgJ3RleHQvaHRtbCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5xdWVyeVNlbGVjdG9yKCd1bCcpXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmRldGFpbHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5tZXNzYWdlKGRhdGEuZGF0YS5kZXRhaWxzLm1hcChkID0+IGAke2QuaXNzdWV9ICR7ZC5kZXNjcmlwdGlvbn1gKS5qb2luKCc8YnIvPicpLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLm1lc3NhZ2UoZGF0YS5kYXRhLm1lc3NhZ2UsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd0eXBlJywgJ2hpZGRlbicpO1xuICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnbmFtZScsICdwcGNwLXJlc3VtZS1vcmRlcicpO1xuICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgndmFsdWUnLCBkYXRhLmRhdGEucHVyY2hhc2VfdW5pdHNbMF0uY3VzdG9tX2lkKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1TZWxlY3RvcikuYXBwZW5kKGlucHV0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOm9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciwgdGhpcy5zcGlubmVyKSxcbiAgICAgICAgICAgIG9uQ2FuY2VsOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb25FcnJvcjogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEFjdGlvbkhhbmRsZXI7XG4iLCJjb25zdCBnZXRFbGVtZW50ID0gKHNlbGVjdG9yT3JFbGVtZW50KSA9PiB7XG4gICAgaWYgKHR5cGVvZiBzZWxlY3Rvck9yRWxlbWVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3JPckVsZW1lbnQpO1xuICAgIH1cbiAgICByZXR1cm4gc2VsZWN0b3JPckVsZW1lbnQ7XG59XG5cbmV4cG9ydCBjb25zdCBpc1Zpc2libGUgPSAoZWxlbWVudCkgPT4ge1xuICAgIHJldHVybiAhIShlbGVtZW50Lm9mZnNldFdpZHRoIHx8IGVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IGVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGgpO1xufVxuXG5leHBvcnQgY29uc3Qgc2V0VmlzaWJsZSA9IChzZWxlY3Rvck9yRWxlbWVudCwgc2hvdywgaW1wb3J0YW50ID0gZmFsc2UpID0+IHtcbiAgICBjb25zdCBlbGVtZW50ID0gZ2V0RWxlbWVudChzZWxlY3Rvck9yRWxlbWVudCk7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSBlbGVtZW50LnN0eWxlLmdldFByb3BlcnR5VmFsdWUoJ2Rpc3BsYXknKTtcblxuICAgIGlmICghc2hvdykge1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlID09PSAnbm9uZScpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJ2Rpc3BsYXknLCAnbm9uZScsIGltcG9ydGFudCA/ICdpbXBvcnRhbnQnIDogJycpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPT09ICdub25lJykge1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgnZGlzcGxheScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gc3RpbGwgbm90IHZpc2libGUgKGlmIHNvbWV0aGluZyBlbHNlIGFkZGVkIGRpc3BsYXk6IG5vbmUgaW4gQ1NTKVxuICAgICAgICBpZiAoIWlzVmlzaWJsZShlbGVtZW50KSkge1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnZGlzcGxheScsICdibG9jaycpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGhpZGUgPSAoc2VsZWN0b3JPckVsZW1lbnQsIGltcG9ydGFudCA9IGZhbHNlKSA9PiB7XG4gICAgc2V0VmlzaWJsZShzZWxlY3Rvck9yRWxlbWVudCwgZmFsc2UsIGltcG9ydGFudCk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2hvdyA9IChzZWxlY3Rvck9yRWxlbWVudCkgPT4ge1xuICAgIHNldFZpc2libGUoc2VsZWN0b3JPckVsZW1lbnQsIHRydWUpO1xufTtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDaGVja291dEFjdGlvbkhhbmRsZXIgZnJvbSAnLi4vQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IHsgc2V0VmlzaWJsZSB9IGZyb20gJy4uL0hlbHBlci9IaWRpbmcnO1xuaW1wb3J0IHtcbiAgICBnZXRDdXJyZW50UGF5bWVudE1ldGhvZCxcbiAgICBpc1NhdmVkQ2FyZFNlbGVjdGVkLCBPUkRFUl9CVVRUT05fU0VMRUNUT1IsXG4gICAgUGF5bWVudE1ldGhvZHNcbn0gZnJvbSBcIi4uL0hlbHBlci9DaGVja291dE1ldGhvZFN0YXRlXCI7XG5cbmNsYXNzIENoZWNrb3V0Qm9vdHN0YXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcywgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlcztcbiAgICAgICAgdGhpcy5zcGlubmVyID0gc3Bpbm5lcjtcblxuICAgICAgICB0aGlzLnN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciA9IE9SREVSX0JVVFRPTl9TRUxFQ1RPUjtcblxuICAgICAgICB0aGlzLmJ1dHRvbkNoYW5nZU9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKGVsKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVVpKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICAgICAgLy8gVW5zZWxlY3Qgc2F2ZWQgY2FyZC5cbiAgICAgICAgLy8gV0Mgc2F2ZXMgZm9ybSB2YWx1ZXMsIHNvIHdpdGggb3VyIGN1cnJlbnQgVUkgaXQgd291bGQgYmUgYSBiaXQgd2VpcmRcbiAgICAgICAgLy8gaWYgdGhlIHVzZXIgcGFpZCB3aXRoIHNhdmVkLCB0aGVuIGFmdGVyIHNvbWUgdGltZSB0cmllcyB0byBwYXkgYWdhaW4sXG4gICAgICAgIC8vIGJ1dCB3YW50cyB0byBlbnRlciBhIG5ldyBjYXJkLCBhbmQgdG8gZG8gdGhhdCB0aGV5IGhhdmUgdG8gY2hvb3NlIOKAnFNlbGVjdCBwYXltZW504oCdIGluIHRoZSBsaXN0LlxuICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLnZhbChqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCBvcHRpb246Zmlyc3QnKS52YWwoKSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLm9uKCd1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKVxuICAgICAgICB9KTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3VwZGF0ZWRfY2hlY2tvdXQgcGF5bWVudF9tZXRob2Rfc2VsZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVVpKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudCkub24oJ2hvc3RlZF9maWVsZHNfbG9hZGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS5vbignY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24uY2FuY2VsX3dyYXBwZXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PSBudWxsIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcikgIT09IG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKSkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICAgICAgdGhpcy5zcGlubmVyXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5idXR0b25DaGFuZ2VPYnNlcnZlci5vYnNlcnZlKFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLnN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciksXG4gICAgICAgICAgICB7YXR0cmlidXRlczogdHJ1ZX1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICB1cGRhdGVVaSgpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFBheW1lbnRNZXRob2QgPSBnZXRDdXJyZW50UGF5bWVudE1ldGhvZCgpO1xuICAgICAgICBjb25zdCBpc1BheXBhbCA9IGN1cnJlbnRQYXltZW50TWV0aG9kID09PSBQYXltZW50TWV0aG9kcy5QQVlQQUw7XG4gICAgICAgIGNvbnN0IGlzQ2FyZCA9IGN1cnJlbnRQYXltZW50TWV0aG9kID09PSBQYXltZW50TWV0aG9kcy5DQVJEUztcbiAgICAgICAgY29uc3QgaXNTYXZlZENhcmQgPSBpc0NhcmQgJiYgaXNTYXZlZENhcmRTZWxlY3RlZCgpO1xuICAgICAgICBjb25zdCBpc05vdE91ckdhdGV3YXkgPSAhaXNQYXlwYWwgJiYgIWlzQ2FyZDtcbiAgICAgICAgY29uc3QgaXNGcmVlVHJpYWwgPSBQYXlQYWxDb21tZXJjZUdhdGV3YXkuaXNfZnJlZV90cmlhbF9jYXJ0O1xuICAgICAgICBjb25zdCBoYXNWYXVsdGVkUGF5cGFsID0gUGF5UGFsQ29tbWVyY2VHYXRld2F5LnZhdWx0ZWRfcGF5cGFsX2VtYWlsICE9PSAnJztcblxuICAgICAgICBzZXRWaXNpYmxlKHRoaXMuc3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yLCAgKGlzUGF5cGFsICYmIGlzRnJlZVRyaWFsICYmIGhhc1ZhdWx0ZWRQYXlwYWwpIHx8IGlzTm90T3VyR2F0ZXdheSB8fCBpc1NhdmVkQ2FyZCwgdHJ1ZSk7XG4gICAgICAgIHNldFZpc2libGUoJy5wcGNwLXZhdWx0ZWQtcGF5cGFsLWRldGFpbHMnLCBpc1BheXBhbCk7XG4gICAgICAgIHNldFZpc2libGUodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLCBpc1BheXBhbCAmJiAhKGlzRnJlZVRyaWFsICYmIGhhc1ZhdWx0ZWRQYXlwYWwpKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlciwgaXNQYXlwYWwgJiYgIWlzRnJlZVRyaWFsKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLCBpc0NhcmQgJiYgIWlzU2F2ZWRDYXJkKTtcblxuICAgICAgICBpZiAoaXNQYXlwYWwgJiYgIWlzRnJlZVRyaWFsKSB7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnJlbmRlcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQ2FyZCkge1xuICAgICAgICAgICAgaWYgKGlzU2F2ZWRDYXJkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRpc2FibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgdHJ1ZSlcbiAgICAgICAgdGhpcy5yZW5kZXJlci5kaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxuXG4gICAgZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpIHtcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXInKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeVwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjXCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJ2YXVsdFwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYXR0cihcImRpc2FibGVkXCIsIGZhbHNlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRCb290c3RhcFxuIiwiZXhwb3J0IGNvbnN0IGlzQ2hhbmdlUGF5bWVudFBhZ2UgPSAoKSA9PiB7XG4gICAgY29uc3QgdXJsUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKVxuICAgIHJldHVybiB1cmxQYXJhbXMuaGFzKCdjaGFuZ2VfcGF5bWVudF9tZXRob2QnKTtcbn1cbiIsImltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vQ2hlY2tvdXRCb290c3RhcCdcbmltcG9ydCB7aXNDaGFuZ2VQYXltZW50UGFnZX0gZnJvbSBcIi4uL0hlbHBlci9TdWJzY3JpcHRpb25zXCI7XG5cbmNsYXNzIFBheU5vd0Jvb3RzdHJhcCBleHRlbmRzIENoZWNrb3V0Qm9vdHN0YXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcywgc3Bpbm5lcikge1xuICAgICAgICBzdXBlcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpXG4gICAgfVxuXG4gICAgdXBkYXRlVWkoKSB7XG4gICAgICAgIGlmIChpc0NoYW5nZVBheW1lbnRQYWdlKCkpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgc3VwZXIudXBkYXRlVWkoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBheU5vd0Jvb3RzdHJhcDtcbiIsImNsYXNzIFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihjcmVkaXRDYXJkUmVuZGVyZXIsIGRlZmF1bHRDb25maWcsIG9uU21hcnRCdXR0b25DbGljaywgb25TbWFydEJ1dHRvbnNJbml0KSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWc7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyID0gY3JlZGl0Q2FyZFJlbmRlcmVyO1xuICAgICAgICB0aGlzLm9uU21hcnRCdXR0b25DbGljayA9IG9uU21hcnRCdXR0b25DbGljaztcbiAgICAgICAgdGhpcy5vblNtYXJ0QnV0dG9uc0luaXQgPSBvblNtYXJ0QnV0dG9uc0luaXQ7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICB0aGlzLnJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLnJlbmRlcihob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICB9XG5cbiAgICByZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSB8fCB0aGlzLmlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHx8ICd1bmRlZmluZWQnID09PSB0eXBlb2YgcGF5cGFsLkJ1dHRvbnMgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdHlsZSA9IHdyYXBwZXIgPT09IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ud3JhcHBlciA/IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24uc3R5bGUgOiB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLm1pbmlfY2FydF9zdHlsZTtcbiAgICAgICAgcGF5cGFsLkJ1dHRvbnMoe1xuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAuLi5jb250ZXh0Q29uZmlnLFxuICAgICAgICAgICAgb25DbGljazogdGhpcy5vblNtYXJ0QnV0dG9uQ2xpY2ssXG4gICAgICAgICAgICBvbkluaXQ6IHRoaXMub25TbWFydEJ1dHRvbnNJbml0LFxuICAgICAgICB9KS5yZW5kZXIod3JhcHBlcik7XG4gICAgfVxuXG4gICAgaXNBbHJlYWR5UmVuZGVyZWQod3JhcHBlcikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5oYXNDaGlsZE5vZGVzKCk7XG4gICAgfVxuXG4gICAgaGlkZUJ1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHNob3dCdXR0b25zKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgICAgIGlmICghIGRvbUVsZW1lbnQgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZG9tRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmRpc2FibGVGaWVsZHMoKTtcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5lbmFibGVGaWVsZHMoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlcmVyO1xuIiwiY29uc3QgZGNjSW5wdXRGYWN0b3J5ID0gKG9yaWdpbmFsKSA9PiB7XG4gICAgY29uc3Qgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUob3JpZ2luYWwpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2lkJywgb3JpZ2luYWwuaWQpO1xuICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzKS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICBpZiAoISBzdHlsZXNbcHJvcF0gfHwgISBpc05hTihwcm9wKSApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBuZXdFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KHByb3AsJycgKyBzdHlsZXNbcHJvcF0pO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBkY2NJbnB1dEZhY3Rvcnk7IiwiaW1wb3J0IGRjY0lucHV0RmFjdG9yeSBmcm9tIFwiLi4vSGVscGVyL0RjY0lucHV0RmFjdG9yeVwiO1xuaW1wb3J0IHtzaG93fSBmcm9tIFwiLi4vSGVscGVyL0hpZGluZ1wiO1xuXG5jbGFzcyBDcmVkaXRDYXJkUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoZGVmYXVsdENvbmZpZywgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZy5jb250ZXh0ICE9PSAnY2hlY2tvdXQnXG4gICAgICAgICAgICAgICAgJiYgdGhpcy5kZWZhdWx0Q29uZmlnLmNvbnRleHQgIT09ICdwYXktbm93J1xuICAgICAgICAgICAgKVxuICAgICAgICAgICAgfHwgd3JhcHBlciA9PT0gbnVsbFxuICAgICAgICAgICAgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSA9PT0gbnVsbFxuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlb2YgcGF5cGFsLkhvc3RlZEZpZWxkcyA9PT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgIHx8ICEgcGF5cGFsLkhvc3RlZEZpZWxkcy5pc0VsaWdpYmxlKClcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVyRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcik7XG4gICAgICAgICAgICB3cmFwcGVyRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHdyYXBwZXJFbGVtZW50KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGJ1dHRvblNlbGVjdG9yID0gd3JhcHBlciArICcgYnV0dG9uJztcblxuICAgICAgICBpZiAodGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnRlYXJkb3duKClcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoYEhvc3RlZCBmaWVsZHMgdGVhcmRvd24gZXJyb3I6ICR7ZXJyfWApKTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGdhdGVXYXlCb3ggPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGF5bWVudF9ib3gucGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5Jyk7XG4gICAgICAgIGlmKCEgZ2F0ZVdheUJveCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb2xkRGlzcGxheVN0eWxlID0gZ2F0ZVdheUJveC5zdHlsZS5kaXNwbGF5O1xuICAgICAgICBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXG4gICAgICAgIGNvbnN0IGhpZGVEY2NHYXRld2F5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtaGlkZS1kY2MnKTtcbiAgICAgICAgaWYgKGhpZGVEY2NHYXRld2F5KSB7XG4gICAgICAgICAgICBoaWRlRGNjR2F0ZXdheS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGhpZGVEY2NHYXRld2F5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNhcmROdW1iZXJGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXInKTtcblxuICAgICAgICBjb25zdCBzdHlsZXNSYXcgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBsZXQgc3R5bGVzID0ge307XG4gICAgICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzUmF3KS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICAgICAgaWYgKCEgc3R5bGVzUmF3W3Byb3BdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3R5bGVzW3Byb3BdID0gJycgKyBzdHlsZXNSYXdbcHJvcF07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNhcmROdW1iZXIgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZE51bWJlckZpZWxkKTtcbiAgICAgICAgY2FyZE51bWJlckZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmROdW1iZXIsIGNhcmROdW1iZXJGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZEV4cGlyeUZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeScpO1xuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5ID0gZGNjSW5wdXRGYWN0b3J5KGNhcmRFeHBpcnlGaWVsZCk7XG4gICAgICAgIGNhcmRFeHBpcnlGaWVsZC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjYXJkRXhwaXJ5LCBjYXJkRXhwaXJ5RmllbGQpO1xuXG4gICAgICAgIGNvbnN0IGNhcmRDb2RlRmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyk7XG4gICAgICAgIGNvbnN0IGNhcmRDb2RlID0gZGNjSW5wdXRGYWN0b3J5KGNhcmRDb2RlRmllbGQpO1xuICAgICAgICBjYXJkQ29kZUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRDb2RlLCBjYXJkQ29kZUZpZWxkKTtcblxuICAgICAgICBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXkgPSBvbGREaXNwbGF5U3R5bGU7XG5cbiAgICAgICAgY29uc3QgZm9ybVdyYXBwZXIgPSAnLnBheW1lbnRfYm94IHBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheSc7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZy5lbmZvcmNlX3ZhdWx0XG4gICAgICAgICAgICAmJiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpXG4gICAgICAgICkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5jaGVja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0Jykuc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHBheXBhbC5Ib3N0ZWRGaWVsZHMucmVuZGVyKHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiBjb250ZXh0Q29uZmlnLmNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgc3R5bGVzOiB7XG4gICAgICAgICAgICAgICAgJ2lucHV0Jzogc3R5bGVzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgICAgICAgbnVtYmVyOiB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yOiAnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuY3JlZGl0X2NhcmRfbnVtYmVyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY3Z2OiB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yOiAnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuY3Z2LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXhwaXJhdGlvbkRhdGU6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5tbV95eSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pLnRoZW4oaG9zdGVkRmllbGRzID0+IHtcbiAgICAgICAgICAgIGRvY3VtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwiaG9zdGVkX2ZpZWxkc19sb2FkZWRcIikpO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UgPSBob3N0ZWRGaWVsZHM7XG5cbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbignaW5wdXRTdWJtaXRSZXF1ZXN0JywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N1Ym1pdChjb250ZXh0Q29uZmlnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdjYXJkVHlwZUNoYW5nZScsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICggISBldmVudC5jYXJkcy5sZW5ndGggKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FyZFZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsaWRDYXJkcyA9IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLnZhbGlkX2NhcmRzO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FyZFZhbGlkID0gdmFsaWRDYXJkcy5pbmRleE9mKGV2ZW50LmNhcmRzWzBdLnR5cGUpICE9PSAtMTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ3ZhbGlkaXR5Q2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZm9ybVZhbGlkID0gT2JqZWN0LmtleXMoZXZlbnQuZmllbGRzKS5ldmVyeShmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBldmVudC5maWVsZHNba2V5XS5pc1ZhbGlkO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWQgPSBmb3JtVmFsaWQ7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBzaG93KGJ1dHRvblNlbGVjdG9yKTtcblxuICAgICAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikuZ2V0QXR0cmlidXRlKCdkYXRhLXBwY3Atc3Vic2NyaWJlZCcpICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihidXR0b25TZWxlY3RvcikuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAgICAgJ2NsaWNrJyxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N1Ym1pdChjb250ZXh0Q29uZmlnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpLnNldEF0dHJpYnV0ZSgnZGF0YS1wcGNwLXN1YnNjcmliZWQnLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2xhYmVsW2Zvcj1wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJdJykuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgIH1cblxuICAgIGRpc2FibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmFibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc3VibWl0KGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5zcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZm9ybVZhbGlkICYmIHRoaXMuY2FyZFZhbGlkKSB7XG4gICAgICAgICAgICBjb25zdCBzYXZlX2NhcmQgPSB0aGlzLmRlZmF1bHRDb25maWcuY2FuX3NhdmVfdmF1bHRfdG9rZW4gPyB0cnVlIDogZmFsc2U7XG4gICAgICAgICAgICBsZXQgdmF1bHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpID9cbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgOiBzYXZlX2NhcmQ7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHQpIHtcbiAgICAgICAgICAgICAgICB2YXVsdCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb250aW5nZW5jeSA9IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmNvbnRpbmdlbmN5O1xuICAgICAgICAgICAgY29uc3QgaG9zdGVkRmllbGRzRGF0YSA9IHtcbiAgICAgICAgICAgICAgICB2YXVsdDogdmF1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoY29udGluZ2VuY3kgIT09ICdOT18zRF9TRUNVUkUnKSB7XG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jb250aW5nZW5jaWVzID0gW2NvbnRpbmdlbmN5XTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbmZpZy5wYXllcikge1xuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY2FyZGhvbGRlck5hbWUgPSB0aGlzLmRlZmF1bHRDb25maWcucGF5ZXIubmFtZS5naXZlbl9uYW1lICsgJyAnICsgdGhpcy5kZWZhdWx0Q29uZmlnLnBheWVyLm5hbWUuc3VybmFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaG9zdGVkRmllbGRzRGF0YS5jYXJkaG9sZGVyTmFtZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0TmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2ZpcnN0X25hbWUnKSA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2ZpcnN0X25hbWUnKS52YWx1ZSA6ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhc3ROYW1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JpbGxpbmdfbGFzdF9uYW1lJykgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6ICcnO1xuXG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jYXJkaG9sZGVyTmFtZSA9IGZpcnN0TmFtZSArICcgJyArIGxhc3ROYW1lO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zdWJtaXQoaG9zdGVkRmllbGRzRGF0YSkudGhlbigocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgIHBheWxvYWQub3JkZXJJRCA9IHBheWxvYWQub3JkZXJJZDtcbiAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0Q29uZmlnLm9uQXBwcm92ZShwYXlsb2FkKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5kZXRhaWxzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UoZXJyLmRldGFpbHMubWFwKGQgPT4gYCR7ZC5pc3N1ZX0gJHtkLmRlc2NyaXB0aW9ufWApLmpvaW4oJzxici8+JyksIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSAhIHRoaXMuY2FyZFZhbGlkID8gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNhcmRfbm90X3N1cHBvcnRlZCA6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5maWVsZHNfbm90X3ZhbGlkO1xuICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IENyZWRpdENhcmRSZW5kZXJlcjtcbiIsImNvbnN0IHN0b3JhZ2VLZXkgPSAncHBjcC1kYXRhLWNsaWVudC1pZCc7XG5cbmNvbnN0IHZhbGlkYXRlVG9rZW4gPSAodG9rZW4sIHVzZXIpID0+IHtcbiAgICBpZiAoISB0b2tlbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0b2tlbi51c2VyICE9PSB1c2VyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBpc0V4cGlyZWQgPSBjdXJyZW50VGltZSA+PSB0b2tlbi5leHBpcmF0aW9uICogMTAwMDtcbiAgICByZXR1cm4gISBpc0V4cGlyZWQ7XG59XG5cbmNvbnN0IHN0b3JlZFRva2VuRm9yVXNlciA9ICh1c2VyKSA9PiB7XG4gICAgY29uc3QgdG9rZW4gPSBKU09OLnBhcnNlKHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oc3RvcmFnZUtleSkpO1xuICAgIGlmICh2YWxpZGF0ZVRva2VuKHRva2VuLCB1c2VyKSkge1xuICAgICAgICByZXR1cm4gdG9rZW4udG9rZW47XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBzdG9yZVRva2VuID0gKHRva2VuKSA9PiB7XG4gICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeSh0b2tlbikpO1xufVxuXG5jb25zdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyID0gKHNjcmlwdCwgY29uZmlnKSA9PiB7XG4gICAgZmV0Y2goY29uZmlnLmVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBub25jZTogY29uZmlnLm5vbmNlXG4gICAgICAgIH0pXG4gICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICB9KS50aGVuKChkYXRhKT0+e1xuICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdGVUb2tlbihkYXRhLCBjb25maWcudXNlcik7XG4gICAgICAgIGlmICghaXNWYWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0b3JlVG9rZW4oZGF0YSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtY2xpZW50LXRva2VuJywgZGF0YS50b2tlbik7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKHNjcmlwdCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXI7XG4iLCJjbGFzcyBNZXNzYWdlUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGF5cGFsLk1lc3NhZ2VzKHtcbiAgICAgICAgICAgIGFtb3VudDogdGhpcy5jb25maWcuYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscycsICgpID0+IHtcbiAgICAgICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICAgICAgYW1vdW50OiB0aGlzLmNvbmZpZy5hbW91bnQsXG4gICAgICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHRoaXMuY29uZmlnLnN0eWxlXG4gICAgICAgICAgICB9KS5yZW5kZXIodGhpcy5jb25maWcud3JhcHBlcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJlbmRlcldpdGhBbW91bnQoYW1vdW50KSB7XG5cbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3V3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBuZXdXcmFwcGVyLnNldEF0dHJpYnV0ZSgnaWQnLCB0aGlzLmNvbmZpZy53cmFwcGVyLnJlcGxhY2UoJyMnLCAnJykpO1xuXG4gICAgICAgIGNvbnN0IHNpYmxpbmcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLm5leHRTaWJsaW5nO1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSk7XG4gICAgICAgIHNpYmxpbmcucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUobmV3V3JhcHBlciwgc2libGluZyk7XG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgICBwbGFjZW1lbnQ6IHRoaXMuY29uZmlnLnBsYWNlbWVudCxcbiAgICAgICAgICAgIHN0eWxlOiB0aGlzLmNvbmZpZy5zdHlsZVxuICAgICAgICB9KS5yZW5kZXIodGhpcy5jb25maWcud3JhcHBlcik7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuXG4gICAgICAgIGlmICh0eXBlb2YgcGF5cGFsLk1lc3NhZ2VzID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgdGhpcy5jb25maWcud3JhcHBlciA9PT0gJ3VuZGVmaW5lZCcgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IE1lc3NhZ2VSZW5kZXJlcjtcbiIsImNsYXNzIFNwaW5uZXIge1xuXG4gICAgY29uc3RydWN0b3IodGFyZ2V0ID0gJ2Zvcm0ud29vY29tbWVyY2UtY2hlY2tvdXQnKSB7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIH1cblxuICAgIHNldFRhcmdldCh0YXJnZXQpIHtcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gICAgfVxuXG4gICAgYmxvY2soKSB7XG5cbiAgICAgICAgalF1ZXJ5KCB0aGlzLnRhcmdldCApLmJsb2NrKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IG51bGwsXG4gICAgICAgICAgICBvdmVybGF5Q1NTOiB7XG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJyNmZmYnLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAuNlxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmJsb2NrKCkge1xuXG4gICAgICAgIGpRdWVyeSggdGhpcy50YXJnZXQgKS51bmJsb2NrKCk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTcGlubmVyO1xuIiwiaW1wb3J0IHtQYXltZW50TWV0aG9kc30gZnJvbSBcIi4uL0hlbHBlci9DaGVja291dE1ldGhvZFN0YXRlXCI7XG5pbXBvcnQgZXJyb3JIYW5kbGVyIGZyb20gXCIuLi9FcnJvckhhbmRsZXJcIjtcblxuY2xhc3MgRnJlZVRyaWFsSGFuZGxlciB7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgc3Bpbm5lcixcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBoYW5kbGUoKVxuICAgIHtcbiAgICAgICAgdGhpcy5zcGlubmVyLmJsb2NrKCk7XG5cbiAgICAgICAgZmV0Y2godGhpcy5jb25maWcuYWpheC52YXVsdF9wYXlwYWwuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LnZhdWx0X3BheXBhbC5ub25jZSxcbiAgICAgICAgICAgICAgICByZXR1cm5fdXJsOiBsb2NhdGlvbi5ocmVmXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfSkudGhlbihyZXMgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgIH0pLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5tZXNzYWdlKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxvY2F0aW9uLmhyZWYgPSBkYXRhLmRhdGEuYXBwcm92ZV9saW5rO1xuICAgICAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgRnJlZVRyaWFsSGFuZGxlcjtcbiIsImltcG9ydCBNaW5pQ2FydEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL01pbmlDYXJ0Qm9vdHN0YXAnO1xuaW1wb3J0IFNpbmdsZVByb2R1Y3RCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAnO1xuaW1wb3J0IENhcnRCb290c3RyYXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2FydEJvb3RzdGFwJztcbmltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAnO1xuaW1wb3J0IFBheU5vd0Jvb3RzdHJhcCBmcm9tIFwiLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwXCI7XG5pbXBvcnQgUmVuZGVyZXIgZnJvbSAnLi9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyJztcbmltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi9tb2R1bGVzL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ3JlZGl0Q2FyZFJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyXCI7XG5pbXBvcnQgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciBmcm9tIFwiLi9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXJcIjtcbmltcG9ydCBNZXNzYWdlUmVuZGVyZXIgZnJvbSBcIi4vbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXJcIjtcbmltcG9ydCBTcGlubmVyIGZyb20gXCIuL21vZHVsZXMvSGVscGVyL1NwaW5uZXJcIjtcbmltcG9ydCB7XG4gICAgZ2V0Q3VycmVudFBheW1lbnRNZXRob2QsXG4gICAgT1JERVJfQlVUVE9OX1NFTEVDVE9SLFxuICAgIFBheW1lbnRNZXRob2RzXG59IGZyb20gXCIuL21vZHVsZXMvSGVscGVyL0NoZWNrb3V0TWV0aG9kU3RhdGVcIjtcbmltcG9ydCB7aGlkZSwgc2V0VmlzaWJsZX0gZnJvbSBcIi4vbW9kdWxlcy9IZWxwZXIvSGlkaW5nXCI7XG5pbXBvcnQge2lzQ2hhbmdlUGF5bWVudFBhZ2V9IGZyb20gXCIuL21vZHVsZXMvSGVscGVyL1N1YnNjcmlwdGlvbnNcIjtcbmltcG9ydCBGcmVlVHJpYWxIYW5kbGVyIGZyb20gXCIuL21vZHVsZXMvQWN0aW9uSGFuZGxlci9GcmVlVHJpYWxIYW5kbGVyXCI7XG5cbmNvbnN0IGJ1dHRvbnNTcGlubmVyID0gbmV3IFNwaW5uZXIoJy5wcGMtYnV0dG9uLXdyYXBwZXInKTtcbmNvbnN0IGNhcmRzU3Bpbm5lciA9IG5ldyBTcGlubmVyKCcjcHBjcC1ob3N0ZWQtZmllbGRzJyk7XG5cbmNvbnN0IGJvb3RzdHJhcCA9ICgpID0+IHtcbiAgICBjb25zdCBlcnJvckhhbmRsZXIgPSBuZXcgRXJyb3JIYW5kbGVyKFBheVBhbENvbW1lcmNlR2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyk7XG4gICAgY29uc3Qgc3Bpbm5lciA9IG5ldyBTcGlubmVyKCk7XG4gICAgY29uc3QgY3JlZGl0Q2FyZFJlbmRlcmVyID0gbmV3IENyZWRpdENhcmRSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXksIGVycm9ySGFuZGxlciwgc3Bpbm5lcik7XG5cbiAgICBjb25zdCBmcmVlVHJpYWxIYW5kbGVyID0gbmV3IEZyZWVUcmlhbEhhbmRsZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5LCBzcGlubmVyLCBlcnJvckhhbmRsZXIpO1xuXG4gICAgY29uc3Qgb25TbWFydEJ1dHRvbkNsaWNrID0gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgd2luZG93LnBwY3BGdW5kaW5nU291cmNlID0gZGF0YS5mdW5kaW5nU291cmNlO1xuXG4gICAgICAgIGNvbnN0IGZvcm0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLndvb2NvbW1lcmNlLWNoZWNrb3V0Jyk7XG4gICAgICAgIGlmIChmb3JtKSB7XG4gICAgICAgICAgICBqUXVlcnkoJyNwcGNwLWZ1bmRpbmctc291cmNlLWZvcm0taW5wdXQnKS5yZW1vdmUoKTtcbiAgICAgICAgICAgIGZvcm0uaW5zZXJ0QWRqYWNlbnRIVE1MKFxuICAgICAgICAgICAgICAgICdiZWZvcmVlbmQnLFxuICAgICAgICAgICAgICAgIGA8aW5wdXQgdHlwZT1cImhpZGRlblwiIG5hbWU9XCJwcGNwLWZ1bmRpbmctc291cmNlXCIgdmFsdWU9XCIke2RhdGEuZnVuZGluZ1NvdXJjZX1cIiBpZD1cInBwY3AtZnVuZGluZy1zb3VyY2UtZm9ybS1pbnB1dFwiPmBcbiAgICAgICAgICAgIClcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlzRnJlZVRyaWFsID0gUGF5UGFsQ29tbWVyY2VHYXRld2F5LmlzX2ZyZWVfdHJpYWxfY2FydDtcbiAgICAgICAgaWYgKGlzRnJlZVRyaWFsICYmIGRhdGEuZnVuZGluZ1NvdXJjZSAhPT0gJ2NhcmQnKSB7XG4gICAgICAgICAgICBmcmVlVHJpYWxIYW5kbGVyLmhhbmRsZSgpO1xuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbnMucmVqZWN0KCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IG9uU21hcnRCdXR0b25zSW5pdCA9ICgpID0+IHtcbiAgICAgICAgYnV0dG9uc1NwaW5uZXIudW5ibG9jaygpO1xuICAgIH07XG4gICAgY29uc3QgcmVuZGVyZXIgPSBuZXcgUmVuZGVyZXIoY3JlZGl0Q2FyZFJlbmRlcmVyLCBQYXlQYWxDb21tZXJjZUdhdGV3YXksIG9uU21hcnRCdXR0b25DbGljaywgb25TbWFydEJ1dHRvbnNJbml0KTtcbiAgICBjb25zdCBtZXNzYWdlUmVuZGVyZXIgPSBuZXcgTWVzc2FnZVJlbmRlcmVyKFBheVBhbENvbW1lcmNlR2F0ZXdheS5tZXNzYWdlcyk7XG4gICAgY29uc3QgY29udGV4dCA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5jb250ZXh0O1xuICAgIGlmIChjb250ZXh0ID09PSAnbWluaS1jYXJ0JyB8fCBjb250ZXh0ID09PSAncHJvZHVjdCcpIHtcbiAgICAgICAgaWYgKFBheVBhbENvbW1lcmNlR2F0ZXdheS5taW5pX2NhcnRfYnV0dG9uc19lbmFibGVkID09PSAnMScpIHtcbiAgICAgICAgICAgIGNvbnN0IG1pbmlDYXJ0Qm9vdHN0cmFwID0gbmV3IE1pbmlDYXJ0Qm9vdHN0YXAoXG4gICAgICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgICAgIHJlbmRlcmVyXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBtaW5pQ2FydEJvb3RzdHJhcC5pbml0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ3Byb2R1Y3QnICYmIFBheVBhbENvbW1lcmNlR2F0ZXdheS5zaW5nbGVfcHJvZHVjdF9idXR0b25zX2VuYWJsZWQgPT09ICcxJykge1xuICAgICAgICBjb25zdCBzaW5nbGVQcm9kdWN0Qm9vdHN0cmFwID0gbmV3IFNpbmdsZVByb2R1Y3RCb290c3RhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICAgICAgbWVzc2FnZVJlbmRlcmVyLFxuICAgICAgICApO1xuXG4gICAgICAgIHNpbmdsZVByb2R1Y3RCb290c3RyYXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAnY2FydCcpIHtcbiAgICAgICAgY29uc3QgY2FydEJvb3RzdHJhcCA9IG5ldyBDYXJ0Qm9vdHN0cmFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICk7XG5cbiAgICAgICAgY2FydEJvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdjaGVja291dCcpIHtcbiAgICAgICAgY29uc3QgY2hlY2tvdXRCb290c3RhcCA9IG5ldyBDaGVja291dEJvb3RzdGFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICAgICBzcGlubmVyXG4gICAgICAgICk7XG5cbiAgICAgICAgY2hlY2tvdXRCb290c3RhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdwYXktbm93JyApIHtcbiAgICAgICAgY29uc3QgcGF5Tm93Qm9vdHN0cmFwID0gbmV3IFBheU5vd0Jvb3RzdHJhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICAgICAgbWVzc2FnZVJlbmRlcmVyLFxuICAgICAgICAgICAgc3Bpbm5lclxuICAgICAgICApO1xuICAgICAgICBwYXlOb3dCb290c3RyYXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ICE9PSAnY2hlY2tvdXQnKSB7XG4gICAgICAgIG1lc3NhZ2VSZW5kZXJlci5yZW5kZXIoKTtcbiAgICB9XG59O1xuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAnRE9NQ29udGVudExvYWRlZCcsXG4gICAgKCkgPT4ge1xuICAgICAgICBpZiAoIXR5cGVvZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5KSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignUGF5UGFsIGJ1dHRvbiBjb3VsZCBub3QgYmUgY29uZmlndXJlZC4nKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheS5jb250ZXh0ICE9PSAnY2hlY2tvdXQnXG4gICAgICAgICAgICAmJiBQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQudXNlciA9PT0gMFxuICAgICAgICAgICAgJiYgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkLmhhc19zdWJzY3JpcHRpb25zXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU29tZXRpbWVzIFBheVBhbCBzY3JpcHQgdGFrZXMgbG9uZyB0aW1lIHRvIGxvYWQsXG4gICAgICAgIC8vIHNvIHdlIGFkZGl0aW9uYWxseSBoaWRlIHRoZSBzdGFuZGFyZCBvcmRlciBidXR0b24gaGVyZSB0byBhdm9pZCBmYWlsZWQgb3JkZXJzLlxuICAgICAgICAvLyBOb3JtYWxseSBpdCBpcyBoaWRkZW4gbGF0ZXIgYWZ0ZXIgdGhlIHNjcmlwdCBsb2FkLlxuICAgICAgICBjb25zdCBoaWRlT3JkZXJCdXR0b25JZlBwY3BHYXRld2F5ID0gKCkgPT4ge1xuICAgICAgICAgICAgLy8gb25seSBpbiBjaGVja291dCBhbmQgcGF5IG5vdyBwYWdlLCBvdGhlcndpc2UgaXQgbWF5IGJyZWFrIHRoaW5ncyAoZS5nLiBwYXltZW50IHZpYSBwcm9kdWN0IHBhZ2UpLFxuICAgICAgICAgICAgLy8gYW5kIGFsc28gdGhlIGxvYWRpbmcgc3Bpbm5lciBtYXkgbG9vayB3ZWlyZCBvbiBvdGhlciBwYWdlc1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICFbJ2NoZWNrb3V0JywgJ3BheS1ub3cnXS5pbmNsdWRlcyhQYXlQYWxDb21tZXJjZUdhdGV3YXkuY29udGV4dClcbiAgICAgICAgICAgICAgICB8fCBpc0NoYW5nZVBheW1lbnRQYWdlKClcbiAgICAgICAgICAgICAgICB8fCAoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmlzX2ZyZWVfdHJpYWxfY2FydCAmJiBQYXlQYWxDb21tZXJjZUdhdGV3YXkudmF1bHRlZF9wYXlwYWxfZW1haWwgIT09ICcnKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IGdldEN1cnJlbnRQYXltZW50TWV0aG9kKCk7XG4gICAgICAgICAgICBjb25zdCBpc1BheXBhbCA9IGN1cnJlbnRQYXltZW50TWV0aG9kID09PSBQYXltZW50TWV0aG9kcy5QQVlQQUw7XG4gICAgICAgICAgICBjb25zdCBpc0NhcmRzID0gY3VycmVudFBheW1lbnRNZXRob2QgPT09IFBheW1lbnRNZXRob2RzLkNBUkRTO1xuXG4gICAgICAgICAgICBzZXRWaXNpYmxlKE9SREVSX0JVVFRPTl9TRUxFQ1RPUiwgIWlzUGF5cGFsICYmICFpc0NhcmRzLCB0cnVlKTtcblxuICAgICAgICAgICAgaWYgKGlzUGF5cGFsKSB7XG4gICAgICAgICAgICAgICAgLy8gc3RvcHBlZCBhZnRlciB0aGUgZmlyc3QgcmVuZGVyaW5nIG9mIHRoZSBidXR0b25zLCBpbiBvbkluaXRcbiAgICAgICAgICAgICAgICBidXR0b25zU3Bpbm5lci5ibG9jaygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBidXR0b25zU3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0NhcmRzKSB7XG4gICAgICAgICAgICAgICAgY2FyZHNTcGlubmVyLmJsb2NrKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhcmRzU3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQpLm9uKCdob3N0ZWRfZmllbGRzX2xvYWRlZCcsICgpID0+IHtcbiAgICAgICAgICAgIGNhcmRzU3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGxldCBib290c3RyYXBwZWQgPSBmYWxzZTtcblxuICAgICAgICBoaWRlT3JkZXJCdXR0b25JZlBwY3BHYXRld2F5KCk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLm9uKCd1cGRhdGVkX2NoZWNrb3V0IHBheW1lbnRfbWV0aG9kX3NlbGVjdGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGJvb3RzdHJhcHBlZCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaGlkZU9yZGVyQnV0dG9uSWZQcGNwR2F0ZXdheSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgICAgc2NyaXB0LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGJvb3RzdHJhcHBlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGJvb3RzdHJhcCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgc2NyaXB0LnNldEF0dHJpYnV0ZSgnc3JjJywgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmJ1dHRvbi51cmwpO1xuICAgICAgICBPYmplY3QuZW50cmllcyhQYXlQYWxDb21tZXJjZUdhdGV3YXkuc2NyaXB0X2F0dHJpYnV0ZXMpLmZvckVhY2goXG4gICAgICAgICAgICAoa2V5VmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKGtleVZhbHVlWzBdLCBrZXlWYWx1ZVsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZC5zZXRfYXR0cmlidXRlKSB7XG4gICAgICAgICAgICBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyKHNjcmlwdCwgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKHNjcmlwdCk7XG4gICAgfSxcbik7XG4iXSwibmFtZXMiOlsiRXJyb3JIYW5kbGVyIiwiY29uc3RydWN0b3IiLCJnZW5lcmljRXJyb3JUZXh0Iiwid3JhcHBlciIsImRvY3VtZW50IiwicXVlcnlTZWxlY3RvciIsIm1lc3NhZ2VzTGlzdCIsImdlbmVyaWNFcnJvciIsImNsYXNzTGlzdCIsImNvbnRhaW5zIiwiY2xlYXIiLCJtZXNzYWdlIiwiYXBwZW5kUHJlcGFyZWRFcnJvck1lc3NhZ2VFbGVtZW50IiwiZXJyb3JNZXNzYWdlRWxlbWVudCIsInByZXBhcmVNZXNzYWdlc0xpc3QiLCJyZXBsYWNlV2l0aCIsInRleHQiLCJwZXJzaXN0IiwiU3RyaW5nIiwibGVuZ3RoIiwiRXJyb3IiLCJhZGQiLCJyZW1vdmUiLCJtZXNzYWdlTm9kZSIsInByZXBhcmVNZXNzYWdlc0xpc3RJdGVtIiwiYXBwZW5kQ2hpbGQiLCJqUXVlcnkiLCJzY3JvbGxfdG9fbm90aWNlcyIsImNyZWF0ZUVsZW1lbnQiLCJzZXRBdHRyaWJ1dGUiLCJsaSIsImlubmVySFRNTCIsInNhbml0aXplIiwidGV4dGFyZWEiLCJ2YWx1ZSIsInJlcGxhY2UiLCJvbkFwcHJvdmUiLCJjb250ZXh0IiwiZXJyb3JIYW5kbGVyIiwiZGF0YSIsImFjdGlvbnMiLCJmZXRjaCIsImNvbmZpZyIsImFqYXgiLCJhcHByb3ZlX29yZGVyIiwiZW5kcG9pbnQiLCJtZXRob2QiLCJib2R5IiwiSlNPTiIsInN0cmluZ2lmeSIsIm5vbmNlIiwib3JkZXJfaWQiLCJvcmRlcklEIiwiZnVuZGluZ19zb3VyY2UiLCJ3aW5kb3ciLCJwcGNwRnVuZGluZ1NvdXJjZSIsInRoZW4iLCJyZXMiLCJqc29uIiwic3VjY2VzcyIsInJlc3RhcnQiLCJjYXRjaCIsImVyciIsImxvY2F0aW9uIiwiaHJlZiIsInJlZGlyZWN0IiwicGF5ZXJEYXRhIiwicGF5ZXIiLCJQYXlQYWxDb21tZXJjZUdhdGV3YXkiLCJwaG9uZSIsInBob25lX3R5cGUiLCJwaG9uZV9udW1iZXIiLCJuYXRpb25hbF9udW1iZXIiLCJlbWFpbF9hZGRyZXNzIiwibmFtZSIsInN1cm5hbWUiLCJnaXZlbl9uYW1lIiwiYWRkcmVzcyIsImNvdW50cnlfY29kZSIsImFkZHJlc3NfbGluZV8xIiwiYWRkcmVzc19saW5lXzIiLCJhZG1pbl9hcmVhXzEiLCJhZG1pbl9hcmVhXzIiLCJwb3N0YWxfY29kZSIsIlBheW1lbnRNZXRob2RzIiwiUEFZUEFMIiwiQ0FSRFMiLCJPUkRFUl9CVVRUT05fU0VMRUNUT1IiLCJnZXRDdXJyZW50UGF5bWVudE1ldGhvZCIsImVsIiwiaXNTYXZlZENhcmRTZWxlY3RlZCIsInNhdmVkQ2FyZExpc3QiLCJDYXJ0QWN0aW9uSGFuZGxlciIsImNvbmZpZ3VyYXRpb24iLCJjcmVhdGVPcmRlciIsImJuQ29kZSIsImJuX2NvZGVzIiwiY3JlYXRlX29yZGVyIiwicHVyY2hhc2VfdW5pdHMiLCJwYXltZW50X21ldGhvZCIsImJuX2NvZGUiLCJjb25zb2xlIiwiZXJyb3IiLCJpZCIsIm9uRXJyb3IiLCJNaW5pQ2FydEJvb3RzdGFwIiwiZ2F0ZXdheSIsInJlbmRlcmVyIiwiYWN0aW9uSGFuZGxlciIsImluaXQiLCJsYWJlbHMiLCJnZW5lcmljIiwicmVuZGVyIiwib24iLCJzaG91bGRSZW5kZXIiLCJidXR0b24iLCJtaW5pX2NhcnRfd3JhcHBlciIsImhvc3RlZF9maWVsZHMiLCJQcm9kdWN0IiwiVXBkYXRlQ2FydCIsInVwZGF0ZSIsIm9uUmVzb2x2ZSIsInByb2R1Y3RzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJyZXN1bHQiLCJyZXNvbHZlZCIsIkJ1dHRvbnNUb2dnbGVMaXN0ZW5lciIsImVsZW1lbnQiLCJzaG93Q2FsbGJhY2siLCJoaWRlQ2FsbGJhY2siLCJvYnNlcnZlciIsImF0dHJpYnV0ZXMiLCJjYWxsYmFjayIsIk11dGF0aW9uT2JzZXJ2ZXIiLCJvYnNlcnZlIiwiZGlzY29ubmVjdCIsInF1YW50aXR5IiwidmFyaWF0aW9ucyIsIlNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIiwidXBkYXRlQ2FydCIsInNob3dCdXR0b25DYWxsYmFjayIsImhpZGVCdXR0b25DYWxsYmFjayIsImZvcm1FbGVtZW50IiwiaGFzVmFyaWF0aW9ucyIsImdldFByb2R1Y3RzIiwiaXNHcm91cGVkUHJvZHVjdCIsInF0eSIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJmb3JFYWNoIiwiZWxlbWVudE5hbWUiLCJnZXRBdHRyaWJ1dGUiLCJtYXRjaCIsInBhcnNlSW50IiwicHVzaCIsInByb21pc2UiLCJtYXAiLCJTaW5nbGVQcm9kdWN0Qm9vdHN0YXAiLCJtZXNzYWdlcyIsImhhbmRsZUNoYW5nZSIsImhpZGVCdXR0b25zIiwiYWRkRXZlbnRMaXN0ZW5lciIsImJpbmQiLCJwcmljZUFtb3VudElzWmVybyIsInByaWNlVGV4dCIsImlubmVyVGV4dCIsImFtb3VudCIsInBhcnNlRmxvYXQiLCJjaGFuZ2VfY2FydCIsInNob3dCdXR0b25zIiwicmVuZGVyV2l0aEFtb3VudCIsIkNhcnRCb290c3RyYXAiLCJzcGlubmVyIiwiYmxvY2siLCJ1bmJsb2NrIiwiY29kZSIsImNsaWNrIiwiQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIiwiZm9ybVNlbGVjdG9yIiwiZm9ybVZhbHVlcyIsInNlcmlhbGl6ZSIsImNyZWF0ZWFjY291bnQiLCJpcyIsImZvcm0iLCJkb21QYXJzZXIiLCJET01QYXJzZXIiLCJwYXJzZUZyb21TdHJpbmciLCJkZXRhaWxzIiwiZCIsImlzc3VlIiwiZGVzY3JpcHRpb24iLCJqb2luIiwiaW5wdXQiLCJjdXN0b21faWQiLCJhcHBlbmQiLCJvbkNhbmNlbCIsImdldEVsZW1lbnQiLCJzZWxlY3Rvck9yRWxlbWVudCIsImlzVmlzaWJsZSIsIm9mZnNldFdpZHRoIiwib2Zmc2V0SGVpZ2h0IiwiZ2V0Q2xpZW50UmVjdHMiLCJzZXRWaXNpYmxlIiwic2hvdyIsImltcG9ydGFudCIsImN1cnJlbnRWYWx1ZSIsInN0eWxlIiwiZ2V0UHJvcGVydHlWYWx1ZSIsInNldFByb3BlcnR5IiwicmVtb3ZlUHJvcGVydHkiLCJoaWRlIiwiQ2hlY2tvdXRCb290c3RhcCIsInN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciIsImJ1dHRvbkNoYW5nZU9ic2VydmVyIiwidXBkYXRlVWkiLCJ2YWwiLCJjYW5jZWxfd3JhcHBlciIsImN1cnJlbnRQYXltZW50TWV0aG9kIiwiaXNQYXlwYWwiLCJpc0NhcmQiLCJpc1NhdmVkQ2FyZCIsImlzTm90T3VyR2F0ZXdheSIsImlzRnJlZVRyaWFsIiwiaXNfZnJlZV90cmlhbF9jYXJ0IiwiaGFzVmF1bHRlZFBheXBhbCIsInZhdWx0ZWRfcGF5cGFsX2VtYWlsIiwiZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMiLCJlbmFibGVDcmVkaXRDYXJkRmllbGRzIiwiYWRkQ2xhc3MiLCJhdHRyIiwicmVtb3ZlQ2xhc3MiLCJpc0NoYW5nZVBheW1lbnRQYWdlIiwidXJsUGFyYW1zIiwiVVJMU2VhcmNoUGFyYW1zIiwic2VhcmNoIiwiaGFzIiwiUGF5Tm93Qm9vdHN0cmFwIiwiUmVuZGVyZXIiLCJjcmVkaXRDYXJkUmVuZGVyZXIiLCJkZWZhdWx0Q29uZmlnIiwib25TbWFydEJ1dHRvbkNsaWNrIiwib25TbWFydEJ1dHRvbnNJbml0IiwiaG9zdGVkRmllbGRzV3JhcHBlciIsImNvbnRleHRDb25maWciLCJyZW5kZXJCdXR0b25zIiwiaXNBbHJlYWR5UmVuZGVyZWQiLCJwYXlwYWwiLCJCdXR0b25zIiwibWluaV9jYXJ0X3N0eWxlIiwib25DbGljayIsIm9uSW5pdCIsImhhc0NoaWxkTm9kZXMiLCJkb21FbGVtZW50IiwiZGlzcGxheSIsImRpc2FibGVGaWVsZHMiLCJlbmFibGVGaWVsZHMiLCJkY2NJbnB1dEZhY3RvcnkiLCJvcmlnaW5hbCIsInN0eWxlcyIsImdldENvbXB1dGVkU3R5bGUiLCJuZXdFbGVtZW50IiwiT2JqZWN0IiwidmFsdWVzIiwicHJvcCIsImlzTmFOIiwiQ3JlZGl0Q2FyZFJlbmRlcmVyIiwiY2FyZFZhbGlkIiwiZm9ybVZhbGlkIiwiY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlIiwiSG9zdGVkRmllbGRzIiwiaXNFbGlnaWJsZSIsIndyYXBwZXJFbGVtZW50IiwicGFyZW50Tm9kZSIsInJlbW92ZUNoaWxkIiwiYnV0dG9uU2VsZWN0b3IiLCJ0ZWFyZG93biIsImdhdGVXYXlCb3giLCJvbGREaXNwbGF5U3R5bGUiLCJoaWRlRGNjR2F0ZXdheSIsImNhcmROdW1iZXJGaWVsZCIsInN0eWxlc1JhdyIsImNhcmROdW1iZXIiLCJyZXBsYWNlQ2hpbGQiLCJjYXJkRXhwaXJ5RmllbGQiLCJjYXJkRXhwaXJ5IiwiY2FyZENvZGVGaWVsZCIsImNhcmRDb2RlIiwiZm9ybVdyYXBwZXIiLCJlbmZvcmNlX3ZhdWx0IiwiY2hlY2tlZCIsImZpZWxkcyIsIm51bWJlciIsInNlbGVjdG9yIiwicGxhY2Vob2xkZXIiLCJjcmVkaXRfY2FyZF9udW1iZXIiLCJjdnYiLCJleHBpcmF0aW9uRGF0ZSIsIm1tX3l5IiwiaG9zdGVkRmllbGRzIiwiZGlzcGF0Y2hFdmVudCIsIkN1c3RvbUV2ZW50IiwiX3N1Ym1pdCIsImV2ZW50IiwiY2FyZHMiLCJ2YWxpZENhcmRzIiwidmFsaWRfY2FyZHMiLCJpbmRleE9mIiwidHlwZSIsImtleXMiLCJldmVyeSIsImtleSIsImlzVmFsaWQiLCJwcmV2ZW50RGVmYXVsdCIsImZpZWxkIiwiYXR0cmlidXRlIiwicmVtb3ZlQXR0cmlidXRlIiwic2F2ZV9jYXJkIiwiY2FuX3NhdmVfdmF1bHRfdG9rZW4iLCJ2YXVsdCIsImdldEVsZW1lbnRCeUlkIiwiY29udGluZ2VuY3kiLCJob3N0ZWRGaWVsZHNEYXRhIiwiY29udGluZ2VuY2llcyIsImNhcmRob2xkZXJOYW1lIiwiZmlyc3ROYW1lIiwibGFzdE5hbWUiLCJzdWJtaXQiLCJwYXlsb2FkIiwib3JkZXJJZCIsImNhcmRfbm90X3N1cHBvcnRlZCIsImZpZWxkc19ub3RfdmFsaWQiLCJzdG9yYWdlS2V5IiwidmFsaWRhdGVUb2tlbiIsInRva2VuIiwidXNlciIsImN1cnJlbnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJpc0V4cGlyZWQiLCJleHBpcmF0aW9uIiwic3RvcmVkVG9rZW5Gb3JVc2VyIiwicGFyc2UiLCJzZXNzaW9uU3RvcmFnZSIsImdldEl0ZW0iLCJzdG9yZVRva2VuIiwic2V0SXRlbSIsImRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIiLCJzY3JpcHQiLCJNZXNzYWdlUmVuZGVyZXIiLCJNZXNzYWdlcyIsInBsYWNlbWVudCIsIm5ld1dyYXBwZXIiLCJzaWJsaW5nIiwibmV4dFNpYmxpbmciLCJwYXJlbnRFbGVtZW50IiwiaW5zZXJ0QmVmb3JlIiwiU3Bpbm5lciIsInRhcmdldCIsInNldFRhcmdldCIsIm92ZXJsYXlDU1MiLCJiYWNrZ3JvdW5kIiwib3BhY2l0eSIsIkZyZWVUcmlhbEhhbmRsZXIiLCJoYW5kbGUiLCJ2YXVsdF9wYXlwYWwiLCJyZXR1cm5fdXJsIiwiYXBwcm92ZV9saW5rIiwiYnV0dG9uc1NwaW5uZXIiLCJjYXJkc1NwaW5uZXIiLCJib290c3RyYXAiLCJmcmVlVHJpYWxIYW5kbGVyIiwiZnVuZGluZ1NvdXJjZSIsImluc2VydEFkamFjZW50SFRNTCIsIm1lc3NhZ2VSZW5kZXJlciIsIm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQiLCJtaW5pQ2FydEJvb3RzdHJhcCIsInNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCIsInNpbmdsZVByb2R1Y3RCb290c3RyYXAiLCJjYXJ0Qm9vdHN0cmFwIiwiY2hlY2tvdXRCb290c3RhcCIsInBheU5vd0Jvb3RzdHJhcCIsImRhdGFfY2xpZW50X2lkIiwiaGFzX3N1YnNjcmlwdGlvbnMiLCJoaWRlT3JkZXJCdXR0b25JZlBwY3BHYXRld2F5IiwiaW5jbHVkZXMiLCJpc0NhcmRzIiwiYm9vdHN0cmFwcGVkIiwidXJsIiwiZW50cmllcyIsInNjcmlwdF9hdHRyaWJ1dGVzIiwia2V5VmFsdWUiLCJzZXRfYXR0cmlidXRlIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///536\n")}},__webpack_exports__={};__webpack_modules__[536]()})();
|
modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js
CHANGED
@@ -13,7 +13,6 @@ class CreditCardRenderer {
|
|
13 |
}
|
14 |
|
15 |
render(wrapper, contextConfig) {
|
16 |
-
|
17 |
if (
|
18 |
(
|
19 |
this.defaultConfig.context !== 'checkout'
|
@@ -42,6 +41,9 @@ class CreditCardRenderer {
|
|
42 |
}
|
43 |
|
44 |
const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');
|
|
|
|
|
|
|
45 |
const oldDisplayStyle = gateWayBox.style.display;
|
46 |
gateWayBox.style.display = 'block';
|
47 |
|
@@ -207,12 +209,6 @@ class CreditCardRenderer {
|
|
207 |
const firstName = document.getElementById('billing_first_name') ? document.getElementById('billing_first_name').value : '';
|
208 |
const lastName = document.getElementById('billing_last_name') ? document.getElementById('billing_last_name').value : '';
|
209 |
|
210 |
-
if (!firstName || !lastName) {
|
211 |
-
this.spinner.unblock();
|
212 |
-
this.errorHandler.message(this.defaultConfig.hosted_fields.labels.cardholder_name_required);
|
213 |
-
return;
|
214 |
-
}
|
215 |
-
|
216 |
hostedFieldsData.cardholderName = firstName + ' ' + lastName;
|
217 |
}
|
218 |
|
13 |
}
|
14 |
|
15 |
render(wrapper, contextConfig) {
|
|
|
16 |
if (
|
17 |
(
|
18 |
this.defaultConfig.context !== 'checkout'
|
41 |
}
|
42 |
|
43 |
const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');
|
44 |
+
if(! gateWayBox) {
|
45 |
+
return
|
46 |
+
}
|
47 |
const oldDisplayStyle = gateWayBox.style.display;
|
48 |
gateWayBox.style.display = 'block';
|
49 |
|
209 |
const firstName = document.getElementById('billing_first_name') ? document.getElementById('billing_first_name').value : '';
|
210 |
const lastName = document.getElementById('billing_last_name') ? document.getElementById('billing_last_name').value : '';
|
211 |
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
hostedFieldsData.cardholderName = firstName + ' ' + lastName;
|
213 |
}
|
214 |
|
modules/ppcp-button/resources/js/modules/Renderer/MessageRenderer.js
CHANGED
@@ -14,6 +14,14 @@ class MessageRenderer {
|
|
14 |
placement: this.config.placement,
|
15 |
style: this.config.style
|
16 |
}).render(this.config.wrapper);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
}
|
18 |
|
19 |
renderWithAmount(amount) {
|
@@ -46,4 +54,4 @@ class MessageRenderer {
|
|
46 |
return true;
|
47 |
}
|
48 |
}
|
49 |
-
export default MessageRenderer;
|
14 |
placement: this.config.placement,
|
15 |
style: this.config.style
|
16 |
}).render(this.config.wrapper);
|
17 |
+
|
18 |
+
jQuery(document.body).on('updated_cart_totals', () => {
|
19 |
+
paypal.Messages({
|
20 |
+
amount: this.config.amount,
|
21 |
+
placement: this.config.placement,
|
22 |
+
style: this.config.style
|
23 |
+
}).render(this.config.wrapper);
|
24 |
+
});
|
25 |
}
|
26 |
|
27 |
renderWithAmount(amount) {
|
54 |
return true;
|
55 |
}
|
56 |
}
|
57 |
+
export default MessageRenderer;
|
modules/ppcp-button/src/Assets/SmartButton.php
CHANGED
@@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Button\Assets;
|
|
11 |
|
12 |
use Exception;
|
13 |
use Psr\Log\LoggerInterface;
|
|
|
14 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
@@ -220,16 +221,15 @@ class SmartButton implements SmartButtonInterface {
|
|
220 |
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
|
221 |
*/
|
222 |
public function render_wrapper(): bool {
|
223 |
-
|
224 |
-
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
|
225 |
-
return false;
|
226 |
-
}
|
227 |
-
|
228 |
if ( $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' ) ) {
|
229 |
$this->render_button_wrapper_registrar();
|
230 |
$this->render_message_wrapper_registrar();
|
231 |
}
|
232 |
|
|
|
|
|
|
|
|
|
233 |
if (
|
234 |
$this->settings->has( 'dcc_enabled' )
|
235 |
&& $this->settings->get( 'dcc_enabled' )
|
@@ -341,19 +341,17 @@ class SmartButton implements SmartButtonInterface {
|
|
341 |
|
342 |
$not_enabled_on_cart = $this->settings->has( 'message_cart_enabled' ) &&
|
343 |
! $this->settings->get( 'message_cart_enabled' );
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
);
|
356 |
-
}
|
357 |
|
358 |
$not_enabled_on_product_page = $this->settings->has( 'message_product_enabled' ) &&
|
359 |
! $this->settings->get( 'message_product_enabled' );
|
@@ -432,6 +430,10 @@ class SmartButton implements SmartButtonInterface {
|
|
432 |
add_action(
|
433 |
$this->mini_cart_button_renderer_hook(),
|
434 |
function () {
|
|
|
|
|
|
|
|
|
435 |
if ( $this->is_cart_price_total_zero() || $this->is_free_trial_cart() ) {
|
436 |
return;
|
437 |
}
|
@@ -445,28 +447,21 @@ class SmartButton implements SmartButtonInterface {
|
|
445 |
);
|
446 |
}
|
447 |
|
448 |
-
|
449 |
-
return false;
|
450 |
-
}
|
451 |
|
452 |
$not_enabled_on_cart = $this->settings->has( 'button_cart_enabled' ) &&
|
453 |
! $this->settings->get( 'button_cart_enabled' );
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
$this->proceed_to_checkout_button_renderer_hook(),
|
461 |
-
array(
|
462 |
-
$this,
|
463 |
-
'button_renderer',
|
464 |
-
),
|
465 |
-
20
|
466 |
-
);
|
467 |
-
}
|
468 |
|
469 |
-
|
|
|
|
|
|
|
470 |
|
471 |
return true;
|
472 |
}
|
@@ -521,13 +516,16 @@ class SmartButton implements SmartButtonInterface {
|
|
521 |
* Renders the HTML for the buttons.
|
522 |
*/
|
523 |
public function button_renderer() {
|
|
|
|
|
|
|
|
|
|
|
524 |
$product = wc_get_product();
|
|
|
525 |
if (
|
526 |
-
! is_checkout() && is_a( $product,
|
527 |
-
&& (
|
528 |
-
$product->is_type( array( 'external', 'grouped' ) )
|
529 |
-
|| ! $product->is_in_stock()
|
530 |
-
)
|
531 |
) {
|
532 |
|
533 |
return;
|
@@ -548,6 +546,21 @@ class SmartButton implements SmartButtonInterface {
|
|
548 |
* Renders the HTML for the credit messaging.
|
549 |
*/
|
550 |
public function message_renderer() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
551 |
|
552 |
echo '<div id="ppcp-messages" data-partner-attribution-id="Woo_PPCP"></div>';
|
553 |
}
|
@@ -568,7 +581,7 @@ class SmartButton implements SmartButtonInterface {
|
|
568 |
}
|
569 |
$placement = 'product';
|
570 |
$product = wc_get_product();
|
571 |
-
$amount = ( is_a( $product,
|
572 |
$layout = $this->settings->has( 'message_product_layout' ) ?
|
573 |
$this->settings->get( 'message_product_layout' ) : 'text';
|
574 |
$logo_type = $this->settings->has( 'message_product_logo' ) ?
|
@@ -1221,10 +1234,29 @@ class SmartButton implements SmartButtonInterface {
|
|
1221 |
* Check if cart product price total is 0.
|
1222 |
*
|
1223 |
* @return bool true if is 0, otherwise false.
|
|
|
1224 |
*/
|
1225 |
protected function is_cart_price_total_zero(): bool {
|
1226 |
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
1227 |
-
return WC()->cart->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1228 |
}
|
1229 |
|
1230 |
/**
|
11 |
|
12 |
use Exception;
|
13 |
use Psr\Log\LoggerInterface;
|
14 |
+
use WC_Product;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
|
17 |
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
221 |
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
|
222 |
*/
|
223 |
public function render_wrapper(): bool {
|
|
|
|
|
|
|
|
|
|
|
224 |
if ( $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' ) ) {
|
225 |
$this->render_button_wrapper_registrar();
|
226 |
$this->render_message_wrapper_registrar();
|
227 |
}
|
228 |
|
229 |
+
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
|
230 |
+
return false;
|
231 |
+
}
|
232 |
+
|
233 |
if (
|
234 |
$this->settings->has( 'dcc_enabled' )
|
235 |
&& $this->settings->get( 'dcc_enabled' )
|
341 |
|
342 |
$not_enabled_on_cart = $this->settings->has( 'message_cart_enabled' ) &&
|
343 |
! $this->settings->get( 'message_cart_enabled' );
|
344 |
+
|
345 |
+
add_action(
|
346 |
+
$this->proceed_to_checkout_button_renderer_hook(),
|
347 |
+
function() use ( $not_enabled_on_cart ) {
|
348 |
+
if ( ! is_cart() || $not_enabled_on_cart ) {
|
349 |
+
return;
|
350 |
+
}
|
351 |
+
$this->message_renderer();
|
352 |
+
},
|
353 |
+
19
|
354 |
+
);
|
|
|
|
|
355 |
|
356 |
$not_enabled_on_product_page = $this->settings->has( 'message_product_enabled' ) &&
|
357 |
! $this->settings->get( 'message_product_enabled' );
|
430 |
add_action(
|
431 |
$this->mini_cart_button_renderer_hook(),
|
432 |
function () {
|
433 |
+
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
|
434 |
+
return;
|
435 |
+
}
|
436 |
+
|
437 |
if ( $this->is_cart_price_total_zero() || $this->is_free_trial_cart() ) {
|
438 |
return;
|
439 |
}
|
447 |
);
|
448 |
}
|
449 |
|
450 |
+
add_action( $this->checkout_button_renderer_hook(), array( $this, 'button_renderer' ), 10 );
|
|
|
|
|
451 |
|
452 |
$not_enabled_on_cart = $this->settings->has( 'button_cart_enabled' ) &&
|
453 |
! $this->settings->get( 'button_cart_enabled' );
|
454 |
+
add_action(
|
455 |
+
$this->proceed_to_checkout_button_renderer_hook(),
|
456 |
+
function() use ( $not_enabled_on_cart ) {
|
457 |
+
if ( ! is_cart() || $not_enabled_on_cart || $this->is_free_trial_cart() || $this->is_cart_price_total_zero() ) {
|
458 |
+
return;
|
459 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
|
461 |
+
$this->button_renderer();
|
462 |
+
},
|
463 |
+
20
|
464 |
+
);
|
465 |
|
466 |
return true;
|
467 |
}
|
516 |
* Renders the HTML for the buttons.
|
517 |
*/
|
518 |
public function button_renderer() {
|
519 |
+
|
520 |
+
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
|
521 |
+
return;
|
522 |
+
}
|
523 |
+
|
524 |
$product = wc_get_product();
|
525 |
+
|
526 |
if (
|
527 |
+
! is_checkout() && is_a( $product, WC_Product::class )
|
528 |
+
&& ! $this->product_supports_payment( $product )
|
|
|
|
|
|
|
529 |
) {
|
530 |
|
531 |
return;
|
546 |
* Renders the HTML for the credit messaging.
|
547 |
*/
|
548 |
public function message_renderer() {
|
549 |
+
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
|
550 |
+
return false;
|
551 |
+
}
|
552 |
+
|
553 |
+
$product = wc_get_product();
|
554 |
+
|
555 |
+
if (
|
556 |
+
! is_checkout() && is_a( $product, WC_Product::class )
|
557 |
+
/**
|
558 |
+
* The filter returning true if PayPal buttons can be rendered, or false otherwise.
|
559 |
+
*/
|
560 |
+
&& ! $this->product_supports_payment( $product )
|
561 |
+
) {
|
562 |
+
return;
|
563 |
+
}
|
564 |
|
565 |
echo '<div id="ppcp-messages" data-partner-attribution-id="Woo_PPCP"></div>';
|
566 |
}
|
581 |
}
|
582 |
$placement = 'product';
|
583 |
$product = wc_get_product();
|
584 |
+
$amount = ( is_a( $product, WC_Product::class ) ) ? wc_get_price_including_tax( $product ) : 0;
|
585 |
$layout = $this->settings->has( 'message_product_layout' ) ?
|
586 |
$this->settings->get( 'message_product_layout' ) : 'text';
|
587 |
$logo_type = $this->settings->has( 'message_product_logo' ) ?
|
1234 |
* Check if cart product price total is 0.
|
1235 |
*
|
1236 |
* @return bool true if is 0, otherwise false.
|
1237 |
+
* @psalm-suppress RedundantConditionGivenDocblockType
|
1238 |
*/
|
1239 |
protected function is_cart_price_total_zero(): bool {
|
1240 |
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
1241 |
+
return WC()->cart && WC()->cart->get_total( 'numeric' ) == 0;
|
1242 |
+
}
|
1243 |
+
|
1244 |
+
/**
|
1245 |
+
* Checks if PayPal buttons/messages can be rendered for the given product.
|
1246 |
+
*
|
1247 |
+
* @param WC_Product $product The product.
|
1248 |
+
*
|
1249 |
+
* @return bool
|
1250 |
+
*/
|
1251 |
+
protected function product_supports_payment( WC_Product $product ): bool {
|
1252 |
+
/**
|
1253 |
+
* The filter returning true if PayPal buttons/messages can be rendered for this product, or false otherwise.
|
1254 |
+
*/
|
1255 |
+
return apply_filters(
|
1256 |
+
'woocommerce_paypal_payments_product_supports_payment_request_button',
|
1257 |
+
! $product->is_type( array( 'external', 'grouped' ) ) && $product->is_in_stock(),
|
1258 |
+
$product
|
1259 |
+
);
|
1260 |
}
|
1261 |
|
1262 |
/**
|
modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php
CHANGED
@@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
|
|
11 |
|
12 |
use Exception;
|
13 |
use Psr\Log\LoggerInterface;
|
|
|
14 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Amount;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
@@ -242,6 +243,13 @@ class CreateOrderEndpoint implements EndpointInterface {
|
|
242 |
}
|
243 |
|
244 |
$order = $this->create_paypal_order( $wc_order );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
wp_send_json_success( $order->to_array() );
|
246 |
return true;
|
247 |
|
@@ -317,19 +325,51 @@ class CreateOrderEndpoint implements EndpointInterface {
|
|
317 |
* @return Order Created PayPal order.
|
318 |
*
|
319 |
* @throws RuntimeException If create order request fails.
|
|
|
|
|
320 |
*/
|
321 |
private function create_paypal_order( \WC_Order $wc_order = null ): Order {
|
322 |
$needs_shipping = WC()->cart instanceof \WC_Cart && WC()->cart->needs_shipping();
|
323 |
$shipping_address_is_fix = $needs_shipping && 'checkout' === $this->parsed_request_data['context'];
|
324 |
|
325 |
-
|
326 |
-
$this->
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
}
|
334 |
|
335 |
/**
|
11 |
|
12 |
use Exception;
|
13 |
use Psr\Log\LoggerInterface;
|
14 |
+
use stdClass;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Amount;
|
17 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
243 |
}
|
244 |
|
245 |
$order = $this->create_paypal_order( $wc_order );
|
246 |
+
|
247 |
+
if ( 'pay-now' === $data['context'] && is_a( $wc_order, \WC_Order::class ) ) {
|
248 |
+
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
249 |
+
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
250 |
+
$wc_order->save_meta_data();
|
251 |
+
}
|
252 |
+
|
253 |
wp_send_json_success( $order->to_array() );
|
254 |
return true;
|
255 |
|
325 |
* @return Order Created PayPal order.
|
326 |
*
|
327 |
* @throws RuntimeException If create order request fails.
|
328 |
+
* @throws PayPalApiException If create order request fails.
|
329 |
+
* phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
330 |
*/
|
331 |
private function create_paypal_order( \WC_Order $wc_order = null ): Order {
|
332 |
$needs_shipping = WC()->cart instanceof \WC_Cart && WC()->cart->needs_shipping();
|
333 |
$shipping_address_is_fix = $needs_shipping && 'checkout' === $this->parsed_request_data['context'];
|
334 |
|
335 |
+
try {
|
336 |
+
return $this->api_endpoint->create(
|
337 |
+
$this->purchase_units,
|
338 |
+
$this->payer( $this->parsed_request_data, $wc_order ),
|
339 |
+
null,
|
340 |
+
$this->payment_method(),
|
341 |
+
'',
|
342 |
+
$shipping_address_is_fix
|
343 |
+
);
|
344 |
+
} catch ( PayPalApiException $exception ) {
|
345 |
+
// Looks like currently there is no proper way to validate the shipping address for PayPal,
|
346 |
+
// so we cannot make some invalid addresses null in PurchaseUnitFactory,
|
347 |
+
// which causes failure e.g. for guests using the button on products pages when the country does not have postal codes.
|
348 |
+
if ( 422 === $exception->status_code()
|
349 |
+
&& array_filter(
|
350 |
+
$exception->details(),
|
351 |
+
function ( stdClass $detail ): bool {
|
352 |
+
return isset( $detail->field ) && str_contains( (string) $detail->field, 'shipping/address' );
|
353 |
+
}
|
354 |
+
) ) {
|
355 |
+
$this->logger->info( 'Invalid shipping address for order creation, retrying without it.' );
|
356 |
+
|
357 |
+
foreach ( $this->purchase_units as $purchase_unit ) {
|
358 |
+
$purchase_unit->set_shipping( null );
|
359 |
+
}
|
360 |
+
|
361 |
+
return $this->api_endpoint->create(
|
362 |
+
$this->purchase_units,
|
363 |
+
$this->payer( $this->parsed_request_data, $wc_order ),
|
364 |
+
null,
|
365 |
+
$this->payment_method(),
|
366 |
+
'',
|
367 |
+
$shipping_address_is_fix
|
368 |
+
);
|
369 |
+
}
|
370 |
+
|
371 |
+
throw $exception;
|
372 |
+
}
|
373 |
}
|
374 |
|
375 |
/**
|
modules/ppcp-vaulting/src/CustomerApprovalListener.php
CHANGED
@@ -58,7 +58,8 @@ class CustomerApprovalListener {
|
|
58 |
return;
|
59 |
}
|
60 |
|
61 |
-
|
|
|
62 |
|
63 |
$query = wp_parse_url( $url, PHP_URL_QUERY );
|
64 |
if ( $query && str_contains( $query, 'ppcp_vault=cancel' ) ) {
|
58 |
return;
|
59 |
}
|
60 |
|
61 |
+
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
62 |
+
$url = (string) filter_var( $_SERVER['REQUEST_URI'] ?? '', FILTER_SANITIZE_URL );
|
63 |
|
64 |
$query = wp_parse_url( $url, PHP_URL_QUERY );
|
65 |
if ( $query && str_contains( $query, 'ppcp_vault=cancel' ) ) {
|
modules/ppcp-vaulting/src/PaymentTokenChecker.php
CHANGED
@@ -119,7 +119,7 @@ class PaymentTokenChecker {
|
|
119 |
try {
|
120 |
if ( $this->is_free_trial_order( $wc_order ) ) {
|
121 |
if ( CreditCardGateway::ID === $wc_order->get_payment_method()
|
122 |
-
|| ( PayPalGateway::ID === $wc_order->get_payment_method() && 'card' === $wc_order->get_meta( PayPalGateway::
|
123 |
) {
|
124 |
$order = $this->order_repository->for_wc_order( $wc_order );
|
125 |
$this->authorized_payments_processor->void_authorizations( $order );
|
119 |
try {
|
120 |
if ( $this->is_free_trial_order( $wc_order ) ) {
|
121 |
if ( CreditCardGateway::ID === $wc_order->get_payment_method()
|
122 |
+
|| ( PayPalGateway::ID === $wc_order->get_payment_method() && 'card' === $wc_order->get_meta( PayPalGateway::ORDER_PAYMENT_SOURCE_META_KEY ) )
|
123 |
) {
|
124 |
$order = $this->order_repository->for_wc_order( $wc_order );
|
125 |
$this->authorized_payments_processor->void_authorizations( $order );
|
modules/ppcp-wc-gateway/assets/js/gateway-settings.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
(()=>{var __webpack_modules__={795:()=>{eval(";\ndocument.addEventListener('DOMContentLoaded', () => {\n const payLaterMessagingCheckboxes = document.querySelectorAll(\"#ppcp-message_enabled, #ppcp-message_cart_enabled, #ppcp-message_product_enabled\");\n const vaultingCheckboxes = document.querySelectorAll(\"#ppcp-vault_enabled\");\n\n function atLeastOneChecked(checkboxesNodeList) {\n return Array.prototype.slice.call(checkboxesNodeList).filter(node => !node.disabled && node.checked).length > 0;\n }\n\n function disableAll(nodeList) {\n nodeList.forEach(node => node.setAttribute('disabled', 'true'));\n }\n\n function enableAll(nodeList) {\n nodeList.forEach(node => node.removeAttribute('disabled'));\n }\n\n function
|
1 |
+
(()=>{var __webpack_modules__={795:()=>{eval(";\ndocument.addEventListener('DOMContentLoaded', () => {\n const payLaterMessagingCheckboxes = document.querySelectorAll(\"#ppcp-message_enabled, #ppcp-message_cart_enabled, #ppcp-message_product_enabled\");\n const vaultingCheckboxes = document.querySelectorAll(\"#ppcp-vault_enabled\");\n const payLaterEnabledLabels = document.querySelectorAll(\".ppcp-pay-later-enabled-label\");\n const payLaterDisabledLabels = document.querySelectorAll(\".ppcp-pay-later-disabled-label\");\n const disabledCheckboxes = document.querySelectorAll('.ppcp-disabled-checkbox');\n\n function atLeastOneChecked(checkboxesNodeList) {\n return Array.prototype.slice.call(checkboxesNodeList).filter(node => !node.disabled && node.checked).length > 0;\n }\n\n function disableAll(nodeList) {\n nodeList.forEach(node => node.setAttribute('disabled', 'true'));\n }\n\n function enableAll(nodeList) {\n nodeList.forEach(node => node.removeAttribute('disabled'));\n }\n\n function hideAll(nodeList) {\n nodeList.forEach(node => node.style.display = 'none');\n }\n\n function displayAll(nodeList) {\n nodeList.forEach(node => node.style.display = '');\n }\n\n function uncheckAll(nodeList) {\n nodeList.forEach(node => {\n node.checked = false;\n node.dispatchEvent(new Event('change'));\n });\n }\n\n function disablePayLater() {\n uncheckAll(payLaterMessagingCheckboxes);\n disableAll(payLaterMessagingCheckboxes);\n hideAll(payLaterEnabledLabels);\n displayAll(payLaterDisabledLabels);\n }\n\n function enablePayLater() {\n enableAll(payLaterMessagingCheckboxes);\n displayAll(payLaterEnabledLabels);\n hideAll(payLaterDisabledLabels);\n }\n\n function togglePayLater() {\n atLeastOneChecked(vaultingCheckboxes) ? disablePayLater() : enablePayLater();\n }\n\n disableAll(disabledCheckboxes);\n togglePayLater();\n vaultingCheckboxes.forEach(node => node.addEventListener('change', togglePayLater));\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGNwLXdjLWdhdGV3YXkvLi9yZXNvdXJjZXMvanMvZ2F0ZXdheS1zZXR0aW5ncy5qcz8xODEzIl0sIm5hbWVzIjpbImRvY3VtZW50IiwiYWRkRXZlbnRMaXN0ZW5lciIsInBheUxhdGVyTWVzc2FnaW5nQ2hlY2tib3hlcyIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJ2YXVsdGluZ0NoZWNrYm94ZXMiLCJwYXlMYXRlckVuYWJsZWRMYWJlbHMiLCJwYXlMYXRlckRpc2FibGVkTGFiZWxzIiwiZGlzYWJsZWRDaGVja2JveGVzIiwiYXRMZWFzdE9uZUNoZWNrZWQiLCJjaGVja2JveGVzTm9kZUxpc3QiLCJBcnJheSIsInByb3RvdHlwZSIsInNsaWNlIiwiY2FsbCIsImZpbHRlciIsIm5vZGUiLCJkaXNhYmxlZCIsImNoZWNrZWQiLCJsZW5ndGgiLCJkaXNhYmxlQWxsIiwibm9kZUxpc3QiLCJmb3JFYWNoIiwic2V0QXR0cmlidXRlIiwiZW5hYmxlQWxsIiwicmVtb3ZlQXR0cmlidXRlIiwiaGlkZUFsbCIsInN0eWxlIiwiZGlzcGxheSIsImRpc3BsYXlBbGwiLCJ1bmNoZWNrQWxsIiwiZGlzcGF0Y2hFdmVudCIsIkV2ZW50IiwiZGlzYWJsZVBheUxhdGVyIiwiZW5hYmxlUGF5TGF0ZXIiLCJ0b2dnbGVQYXlMYXRlciJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQ0EsUUFBUSxDQUFDQyxnQkFBVCxDQUNHLGtCQURILEVBRUcsTUFBTTtBQUNGLFFBQU1DLDJCQUEyQixHQUFHRixRQUFRLENBQUNHLGdCQUFULENBQ2hDLGtGQURnQyxDQUFwQztBQUlBLFFBQU1DLGtCQUFrQixHQUFHSixRQUFRLENBQUNHLGdCQUFULENBQ3ZCLHFCQUR1QixDQUEzQjtBQUlBLFFBQU1FLHFCQUFxQixHQUFHTCxRQUFRLENBQUNHLGdCQUFULENBQzFCLCtCQUQwQixDQUE5QjtBQUlBLFFBQU1HLHNCQUFzQixHQUFHTixRQUFRLENBQUNHLGdCQUFULENBQzNCLGdDQUQyQixDQUEvQjtBQUlBLFFBQU1JLGtCQUFrQixHQUFHUCxRQUFRLENBQUNHLGdCQUFULENBQ3ZCLHlCQUR1QixDQUEzQjs7QUFJQSxXQUFTSyxpQkFBVCxDQUEyQkMsa0JBQTNCLEVBQStDO0FBQzNDLFdBQU9DLEtBQUssQ0FBQ0MsU0FBTixDQUFnQkMsS0FBaEIsQ0FBc0JDLElBQXRCLENBQTJCSixrQkFBM0IsRUFBK0NLLE1BQS9DLENBQXNEQyxJQUFJLElBQUksQ0FBQ0EsSUFBSSxDQUFDQyxRQUFOLElBQWtCRCxJQUFJLENBQUNFLE9BQXJGLEVBQThGQyxNQUE5RixHQUF1RyxDQUE5RztBQUNIOztBQUVELFdBQVNDLFVBQVQsQ0FBb0JDLFFBQXBCLEVBQTZCO0FBQ3pCQSxJQUFBQSxRQUFRLENBQUNDLE9BQVQsQ0FBaUJOLElBQUksSUFBSUEsSUFBSSxDQUFDTyxZQUFMLENBQWtCLFVBQWxCLEVBQThCLE1BQTlCLENBQXpCO0FBQ0g7O0FBRUQsV0FBU0MsU0FBVCxDQUFtQkgsUUFBbkIsRUFBNEI7QUFDeEJBLElBQUFBLFFBQVEsQ0FBQ0MsT0FBVCxDQUFpQk4sSUFBSSxJQUFJQSxJQUFJLENBQUNTLGVBQUwsQ0FBcUIsVUFBckIsQ0FBekI7QUFDSDs7QUFFRCxXQUFTQyxPQUFULENBQWlCTCxRQUFqQixFQUEyQjtBQUN2QkEsSUFBQUEsUUFBUSxDQUFDQyxPQUFULENBQWlCTixJQUFJLElBQUlBLElBQUksQ0FBQ1csS0FBTCxDQUFXQyxPQUFYLEdBQXFCLE1BQTlDO0FBQ0g7O0FBRUQsV0FBU0MsVUFBVCxDQUFvQlIsUUFBcEIsRUFBOEI7QUFDMUJBLElBQUFBLFFBQVEsQ0FBQ0MsT0FBVCxDQUFpQk4sSUFBSSxJQUFJQSxJQUFJLENBQUNXLEtBQUwsQ0FBV0MsT0FBWCxHQUFxQixFQUE5QztBQUNIOztBQUVELFdBQVNFLFVBQVQsQ0FBb0JULFFBQXBCLEVBQTZCO0FBQ3pCQSxJQUFBQSxRQUFRLENBQUNDLE9BQVQsQ0FBaUJOLElBQUksSUFBSTtBQUNyQkEsTUFBQUEsSUFBSSxDQUFDRSxPQUFMLEdBQWUsS0FBZjtBQUNBRixNQUFBQSxJQUFJLENBQUNlLGFBQUwsQ0FBbUIsSUFBSUMsS0FBSixDQUFVLFFBQVYsQ0FBbkI7QUFDSCxLQUhEO0FBSUg7O0FBRUQsV0FBU0MsZUFBVCxHQUEyQjtBQUN2QkgsSUFBQUEsVUFBVSxDQUFDM0IsMkJBQUQsQ0FBVjtBQUNBaUIsSUFBQUEsVUFBVSxDQUFDakIsMkJBQUQsQ0FBVjtBQUNBdUIsSUFBQUEsT0FBTyxDQUFDcEIscUJBQUQsQ0FBUDtBQUNBdUIsSUFBQUEsVUFBVSxDQUFDdEIsc0JBQUQsQ0FBVjtBQUNIOztBQUVELFdBQVMyQixjQUFULEdBQTBCO0FBQ3RCVixJQUFBQSxTQUFTLENBQUNyQiwyQkFBRCxDQUFUO0FBQ0EwQixJQUFBQSxVQUFVLENBQUN2QixxQkFBRCxDQUFWO0FBQ0FvQixJQUFBQSxPQUFPLENBQUNuQixzQkFBRCxDQUFQO0FBQ0g7O0FBRUQsV0FBUzRCLGNBQVQsR0FBMEI7QUFDdEIxQixJQUFBQSxpQkFBaUIsQ0FBQ0osa0JBQUQsQ0FBakIsR0FBd0M0QixlQUFlLEVBQXZELEdBQTREQyxjQUFjLEVBQTFFO0FBQ0g7O0FBRURkLEVBQUFBLFVBQVUsQ0FBRVosa0JBQUYsQ0FBVjtBQUNBMkIsRUFBQUEsY0FBYztBQUVkOUIsRUFBQUEsa0JBQWtCLENBQUNpQixPQUFuQixDQUEyQk4sSUFBSSxJQUFJQSxJQUFJLENBQUNkLGdCQUFMLENBQXNCLFFBQXRCLEVBQWdDaUMsY0FBaEMsQ0FBbkM7QUFDSCxDQXZFSiIsInNvdXJjZXNDb250ZW50IjpbIjtkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICdET01Db250ZW50TG9hZGVkJyxcbiAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBheUxhdGVyTWVzc2FnaW5nQ2hlY2tib3hlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgICAgICBcIiNwcGNwLW1lc3NhZ2VfZW5hYmxlZCwgI3BwY3AtbWVzc2FnZV9jYXJ0X2VuYWJsZWQsICNwcGNwLW1lc3NhZ2VfcHJvZHVjdF9lbmFibGVkXCJcbiAgICAgICAgKVxuXG4gICAgICAgIGNvbnN0IHZhdWx0aW5nQ2hlY2tib3hlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgICAgICBcIiNwcGNwLXZhdWx0X2VuYWJsZWRcIlxuICAgICAgICApXG5cbiAgICAgICAgY29uc3QgcGF5TGF0ZXJFbmFibGVkTGFiZWxzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgICAgIFwiLnBwY3AtcGF5LWxhdGVyLWVuYWJsZWQtbGFiZWxcIlxuICAgICAgICApXG5cbiAgICAgICAgY29uc3QgcGF5TGF0ZXJEaXNhYmxlZExhYmVscyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgICAgICBcIi5wcGNwLXBheS1sYXRlci1kaXNhYmxlZC1sYWJlbFwiXG4gICAgICAgIClcblxuICAgICAgICBjb25zdCBkaXNhYmxlZENoZWNrYm94ZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICAgICAgJy5wcGNwLWRpc2FibGVkLWNoZWNrYm94J1xuICAgICAgICApXG5cbiAgICAgICAgZnVuY3Rpb24gYXRMZWFzdE9uZUNoZWNrZWQoY2hlY2tib3hlc05vZGVMaXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoY2hlY2tib3hlc05vZGVMaXN0KS5maWx0ZXIobm9kZSA9PiAhbm9kZS5kaXNhYmxlZCAmJiBub2RlLmNoZWNrZWQpLmxlbmd0aCA+IDBcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGRpc2FibGVBbGwobm9kZUxpc3Qpe1xuICAgICAgICAgICAgbm9kZUxpc3QuZm9yRWFjaChub2RlID0+IG5vZGUuc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsICd0cnVlJykpXG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBlbmFibGVBbGwobm9kZUxpc3Qpe1xuICAgICAgICAgICAgbm9kZUxpc3QuZm9yRWFjaChub2RlID0+IG5vZGUucmVtb3ZlQXR0cmlidXRlKCdkaXNhYmxlZCcpKVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gaGlkZUFsbChub2RlTGlzdCkge1xuICAgICAgICAgICAgbm9kZUxpc3QuZm9yRWFjaChub2RlID0+IG5vZGUuc3R5bGUuZGlzcGxheSA9ICdub25lJylcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGRpc3BsYXlBbGwobm9kZUxpc3QpIHtcbiAgICAgICAgICAgIG5vZGVMaXN0LmZvckVhY2gobm9kZSA9PiBub2RlLnN0eWxlLmRpc3BsYXkgPSAnJylcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHVuY2hlY2tBbGwobm9kZUxpc3Qpe1xuICAgICAgICAgICAgbm9kZUxpc3QuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgICAgICBub2RlLmNoZWNrZWQgPSBmYWxzZVxuICAgICAgICAgICAgICAgIG5vZGUuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2NoYW5nZScpKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGRpc2FibGVQYXlMYXRlcigpIHtcbiAgICAgICAgICAgIHVuY2hlY2tBbGwocGF5TGF0ZXJNZXNzYWdpbmdDaGVja2JveGVzKVxuICAgICAgICAgICAgZGlzYWJsZUFsbChwYXlMYXRlck1lc3NhZ2luZ0NoZWNrYm94ZXMpXG4gICAgICAgICAgICBoaWRlQWxsKHBheUxhdGVyRW5hYmxlZExhYmVscylcbiAgICAgICAgICAgIGRpc3BsYXlBbGwocGF5TGF0ZXJEaXNhYmxlZExhYmVscylcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGVuYWJsZVBheUxhdGVyKCkge1xuICAgICAgICAgICAgZW5hYmxlQWxsKHBheUxhdGVyTWVzc2FnaW5nQ2hlY2tib3hlcylcbiAgICAgICAgICAgIGRpc3BsYXlBbGwocGF5TGF0ZXJFbmFibGVkTGFiZWxzKVxuICAgICAgICAgICAgaGlkZUFsbChwYXlMYXRlckRpc2FibGVkTGFiZWxzKVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gdG9nZ2xlUGF5TGF0ZXIoKSB7XG4gICAgICAgICAgICBhdExlYXN0T25lQ2hlY2tlZCh2YXVsdGluZ0NoZWNrYm94ZXMpID8gZGlzYWJsZVBheUxhdGVyKCkgOiBlbmFibGVQYXlMYXRlcigpXG4gICAgICAgIH1cblxuICAgICAgICBkaXNhYmxlQWxsKCBkaXNhYmxlZENoZWNrYm94ZXMgKVxuICAgICAgICB0b2dnbGVQYXlMYXRlcigpXG5cbiAgICAgICAgdmF1bHRpbmdDaGVja2JveGVzLmZvckVhY2gobm9kZSA9PiBub2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRvZ2dsZVBheUxhdGVyKSk7XG4gICAgfVxuKTtcbiJdLCJmaWxlIjoiNzk1LmpzIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///795\n")}},__webpack_exports__={};__webpack_modules__[795]()})();
|
modules/ppcp-wc-gateway/resources/js/gateway-settings.js
CHANGED
@@ -9,6 +9,18 @@
|
|
9 |
"#ppcp-vault_enabled"
|
10 |
)
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
function atLeastOneChecked(checkboxesNodeList) {
|
13 |
return Array.prototype.slice.call(checkboxesNodeList).filter(node => !node.disabled && node.checked).length > 0
|
14 |
}
|
@@ -21,18 +33,41 @@
|
|
21 |
nodeList.forEach(node => node.removeAttribute('disabled'))
|
22 |
}
|
23 |
|
24 |
-
function
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
-
|
29 |
-
|
30 |
-
}
|
31 |
}
|
32 |
|
33 |
-
|
|
|
34 |
|
35 |
-
|
36 |
-
vaultingCheckboxes.forEach(node => node.addEventListener('change', updateCheckboxes));
|
37 |
}
|
38 |
);
|
9 |
"#ppcp-vault_enabled"
|
10 |
)
|
11 |
|
12 |
+
const payLaterEnabledLabels = document.querySelectorAll(
|
13 |
+
".ppcp-pay-later-enabled-label"
|
14 |
+
)
|
15 |
+
|
16 |
+
const payLaterDisabledLabels = document.querySelectorAll(
|
17 |
+
".ppcp-pay-later-disabled-label"
|
18 |
+
)
|
19 |
+
|
20 |
+
const disabledCheckboxes = document.querySelectorAll(
|
21 |
+
'.ppcp-disabled-checkbox'
|
22 |
+
)
|
23 |
+
|
24 |
function atLeastOneChecked(checkboxesNodeList) {
|
25 |
return Array.prototype.slice.call(checkboxesNodeList).filter(node => !node.disabled && node.checked).length > 0
|
26 |
}
|
33 |
nodeList.forEach(node => node.removeAttribute('disabled'))
|
34 |
}
|
35 |
|
36 |
+
function hideAll(nodeList) {
|
37 |
+
nodeList.forEach(node => node.style.display = 'none')
|
38 |
+
}
|
39 |
+
|
40 |
+
function displayAll(nodeList) {
|
41 |
+
nodeList.forEach(node => node.style.display = '')
|
42 |
+
}
|
43 |
+
|
44 |
+
function uncheckAll(nodeList){
|
45 |
+
nodeList.forEach(node => {
|
46 |
+
node.checked = false
|
47 |
+
node.dispatchEvent(new Event('change'))
|
48 |
+
})
|
49 |
+
}
|
50 |
+
|
51 |
+
function disablePayLater() {
|
52 |
+
uncheckAll(payLaterMessagingCheckboxes)
|
53 |
+
disableAll(payLaterMessagingCheckboxes)
|
54 |
+
hideAll(payLaterEnabledLabels)
|
55 |
+
displayAll(payLaterDisabledLabels)
|
56 |
+
}
|
57 |
+
|
58 |
+
function enablePayLater() {
|
59 |
+
enableAll(payLaterMessagingCheckboxes)
|
60 |
+
displayAll(payLaterEnabledLabels)
|
61 |
+
hideAll(payLaterDisabledLabels)
|
62 |
+
}
|
63 |
|
64 |
+
function togglePayLater() {
|
65 |
+
atLeastOneChecked(vaultingCheckboxes) ? disablePayLater() : enablePayLater()
|
|
|
66 |
}
|
67 |
|
68 |
+
disableAll( disabledCheckboxes )
|
69 |
+
togglePayLater()
|
70 |
|
71 |
+
vaultingCheckboxes.forEach(node => node.addEventListener('change', togglePayLater));
|
|
|
72 |
}
|
73 |
);
|
modules/ppcp-wc-gateway/services.php
CHANGED
@@ -13,6 +13,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway;
|
|
13 |
|
14 |
use Psr\Container\ContainerInterface;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
|
|
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
17 |
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
18 |
use WooCommerce\PayPalCommerce\Button\Helper\MessagesDisclaimers;
|
@@ -783,15 +784,7 @@ return array(
|
|
783 |
'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ),
|
784 |
'type' => 'checkbox',
|
785 |
'desc_tip' => true,
|
786 |
-
'label' =>
|
787 |
-
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
788 |
-
__( 'Enable saved cards and subscription features on your store. To use vaulting features, you must %1$senable vaulting on your account%2$s.', 'woocommerce-paypal-payments' ),
|
789 |
-
'<a
|
790 |
-
href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/#enable-vaulting-on-your-live-account"
|
791 |
-
target="_blank"
|
792 |
-
>',
|
793 |
-
'</a>'
|
794 |
-
),
|
795 |
'description' => __( 'Allow registered buyers to save PayPal and Credit Card accounts. Allow Subscription renewals.', 'woocommerce-paypal-payments' ),
|
796 |
'default' => false,
|
797 |
'screens' => array(
|
@@ -799,6 +792,7 @@ return array(
|
|
799 |
),
|
800 |
'requirements' => array(),
|
801 |
'gateway' => array( 'paypal', 'dcc' ),
|
|
|
802 |
),
|
803 |
'logging_enabled' => array(
|
804 |
'title' => __( 'Logging', 'woocommerce-paypal-payments' ),
|
@@ -989,7 +983,7 @@ return array(
|
|
989 |
'message_enabled' => array(
|
990 |
'title' => __( 'Enable message on Checkout', 'woocommerce-paypal-payments' ),
|
991 |
'type' => 'checkbox',
|
992 |
-
'label' => __( 'Enable on Checkout', 'woocommerce-paypal-payments' ),
|
993 |
'default' => true,
|
994 |
'screens' => array(
|
995 |
State::STATE_START,
|
@@ -1295,7 +1289,7 @@ return array(
|
|
1295 |
'message_product_enabled' => array(
|
1296 |
'title' => __( 'Enable message on Single Product', 'woocommerce-paypal-payments' ),
|
1297 |
'type' => 'checkbox',
|
1298 |
-
'label' => __( 'Enable on Single Product', 'woocommerce-paypal-payments' ),
|
1299 |
'default' => true,
|
1300 |
'screens' => array(
|
1301 |
State::STATE_START,
|
@@ -1601,7 +1595,7 @@ return array(
|
|
1601 |
'message_cart_enabled' => array(
|
1602 |
'title' => __( 'Enable message on Cart', 'woocommerce-paypal-payments' ),
|
1603 |
'type' => 'checkbox',
|
1604 |
-
'label' => __( 'Enable on Cart', 'woocommerce-paypal-payments' ),
|
1605 |
'default' => true,
|
1606 |
'screens' => array(
|
1607 |
State::STATE_START,
|
@@ -2047,17 +2041,6 @@ return array(
|
|
2047 |
$fields['disable_cards']['options'] = $card_options;
|
2048 |
$fields['card_icons']['options'] = array_merge( $dark_versions, $card_options );
|
2049 |
|
2050 |
-
/**
|
2051 |
-
* Display vault message on Pay Later label if vault is enabled.
|
2052 |
-
*/
|
2053 |
-
$settings = $container->get( 'wcgateway.settings' );
|
2054 |
-
if ( $settings->has( 'vault_enabled' ) && $settings->get( 'vault_enabled' ) ) {
|
2055 |
-
$message = __( "You have PayPal vaulting enabled, that's why Pay Later Messaging options are unavailable now. You cannot use both features at the same time.", 'woocommerce-paypal-payments' );
|
2056 |
-
$fields['message_enabled']['label'] = $message;
|
2057 |
-
$fields['message_product_enabled']['label'] = $message;
|
2058 |
-
$fields['message_cart_enabled']['label'] = $message;
|
2059 |
-
}
|
2060 |
-
|
2061 |
return $fields;
|
2062 |
},
|
2063 |
|
@@ -2156,4 +2139,44 @@ return array(
|
|
2156 |
$settings->has( 'logging_enabled' ) && $settings->get( 'logging_enabled' )
|
2157 |
);
|
2158 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2159 |
);
|
13 |
|
14 |
use Psr\Container\ContainerInterface;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
|
16 |
+
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
17 |
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
18 |
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
19 |
use WooCommerce\PayPalCommerce\Button\Helper\MessagesDisclaimers;
|
784 |
'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ),
|
785 |
'type' => 'checkbox',
|
786 |
'desc_tip' => true,
|
787 |
+
'label' => $container->get( 'button.helper.vaulting-label' ),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
788 |
'description' => __( 'Allow registered buyers to save PayPal and Credit Card accounts. Allow Subscription renewals.', 'woocommerce-paypal-payments' ),
|
789 |
'default' => false,
|
790 |
'screens' => array(
|
792 |
),
|
793 |
'requirements' => array(),
|
794 |
'gateway' => array( 'paypal', 'dcc' ),
|
795 |
+
'input_class' => $container->get( 'wcgateway.helper.vaulting-scope' ) ? array() : array( 'ppcp-disabled-checkbox' ),
|
796 |
),
|
797 |
'logging_enabled' => array(
|
798 |
'title' => __( 'Logging', 'woocommerce-paypal-payments' ),
|
983 |
'message_enabled' => array(
|
984 |
'title' => __( 'Enable message on Checkout', 'woocommerce-paypal-payments' ),
|
985 |
'type' => 'checkbox',
|
986 |
+
'label' => sprintf( $container->get( 'wcgateway.settings.fields.pay-later-label' ), __( 'Enable on Checkout', 'woocommerce-paypal-payments' ) ),
|
987 |
'default' => true,
|
988 |
'screens' => array(
|
989 |
State::STATE_START,
|
1289 |
'message_product_enabled' => array(
|
1290 |
'title' => __( 'Enable message on Single Product', 'woocommerce-paypal-payments' ),
|
1291 |
'type' => 'checkbox',
|
1292 |
+
'label' => sprintf( $container->get( 'wcgateway.settings.fields.pay-later-label' ), __( 'Enable on Single Product', 'woocommerce-paypal-payments' ) ),
|
1293 |
'default' => true,
|
1294 |
'screens' => array(
|
1295 |
State::STATE_START,
|
1595 |
'message_cart_enabled' => array(
|
1596 |
'title' => __( 'Enable message on Cart', 'woocommerce-paypal-payments' ),
|
1597 |
'type' => 'checkbox',
|
1598 |
+
'label' => sprintf( $container->get( 'wcgateway.settings.fields.pay-later-label' ), __( 'Enable on Cart', 'woocommerce-paypal-payments' ) ),
|
1599 |
'default' => true,
|
1600 |
'screens' => array(
|
1601 |
State::STATE_START,
|
2041 |
$fields['disable_cards']['options'] = $card_options;
|
2042 |
$fields['card_icons']['options'] = array_merge( $dark_versions, $card_options );
|
2043 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2044 |
return $fields;
|
2045 |
},
|
2046 |
|
2139 |
$settings->has( 'logging_enabled' ) && $settings->get( 'logging_enabled' )
|
2140 |
);
|
2141 |
},
|
2142 |
+
|
2143 |
+
'wcgateway.helper.vaulting-scope' => static function ( ContainerInterface $container ): bool {
|
2144 |
+
try {
|
2145 |
+
$token = $container->get( 'api.bearer' )->bearer();
|
2146 |
+
return $token->vaulting_available();
|
2147 |
+
} catch ( RuntimeException $exception ) {
|
2148 |
+
return false;
|
2149 |
+
}
|
2150 |
+
},
|
2151 |
+
|
2152 |
+
'button.helper.vaulting-label' => static function ( ContainerInterface $container ): string {
|
2153 |
+
$vaulting_label = __( 'Enable saved cards and subscription features on your store.', 'woocommerce-paypal-payments' );
|
2154 |
+
|
2155 |
+
if ( ! $container->get( 'wcgateway.helper.vaulting-scope' ) ) {
|
2156 |
+
$vaulting_label .= sprintf(
|
2157 |
+
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
2158 |
+
__( ' To use vaulting features, you must %1$senable vaulting on your account%2$s.', 'woocommerce-paypal-payments' ),
|
2159 |
+
'<a
|
2160 |
+
href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/#enable-vaulting-on-your-live-account"
|
2161 |
+
target="_blank"
|
2162 |
+
>',
|
2163 |
+
'</a>'
|
2164 |
+
);
|
2165 |
+
}
|
2166 |
+
|
2167 |
+
$vaulting_label .= '<p class="description">';
|
2168 |
+
$vaulting_label .= __( 'This will disable all Pay Later messaging on your site.', 'woocommerce-paypal-payments' );
|
2169 |
+
$vaulting_label .= '</p>';
|
2170 |
+
|
2171 |
+
return $vaulting_label;
|
2172 |
+
},
|
2173 |
+
|
2174 |
+
'wcgateway.settings.fields.pay-later-label' => static function ( ContainerInterface $container ): string {
|
2175 |
+
$pay_later_label = '<span class="ppcp-pay-later-enabled-label">%s</span>';
|
2176 |
+
$pay_later_label .= '<span class="ppcp-pay-later-disabled-label">';
|
2177 |
+
$pay_later_label .= __( "You have PayPal vaulting enabled, that's why Pay Later Messaging options are unavailable now. You cannot use both features at the same time.", 'woocommerce-paypal-payments' );
|
2178 |
+
$pay_later_label .= '</span>';
|
2179 |
+
|
2180 |
+
return $pay_later_label;
|
2181 |
+
},
|
2182 |
);
|
modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php
CHANGED
@@ -9,7 +9,6 @@ declare(strict_types=1);
|
|
9 |
|
10 |
namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
|
11 |
|
12 |
-
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
13 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
14 |
|
15 |
/**
|
@@ -31,34 +30,24 @@ class SettingsPageAssets {
|
|
31 |
*/
|
32 |
private $version;
|
33 |
|
34 |
-
/**
|
35 |
-
* The bearer.
|
36 |
-
*
|
37 |
-
* @var Bearer
|
38 |
-
*/
|
39 |
-
private $bearer;
|
40 |
-
|
41 |
/**
|
42 |
* Assets constructor.
|
43 |
*
|
44 |
* @param string $module_url The url of this module.
|
45 |
* @param string $version The assets version.
|
46 |
-
* @param Bearer $bearer The bearer.
|
47 |
*/
|
48 |
-
public function __construct( string $module_url, string $version
|
49 |
$this->module_url = $module_url;
|
50 |
$this->version = $version;
|
51 |
-
$this->bearer = $bearer;
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
* Register assets provided by this module.
|
56 |
*/
|
57 |
public function register_assets() {
|
58 |
-
$bearer = $this->bearer;
|
59 |
add_action(
|
60 |
'admin_enqueue_scripts',
|
61 |
-
function()
|
62 |
if ( ! is_admin() || wp_doing_ajax() ) {
|
63 |
return;
|
64 |
}
|
@@ -67,7 +56,7 @@ class SettingsPageAssets {
|
|
67 |
return;
|
68 |
}
|
69 |
|
70 |
-
$this->register_admin_assets(
|
71 |
}
|
72 |
);
|
73 |
|
@@ -98,10 +87,8 @@ class SettingsPageAssets {
|
|
98 |
|
99 |
/**
|
100 |
* Register assets for admin pages.
|
101 |
-
*
|
102 |
-
* @param Bearer $bearer The bearer.
|
103 |
*/
|
104 |
-
private function register_admin_assets(
|
105 |
wp_enqueue_script(
|
106 |
'ppcp-gateway-settings',
|
107 |
trailingslashit( $this->module_url ) . 'assets/js/gateway-settings.js',
|
@@ -109,18 +96,5 @@ class SettingsPageAssets {
|
|
109 |
$this->version,
|
110 |
true
|
111 |
);
|
112 |
-
|
113 |
-
try {
|
114 |
-
$token = $bearer->bearer();
|
115 |
-
wp_localize_script(
|
116 |
-
'ppcp-gateway-settings',
|
117 |
-
'PayPalCommerceGatewaySettings',
|
118 |
-
array(
|
119 |
-
'vaulting_features_available' => $token->vaulting_available(),
|
120 |
-
)
|
121 |
-
);
|
122 |
-
} catch ( RuntimeException $exception ) {
|
123 |
-
return;
|
124 |
-
}
|
125 |
}
|
126 |
}
|
9 |
|
10 |
namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
|
11 |
|
|
|
12 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
13 |
|
14 |
/**
|
30 |
*/
|
31 |
private $version;
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
/**
|
34 |
* Assets constructor.
|
35 |
*
|
36 |
* @param string $module_url The url of this module.
|
37 |
* @param string $version The assets version.
|
|
|
38 |
*/
|
39 |
+
public function __construct( string $module_url, string $version ) {
|
40 |
$this->module_url = $module_url;
|
41 |
$this->version = $version;
|
|
|
42 |
}
|
43 |
|
44 |
/**
|
45 |
* Register assets provided by this module.
|
46 |
*/
|
47 |
public function register_assets() {
|
|
|
48 |
add_action(
|
49 |
'admin_enqueue_scripts',
|
50 |
+
function() {
|
51 |
if ( ! is_admin() || wp_doing_ajax() ) {
|
52 |
return;
|
53 |
}
|
56 |
return;
|
57 |
}
|
58 |
|
59 |
+
$this->register_admin_assets();
|
60 |
}
|
61 |
);
|
62 |
|
87 |
|
88 |
/**
|
89 |
* Register assets for admin pages.
|
|
|
|
|
90 |
*/
|
91 |
+
private function register_admin_assets() {
|
92 |
wp_enqueue_script(
|
93 |
'ppcp-gateway-settings',
|
94 |
trailingslashit( $this->module_url ) . 'assets/js/gateway-settings.js',
|
96 |
$this->version,
|
97 |
true
|
98 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
}
|
100 |
}
|
modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php
CHANGED
@@ -69,7 +69,7 @@ class DisableGateways {
|
|
69 |
unset( $methods[ CreditCardGateway::ID ] );
|
70 |
}
|
71 |
|
72 |
-
if ( $this->settings->has( 'button_enabled' ) && ! $this->settings->get( 'button_enabled' ) && ! $this->session_handler->order() ) {
|
73 |
unset( $methods[ PayPalGateway::ID ] );
|
74 |
}
|
75 |
|
69 |
unset( $methods[ CreditCardGateway::ID ] );
|
70 |
}
|
71 |
|
72 |
+
if ( $this->settings->has( 'button_enabled' ) && ! $this->settings->get( 'button_enabled' ) && ! $this->session_handler->order() && is_checkout() ) {
|
73 |
unset( $methods[ PayPalGateway::ID ] );
|
74 |
}
|
75 |
|
modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php
CHANGED
@@ -33,12 +33,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|
33 |
|
34 |
use ProcessPaymentTrait;
|
35 |
|
36 |
-
const ID
|
37 |
-
const INTENT_META_KEY
|
38 |
-
const ORDER_ID_META_KEY
|
39 |
-
const ORDER_PAYMENT_MODE_META_KEY
|
40 |
-
const
|
41 |
-
const FEES_META_KEY
|
|
|
42 |
|
43 |
/**
|
44 |
* The Settings Renderer.
|
33 |
|
34 |
use ProcessPaymentTrait;
|
35 |
|
36 |
+
const ID = 'ppcp-gateway';
|
37 |
+
const INTENT_META_KEY = '_ppcp_paypal_intent';
|
38 |
+
const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
|
39 |
+
const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
|
40 |
+
const ORDER_PAYMENT_SOURCE_META_KEY = '_ppcp_paypal_payment_source';
|
41 |
+
const FEES_META_KEY = '_ppcp_paypal_fees';
|
42 |
+
const REFUNDS_META_KEY = '_ppcp_refunds';
|
43 |
|
44 |
/**
|
45 |
* The Settings Renderer.
|
modules/ppcp-wc-gateway/src/Processor/OrderMetaTrait.php
CHANGED
@@ -39,7 +39,7 @@ trait OrderMetaTrait {
|
|
39 |
);
|
40 |
$payment_source = $this->get_payment_source( $order );
|
41 |
if ( $payment_source ) {
|
42 |
-
$wc_order->update_meta_data( PayPalGateway::
|
43 |
}
|
44 |
}
|
45 |
|
39 |
);
|
40 |
$payment_source = $this->get_payment_source( $order );
|
41 |
if ( $payment_source ) {
|
42 |
+
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYMENT_SOURCE_META_KEY, $payment_source );
|
43 |
}
|
44 |
}
|
45 |
|
modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php
CHANGED
@@ -150,7 +150,8 @@ class OrderProcessor {
|
|
150 |
* @return bool
|
151 |
*/
|
152 |
public function process( \WC_Order $wc_order ): bool {
|
153 |
-
$
|
|
|
154 |
if ( ! $order ) {
|
155 |
$this->last_error = __( 'No PayPal order found in the current WooCommerce session.', 'woocommerce-paypal-payments' );
|
156 |
return false;
|
150 |
* @return bool
|
151 |
*/
|
152 |
public function process( \WC_Order $wc_order ): bool {
|
153 |
+
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
154 |
+
$order = $this->session_handler->order() ?? $this->order_endpoint->order( $order_id );
|
155 |
if ( ! $order ) {
|
156 |
$this->last_error = __( 'No PayPal order found in the current WooCommerce session.', 'woocommerce-paypal-payments' );
|
157 |
return false;
|
modules/ppcp-wc-gateway/src/Processor/RefundMetaTrait.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Operations with refund metadata.
|
4 |
+
*
|
5 |
+
* @package WooCommerce\PayPalCommerce\WcGateway\Processor
|
6 |
+
*/
|
7 |
+
|
8 |
+
declare(strict_types=1);
|
9 |
+
|
10 |
+
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
11 |
+
|
12 |
+
use WC_Order;
|
13 |
+
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Trait RefundMetaTrait.
|
17 |
+
*/
|
18 |
+
trait RefundMetaTrait {
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Adds a refund ID to the order metadata.
|
22 |
+
*
|
23 |
+
* @param WC_Order $wc_order The WC order to which metadata will be added.
|
24 |
+
* @param string $refund_id The refund ID to be added.
|
25 |
+
*/
|
26 |
+
protected function add_refund_to_meta( WC_Order $wc_order, string $refund_id ): void {
|
27 |
+
$refunds = $this->get_refunds_meta( $wc_order );
|
28 |
+
$refunds[] = $refund_id;
|
29 |
+
$wc_order->update_meta_data( PayPalGateway::REFUNDS_META_KEY, $refunds );
|
30 |
+
$wc_order->save();
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Returns refund IDs from the order metadata.
|
35 |
+
*
|
36 |
+
* @param WC_Order $wc_order The WC order.
|
37 |
+
*
|
38 |
+
* @return string[]
|
39 |
+
*/
|
40 |
+
protected function get_refunds_meta( WC_Order $wc_order ): array {
|
41 |
+
$refunds = $wc_order->get_meta( PayPalGateway::REFUNDS_META_KEY );
|
42 |
+
if ( ! is_array( $refunds ) ) {
|
43 |
+
$refunds = array();
|
44 |
+
}
|
45 |
+
return $refunds;
|
46 |
+
}
|
47 |
+
}
|
modules/ppcp-wc-gateway/src/Processor/RefundProcessor.php
CHANGED
@@ -26,6 +26,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
|
26 |
* Class RefundProcessor
|
27 |
*/
|
28 |
class RefundProcessor {
|
|
|
29 |
|
30 |
private const REFUND_MODE_REFUND = 'refund';
|
31 |
private const REFUND_MODE_VOID = 'void';
|
@@ -113,8 +114,8 @@ class RefundProcessor {
|
|
113 |
throw new RuntimeException( 'No capture.' );
|
114 |
}
|
115 |
|
116 |
-
$capture
|
117 |
-
$refund
|
118 |
$capture,
|
119 |
$capture->invoice_id(),
|
120 |
$reason,
|
@@ -122,7 +123,10 @@ class RefundProcessor {
|
|
122 |
new Money( $amount, $wc_order->get_currency() )
|
123 |
)
|
124 |
);
|
125 |
-
$this->payments_endpoint->refund( $refund );
|
|
|
|
|
|
|
126 |
break;
|
127 |
case self::REFUND_MODE_VOID:
|
128 |
$voidable_authorizations = array_filter(
|
26 |
* Class RefundProcessor
|
27 |
*/
|
28 |
class RefundProcessor {
|
29 |
+
use RefundMetaTrait;
|
30 |
|
31 |
private const REFUND_MODE_REFUND = 'refund';
|
32 |
private const REFUND_MODE_VOID = 'void';
|
114 |
throw new RuntimeException( 'No capture.' );
|
115 |
}
|
116 |
|
117 |
+
$capture = $captures[0];
|
118 |
+
$refund = new Refund(
|
119 |
$capture,
|
120 |
$capture->invoice_id(),
|
121 |
$reason,
|
123 |
new Money( $amount, $wc_order->get_currency() )
|
124 |
)
|
125 |
);
|
126 |
+
$refund_id = $this->payments_endpoint->refund( $refund );
|
127 |
+
|
128 |
+
$this->add_refund_to_meta( $wc_order, $refund_id );
|
129 |
+
|
130 |
break;
|
131 |
case self::REFUND_MODE_VOID:
|
132 |
$voidable_authorizations = array_filter(
|
modules/ppcp-wc-gateway/src/Settings/SettingsListener.php
CHANGED
@@ -167,7 +167,7 @@ class SettingsListener {
|
|
167 |
* Prevent enabling both Pay Later messaging and PayPal vaulting
|
168 |
*/
|
169 |
public function listen_for_vaulting_enabled() {
|
170 |
-
if ( ! $this->is_valid_site_request() ) {
|
171 |
return;
|
172 |
}
|
173 |
|
@@ -208,10 +208,6 @@ class SettingsListener {
|
|
208 |
$this->settings->set( 'message_product_enabled', false );
|
209 |
$this->settings->set( 'message_cart_enabled', false );
|
210 |
$this->settings->persist();
|
211 |
-
|
212 |
-
$redirect_url = admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' );
|
213 |
-
wp_safe_redirect( $redirect_url, 302 );
|
214 |
-
exit;
|
215 |
}
|
216 |
|
217 |
/**
|
@@ -441,19 +437,10 @@ class SettingsListener {
|
|
441 |
*/
|
442 |
private function is_valid_site_request() : bool {
|
443 |
|
444 |
-
/**
|
445 |
-
* No nonce needed at this point.
|
446 |
-
*
|
447 |
-
* phpcs:disable WordPress.Security.NonceVerification.Missing
|
448 |
-
* phpcs:disable WordPress.Security.NonceVerification.Recommended
|
449 |
-
*/
|
450 |
if ( empty( $this->page_id ) ) {
|
451 |
return false;
|
452 |
}
|
453 |
|
454 |
-
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
455 |
-
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
456 |
-
|
457 |
if ( ! current_user_can( 'manage_woocommerce' ) ) {
|
458 |
return false;
|
459 |
}
|
167 |
* Prevent enabling both Pay Later messaging and PayPal vaulting
|
168 |
*/
|
169 |
public function listen_for_vaulting_enabled() {
|
170 |
+
if ( ! $this->is_valid_site_request() || State::STATE_ONBOARDED !== $this->state->current_state() ) {
|
171 |
return;
|
172 |
}
|
173 |
|
208 |
$this->settings->set( 'message_product_enabled', false );
|
209 |
$this->settings->set( 'message_cart_enabled', false );
|
210 |
$this->settings->persist();
|
|
|
|
|
|
|
|
|
211 |
}
|
212 |
|
213 |
/**
|
437 |
*/
|
438 |
private function is_valid_site_request() : bool {
|
439 |
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
if ( empty( $this->page_id ) ) {
|
441 |
return false;
|
442 |
}
|
443 |
|
|
|
|
|
|
|
444 |
if ( ! current_user_can( 'manage_woocommerce' ) ) {
|
445 |
return false;
|
446 |
}
|
modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php
CHANGED
@@ -124,26 +124,6 @@ class SettingsRenderer {
|
|
124 |
|
125 |
$messages = array();
|
126 |
|
127 |
-
if ( $this->can_display_vaulting_admin_message() ) {
|
128 |
-
|
129 |
-
$vaulting_title = __( 'PayPal vaulting', 'woocommerce-paypal-payments' );
|
130 |
-
$pay_later_messages_title = __( 'Pay Later Messaging', 'woocommerce-paypal-payments' );
|
131 |
-
|
132 |
-
$enabled = $this->paypal_vaulting_is_enabled() ? $vaulting_title : $pay_later_messages_title;
|
133 |
-
$disabled = $this->settings_status->pay_later_messaging_is_enabled() ? $vaulting_title : $pay_later_messages_title;
|
134 |
-
|
135 |
-
$pay_later_messages_or_vaulting_text = sprintf(
|
136 |
-
// translators: %1$s and %2$s is translated PayPal vaulting and Pay Later Messaging strings.
|
137 |
-
__(
|
138 |
-
'You have %1$s enabled, that\'s why %2$s options are unavailable now. You cannot use both features at the same time.',
|
139 |
-
'woocommerce-paypal-payments'
|
140 |
-
),
|
141 |
-
$enabled,
|
142 |
-
$disabled
|
143 |
-
);
|
144 |
-
$messages[] = new Message( $pay_later_messages_or_vaulting_text, 'warning' );
|
145 |
-
}
|
146 |
-
|
147 |
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
148 |
//phpcs:disable WordPress.Security.NonceVerification.Missing
|
149 |
if ( ! isset( $_GET['ppcp-onboarding-error'] ) || ! empty( $_POST ) ) {
|
124 |
|
125 |
$messages = array();
|
126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
128 |
//phpcs:disable WordPress.Security.NonceVerification.Missing
|
129 |
if ( ! isset( $_GET['ppcp-onboarding-error'] ) || ! empty( $_POST ) ) {
|
modules/ppcp-wc-gateway/src/WCGatewayModule.php
CHANGED
@@ -81,6 +81,48 @@ class WCGatewayModule implements ModuleInterface {
|
|
81 |
if ( $breakdown ) {
|
82 |
$wc_order->update_meta_data( PayPalGateway::FEES_META_KEY, $breakdown->to_array() );
|
83 |
$wc_order->save_meta_data();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
}
|
85 |
},
|
86 |
10,
|
@@ -106,8 +148,7 @@ class WCGatewayModule implements ModuleInterface {
|
|
106 |
if ( $c->has( 'wcgateway.url' ) ) {
|
107 |
$assets = new SettingsPageAssets(
|
108 |
$c->get( 'wcgateway.url' ),
|
109 |
-
$c->get( 'ppcp.asset-version' )
|
110 |
-
$c->get( 'api.bearer' )
|
111 |
);
|
112 |
$assets->register_assets();
|
113 |
}
|
81 |
if ( $breakdown ) {
|
82 |
$wc_order->update_meta_data( PayPalGateway::FEES_META_KEY, $breakdown->to_array() );
|
83 |
$wc_order->save_meta_data();
|
84 |
+
$paypal_fee = $breakdown->paypal_fee();
|
85 |
+
if ( $paypal_fee ) {
|
86 |
+
update_post_meta( $wc_order->get_id(), 'PayPal Transaction Key', $paypal_fee->value() );
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
$fraud = $capture->fraud_processor_response();
|
91 |
+
if ( $fraud ) {
|
92 |
+
$fraud_responses = $fraud->to_array();
|
93 |
+
$avs_response_order_note_title = __( 'Address Verification Result', 'woocommerce-paypal-payments' );
|
94 |
+
/* translators: %1$s is AVS order note title, %2$s is AVS order note result markup */
|
95 |
+
$avs_response_order_note_format = __( '%1$s %2$s', 'woocommerce-paypal-payments' );
|
96 |
+
$avs_response_order_note_result_format = '<ul class="ppcp_avs_result">
|
97 |
+
<li>%1$s</li>
|
98 |
+
<ul class="ppcp_avs_result_inner">
|
99 |
+
<li>%2$s</li>
|
100 |
+
<li>%3$s</li>
|
101 |
+
</ul>
|
102 |
+
</ul>';
|
103 |
+
$avs_response_order_note_result = sprintf(
|
104 |
+
$avs_response_order_note_result_format,
|
105 |
+
/* translators: %s is fraud AVS code */
|
106 |
+
sprintf( __( 'AVS: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['avs_code'] ) ),
|
107 |
+
/* translators: %s is fraud AVS address match */
|
108 |
+
sprintf( __( 'Address Match: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['address_match'] ) ),
|
109 |
+
/* translators: %s is fraud AVS postal match */
|
110 |
+
sprintf( __( 'Postal Match: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['postal_match'] ) )
|
111 |
+
);
|
112 |
+
$avs_response_order_note = sprintf(
|
113 |
+
$avs_response_order_note_format,
|
114 |
+
esc_html( $avs_response_order_note_title ),
|
115 |
+
wp_kses_post( $avs_response_order_note_result )
|
116 |
+
);
|
117 |
+
$wc_order->add_order_note( $avs_response_order_note );
|
118 |
+
|
119 |
+
$cvv_response_order_note_format = '<ul class="ppcp_cvv_result"><li>%1$s</li></ul>';
|
120 |
+
$cvv_response_order_note = sprintf(
|
121 |
+
$cvv_response_order_note_format,
|
122 |
+
/* translators: %s is fraud CVV match */
|
123 |
+
sprintf( __( 'CVV2 Match: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['cvv_match'] ) )
|
124 |
+
);
|
125 |
+
$wc_order->add_order_note( $cvv_response_order_note );
|
126 |
}
|
127 |
},
|
128 |
10,
|
148 |
if ( $c->has( 'wcgateway.url' ) ) {
|
149 |
$assets = new SettingsPageAssets(
|
150 |
$c->get( 'wcgateway.url' ),
|
151 |
+
$c->get( 'ppcp.asset-version' )
|
|
|
152 |
);
|
153 |
$assets->register_assets();
|
154 |
}
|
modules/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php
CHANGED
@@ -10,14 +10,17 @@ declare(strict_types=1);
|
|
10 |
namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
|
11 |
|
12 |
use Psr\Log\LoggerInterface;
|
|
|
13 |
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Class PaymentCaptureRefunded
|
17 |
*/
|
18 |
class PaymentCaptureRefunded implements RequestHandler {
|
19 |
|
20 |
-
use PrefixTrait, TransactionIdHandlingTrait;
|
21 |
|
22 |
/**
|
23 |
* The logger.
|
@@ -49,25 +52,26 @@ class PaymentCaptureRefunded implements RequestHandler {
|
|
49 |
/**
|
50 |
* Whether a handler is responsible for a given request or not.
|
51 |
*
|
52 |
-
* @param
|
53 |
*
|
54 |
* @return bool
|
55 |
*/
|
56 |
-
public function responsible_for_request(
|
57 |
return in_array( $request['event_type'], $this->event_types(), true );
|
58 |
}
|
59 |
|
60 |
/**
|
61 |
* Responsible for handling the request.
|
62 |
*
|
63 |
-
* @param
|
64 |
*
|
65 |
-
* @return
|
66 |
*/
|
67 |
-
public function handle_request(
|
68 |
-
$response
|
69 |
-
$order_id
|
70 |
$this->sanitize_custom_id( $request['resource']['custom_id'] ) : 0;
|
|
|
71 |
if ( ! $order_id ) {
|
72 |
$message = sprintf(
|
73 |
// translators: %s is the PayPal webhook Id.
|
@@ -85,7 +89,7 @@ class PaymentCaptureRefunded implements RequestHandler {
|
|
85 |
)
|
86 |
);
|
87 |
$response['message'] = $message;
|
88 |
-
return
|
89 |
}
|
90 |
|
91 |
$wc_order = wc_get_order( $order_id );
|
@@ -93,7 +97,7 @@ class PaymentCaptureRefunded implements RequestHandler {
|
|
93 |
$message = sprintf(
|
94 |
// translators: %s is the PayPal refund Id.
|
95 |
__( 'Order for PayPal refund %s not found.', 'woocommerce-paypal-payments' ),
|
96 |
-
|
97 |
);
|
98 |
$this->logger->log(
|
99 |
'warning',
|
@@ -103,7 +107,13 @@ class PaymentCaptureRefunded implements RequestHandler {
|
|
103 |
)
|
104 |
);
|
105 |
$response['message'] = $message;
|
106 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
}
|
108 |
|
109 |
/**
|
@@ -132,7 +142,7 @@ class PaymentCaptureRefunded implements RequestHandler {
|
|
132 |
);
|
133 |
|
134 |
$response['message'] = $refund->get_error_message();
|
135 |
-
return
|
136 |
}
|
137 |
|
138 |
$this->logger->log(
|
@@ -152,11 +162,12 @@ class PaymentCaptureRefunded implements RequestHandler {
|
|
152 |
)
|
153 |
);
|
154 |
|
155 |
-
if (
|
156 |
-
$this->update_transaction_id( $
|
|
|
157 |
}
|
158 |
|
159 |
$response['success'] = true;
|
160 |
-
return
|
161 |
}
|
162 |
}
|
10 |
namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
|
11 |
|
12 |
use Psr\Log\LoggerInterface;
|
13 |
+
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundMetaTrait;
|
14 |
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
|
15 |
+
use WP_REST_Request;
|
16 |
+
use WP_REST_Response;
|
17 |
|
18 |
/**
|
19 |
* Class PaymentCaptureRefunded
|
20 |
*/
|
21 |
class PaymentCaptureRefunded implements RequestHandler {
|
22 |
|
23 |
+
use PrefixTrait, TransactionIdHandlingTrait, RefundMetaTrait;
|
24 |
|
25 |
/**
|
26 |
* The logger.
|
52 |
/**
|
53 |
* Whether a handler is responsible for a given request or not.
|
54 |
*
|
55 |
+
* @param WP_REST_Request $request The request.
|
56 |
*
|
57 |
* @return bool
|
58 |
*/
|
59 |
+
public function responsible_for_request( WP_REST_Request $request ): bool {
|
60 |
return in_array( $request['event_type'], $this->event_types(), true );
|
61 |
}
|
62 |
|
63 |
/**
|
64 |
* Responsible for handling the request.
|
65 |
*
|
66 |
+
* @param WP_REST_Request $request The request.
|
67 |
*
|
68 |
+
* @return WP_REST_Response
|
69 |
*/
|
70 |
+
public function handle_request( WP_REST_Request $request ): WP_REST_Response {
|
71 |
+
$response = array( 'success' => false );
|
72 |
+
$order_id = isset( $request['resource']['custom_id'] ) ?
|
73 |
$this->sanitize_custom_id( $request['resource']['custom_id'] ) : 0;
|
74 |
+
$refund_id = (string) ( $request['resource']['id'] ?? '' );
|
75 |
if ( ! $order_id ) {
|
76 |
$message = sprintf(
|
77 |
// translators: %s is the PayPal webhook Id.
|
89 |
)
|
90 |
);
|
91 |
$response['message'] = $message;
|
92 |
+
return new WP_REST_Response( $response );
|
93 |
}
|
94 |
|
95 |
$wc_order = wc_get_order( $order_id );
|
97 |
$message = sprintf(
|
98 |
// translators: %s is the PayPal refund Id.
|
99 |
__( 'Order for PayPal refund %s not found.', 'woocommerce-paypal-payments' ),
|
100 |
+
$refund_id
|
101 |
);
|
102 |
$this->logger->log(
|
103 |
'warning',
|
107 |
)
|
108 |
);
|
109 |
$response['message'] = $message;
|
110 |
+
return new WP_REST_Response( $response );
|
111 |
+
}
|
112 |
+
|
113 |
+
$already_added_refunds = $this->get_refunds_meta( $wc_order );
|
114 |
+
if ( in_array( $refund_id, $already_added_refunds, true ) ) {
|
115 |
+
$this->logger->info( "Refund {$refund_id} is already handled." );
|
116 |
+
return new WP_REST_Response( $response );
|
117 |
}
|
118 |
|
119 |
/**
|
142 |
);
|
143 |
|
144 |
$response['message'] = $refund->get_error_message();
|
145 |
+
return new WP_REST_Response( $response );
|
146 |
}
|
147 |
|
148 |
$this->logger->log(
|
162 |
)
|
163 |
);
|
164 |
|
165 |
+
if ( $refund_id ) {
|
166 |
+
$this->update_transaction_id( $refund_id, $wc_order, $this->logger );
|
167 |
+
$this->add_refund_to_meta( $wc_order, $refund_id );
|
168 |
}
|
169 |
|
170 |
$response['success'] = true;
|
171 |
+
return new WP_REST_Response( $response );
|
172 |
}
|
173 |
}
|
psalm.xml.dist
CHANGED
@@ -151,5 +151,11 @@
|
|
151 |
<MixedStringOffsetAssignment errorLevel="info"/>
|
152 |
<ParamNameMismatch errorLevel="info"/>
|
153 |
<RedundantCastGivenDocblockType errorLevel="info"/>
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
</issueHandlers>
|
155 |
</psalm>
|
151 |
<MixedStringOffsetAssignment errorLevel="info"/>
|
152 |
<ParamNameMismatch errorLevel="info"/>
|
153 |
<RedundantCastGivenDocblockType errorLevel="info"/>
|
154 |
+
|
155 |
+
<TooManyArguments>
|
156 |
+
<errorLevel type="suppress">
|
157 |
+
<referencedFunction name="apply_filters" />
|
158 |
+
</errorLevel>
|
159 |
+
</TooManyArguments>
|
160 |
</issueHandlers>
|
161 |
</psalm>
|
readme.txt
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
Contributors: woocommerce, automattic
|
3 |
Tags: woocommerce, paypal, payments, ecommerce, e-commerce, store, sales, sell, shop, shopping, cart, checkout
|
4 |
Requires at least: 5.3
|
5 |
-
Tested up to:
|
6 |
Requires PHP: 7.1
|
7 |
-
Stable tag: 1.8.
|
8 |
License: GPLv2
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -81,11 +81,27 @@ Follow the steps below to connect the plugin to your PayPal account:
|
|
81 |
|
82 |
== Changelog ==
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
= 1.8.0 =
|
85 |
* Add - Allow free trial subscriptions #580
|
86 |
* Fix - The Card Processing does not appear as an available payment method when manually creating an order #562
|
87 |
-
* Fix - Express buttons & Pay Later visible on variable Subscription products /w disabled vaulting #281
|
88 |
-
* Fix - Pay for order (guest) failing when no email address available #535
|
89 |
* Fix - Emoji in product description causing INVALID_STRING_LENGTH error #491
|
90 |
* Enhancement - Change cart total amount that is sent to PayPal gateway #486
|
91 |
* Enhancement - Include dark Visa and Mastercard gateway icon list for PayPal Card Processing #566
|
@@ -144,7 +160,7 @@ Follow the steps below to connect the plugin to your PayPal account:
|
|
144 |
* Fix - Empty space in invoice prefix causes smart buttons to not load #390
|
145 |
* Fix - woocommerce_payment_complete action not triggered for payments completed via webhook #399
|
146 |
* Fix - Paying with Venmo - Change funding source on checkout page and receipt to Venmo #394
|
147 |
-
* Fix - Internal server error on checkout when selected saved card but then switched to paypal #403
|
148 |
* Enhancement - Allow formatted text for the Description field #407
|
149 |
* Enhancement - Remove filter to prevent On-Hold emails #411
|
150 |
|
2 |
Contributors: woocommerce, automattic
|
3 |
Tags: woocommerce, paypal, payments, ecommerce, e-commerce, store, sales, sell, shop, shopping, cart, checkout
|
4 |
Requires at least: 5.3
|
5 |
+
Tested up to: 6.0
|
6 |
Requires PHP: 7.1
|
7 |
+
Stable tag: 1.8.1
|
8 |
License: GPLv2
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
81 |
|
82 |
== Changelog ==
|
83 |
|
84 |
+
= 1.8.1 =
|
85 |
+
* Fix - Manual orders return an error for guest users when paying with PayPal Card Processing #530
|
86 |
+
* Fix - "No PayPal order found in the current WooCommerce session" error for guests on Pay for Order page #605
|
87 |
+
* Fix - Error on order discount by third-party plugins #548
|
88 |
+
* Fix - Empty payer data may cause CITY_REQUIRED error for certain checkout countries #632
|
89 |
+
* Fix - Mini Cart smart buttons visible after adding subscription product to cart from "shop" page while Vaulting is disabled #624
|
90 |
+
* Fix - Smart buttons not loading when free product is in cart but shipping costs are available #606
|
91 |
+
* Fix - Smart button & Pay Later messaging disappear on the cart page after changing shipping method #288
|
92 |
+
* Fix - Disabling PayPal Checkout on the checkout page also removes the button from the Cart and Product Pages #577
|
93 |
+
* Fix - Partial refunds via PayPal are created twice/double in WooCommerce order #522
|
94 |
+
* Fix - Emoji in product description causing INVALID_STRING_LENGTH error #491
|
95 |
+
* Enhancement - Vaulting & Pay Later UI/UX #174
|
96 |
+
* Enhancement - Redirect after updating settings for DCC sends you to PPCP settings screen #392
|
97 |
+
* Enhancement - Add Fraud Processor Response as an order note #616
|
98 |
+
* Enhancement - Add the Paypal Fee to the Meta Custom Field for export purposes #591
|
99 |
+
|
100 |
= 1.8.0 =
|
101 |
* Add - Allow free trial subscriptions #580
|
102 |
* Fix - The Card Processing does not appear as an available payment method when manually creating an order #562
|
103 |
+
* Fix - Express buttons & Pay Later visible on variable Subscription products /w disabled vaulting #281
|
104 |
+
* Fix - Pay for order (guest) failing when no email address available #535
|
105 |
* Fix - Emoji in product description causing INVALID_STRING_LENGTH error #491
|
106 |
* Enhancement - Change cart total amount that is sent to PayPal gateway #486
|
107 |
* Enhancement - Include dark Visa and Mastercard gateway icon list for PayPal Card Processing #566
|
160 |
* Fix - Empty space in invoice prefix causes smart buttons to not load #390
|
161 |
* Fix - woocommerce_payment_complete action not triggered for payments completed via webhook #399
|
162 |
* Fix - Paying with Venmo - Change funding source on checkout page and receipt to Venmo #394
|
163 |
+
* Fix - Internal server error on checkout when selected saved card but then switched to paypal #403
|
164 |
* Enhancement - Allow formatted text for the Description field #407
|
165 |
* Enhancement - Remove filter to prevent On-Hold emails #411
|
166 |
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit5a08559ae58536f83fd0f0260535ccff::getLoader();
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -22,15 +22,15 @@ class ComposerAutoloaderInit16558e4f2223b33dd8a9ed3fc3028843
|
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
-
spl_autoload_register(array('
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
-
spl_autoload_unregister(array('
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
-
call_user_func(\Composer\Autoload\
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
@@ -51,19 +51,19 @@ class ComposerAutoloaderInit16558e4f2223b33dd8a9ed3fc3028843
|
|
51 |
$loader->register(true);
|
52 |
|
53 |
if ($useStaticLoader) {
|
54 |
-
$includeFiles = Composer\Autoload\
|
55 |
} else {
|
56 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
57 |
}
|
58 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
59 |
-
|
60 |
}
|
61 |
|
62 |
return $loader;
|
63 |
}
|
64 |
}
|
65 |
|
66 |
-
function
|
67 |
{
|
68 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
69 |
require $file;
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInit5a08559ae58536f83fd0f0260535ccff
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
+
spl_autoload_register(array('ComposerAutoloaderInit5a08559ae58536f83fd0f0260535ccff', 'loadClassLoader'), true, true);
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit5a08559ae58536f83fd0f0260535ccff', 'loadClassLoader'));
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit5a08559ae58536f83fd0f0260535ccff::getInitializer($loader));
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
51 |
$loader->register(true);
|
52 |
|
53 |
if ($useStaticLoader) {
|
54 |
+
$includeFiles = Composer\Autoload\ComposerStaticInit5a08559ae58536f83fd0f0260535ccff::$files;
|
55 |
} else {
|
56 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
57 |
}
|
58 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
59 |
+
composerRequire5a08559ae58536f83fd0f0260535ccff($fileIdentifier, $file);
|
60 |
}
|
61 |
|
62 |
return $loader;
|
63 |
}
|
64 |
}
|
65 |
|
66 |
+
function composerRequire5a08559ae58536f83fd0f0260535ccff($fileIdentifier, $file)
|
67 |
{
|
68 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
69 |
require $file;
|
vendor/composer/autoload_static.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
@@ -172,9 +172,9 @@ class ComposerStaticInit16558e4f2223b33dd8a9ed3fc3028843
|
|
172 |
public static function getInitializer(ClassLoader $loader)
|
173 |
{
|
174 |
return \Closure::bind(function () use ($loader) {
|
175 |
-
$loader->prefixLengthsPsr4 =
|
176 |
-
$loader->prefixDirsPsr4 =
|
177 |
-
$loader->classMap =
|
178 |
|
179 |
}, null, ClassLoader::class);
|
180 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInit5a08559ae58536f83fd0f0260535ccff
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
172 |
public static function getInitializer(ClassLoader $loader)
|
173 |
{
|
174 |
return \Closure::bind(function () use ($loader) {
|
175 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInit5a08559ae58536f83fd0f0260535ccff::$prefixLengthsPsr4;
|
176 |
+
$loader->prefixDirsPsr4 = ComposerStaticInit5a08559ae58536f83fd0f0260535ccff::$prefixDirsPsr4;
|
177 |
+
$loader->classMap = ComposerStaticInit5a08559ae58536f83fd0f0260535ccff::$classMap;
|
178 |
|
179 |
}, null, ClassLoader::class);
|
180 |
}
|
woocommerce-paypal-payments.php
CHANGED
@@ -3,13 +3,13 @@
|
|
3 |
* Plugin Name: WooCommerce PayPal Payments
|
4 |
* Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
|
5 |
* Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
|
6 |
-
* Version: 1.8.
|
7 |
* Author: WooCommerce
|
8 |
* Author URI: https://woocommerce.com/
|
9 |
* License: GPL-2.0
|
10 |
* Requires PHP: 7.1
|
11 |
* WC requires at least: 3.9
|
12 |
-
* WC tested up to: 6.
|
13 |
* Text Domain: woocommerce-paypal-payments
|
14 |
*
|
15 |
* @package WooCommerce\PayPalCommerce
|
3 |
* Plugin Name: WooCommerce PayPal Payments
|
4 |
* Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
|
5 |
* Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
|
6 |
+
* Version: 1.8.1
|
7 |
* Author: WooCommerce
|
8 |
* Author URI: https://woocommerce.com/
|
9 |
* License: GPL-2.0
|
10 |
* Requires PHP: 7.1
|
11 |
* WC requires at least: 3.9
|
12 |
+
* WC tested up to: 6.5
|
13 |
* Text Domain: woocommerce-paypal-payments
|
14 |
*
|
15 |
* @package WooCommerce\PayPalCommerce
|