Version Description
- Fix - Payments fail when using custom order numbers #354
- Fix - Do not display saved payments on PayPal buttons if vault option is disabled #358
- Fix - Double "Place Order" button #362
- Fix - Coupon causes TAX_TOTAL_MISMATCH #372
- Fix - Funding sources Mercado Pago and BLIK can't be disabled #383
- Fix - Customer details not available in order and name gets replaced by xxx@dcc2.paypal.com #378
- Fix - 3D Secure failing for certain credit card types with PayPal Card Processing #379
- Fix - Error messages are not cleared even when checkout is re-attempted (DCC) #366
- Add - New additions for system report status #377
Download this release
Release Info
Developer | woothemes |
Plugin | WooCommerce PayPal Payments |
Version | 1.6.3 |
Comparing to | |
See all releases |
Code changes from version 1.6.2 to 1.6.3
- changelog.txt +11 -0
- modules/ppcp-api-client/services.php +323 -46
- modules/ppcp-api-client/src/Endpoint/BillingAgreementsEndpoint.php +134 -0
- modules/ppcp-api-client/src/Endpoint/IdentityToken.php +20 -6
- modules/ppcp-api-client/src/Factory/AmountFactory.php +16 -8
- modules/ppcp-api-client/src/Factory/ItemFactory.php +21 -8
- modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php +2 -3
- modules/ppcp-api-client/src/Helper/DccApplies.php +47 -182
- modules/ppcp-button/assets/css/hosted-fields.css +1 -1
- modules/ppcp-button/assets/js/button.js +1 -1
- modules/ppcp-button/resources/css/hosted-fields.scss +4 -0
- modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js +50 -53
- modules/ppcp-button/resources/js/modules/ContextBootstrap/PayNowBootstrap.js +5 -74
- modules/ppcp-button/resources/js/modules/ErrorHandler.js +3 -3
- modules/ppcp-button/resources/js/modules/Helper/Hiding.js +44 -0
- modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForPayNow.js +2 -0
- modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js +17 -0
- modules/ppcp-button/services.php +6 -2
- modules/ppcp-button/src/Assets/SmartButton.php +19 -8
- modules/ppcp-button/src/Helper/MessagesApply.php +17 -3
- modules/ppcp-button/src/Helper/MessagesDisclaimers.php +17 -4
- modules/ppcp-compat/src/PPEC/PPECHelper.php +9 -0
- modules/ppcp-compat/src/PPEC/SettingsImporter.php +1 -1
- modules/ppcp-status-report/src/Renderer.php +4 -2
- modules/ppcp-status-report/src/StatusReportModule.php +112 -34
- modules/ppcp-vaulting/src/VaultingModule.php +5 -0
- modules/ppcp-wc-gateway/services.php +17 -13
- modules/ppcp-wc-gateway/src/Gateway/ProcessPaymentTrait.php +2 -2
- modules/ppcp-webhooks/services.php +11 -0
- modules/ppcp-webhooks/src/Handler/PrefixTrait.php +4 -1
- modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php +12 -0
- modules/ppcp-webhooks/src/WebhookInfoStorage.php +76 -0
- modules/ppcp-webhooks/src/WebhookRegistrar.php +16 -4
- readme.txt +12 -1
- vendor/autoload.php +1 -1
- vendor/composer/autoload_real.php +7 -7
- vendor/composer/autoload_static.php +3 -3
- woocommerce-paypal-payments.php +1 -1
changelog.txt
CHANGED
@@ -1,5 +1,16 @@
|
|
1 |
*** Changelog ***
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
= 1.6.2 - 2021-11-22 =
|
4 |
* Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
|
5 |
* Fix - Can't checkout to certain countries with optional postcode #330
|
1 |
*** Changelog ***
|
2 |
|
3 |
+
= 1.6.3 - 2021-12-14 =
|
4 |
+
* Fix - Payments fail when using custom order numbers #354
|
5 |
+
* Fix - Do not display saved payments on PayPal buttons if vault option is disabled #358
|
6 |
+
* Fix - Double "Place Order" button #362
|
7 |
+
* Fix - Coupon causes TAX_TOTAL_MISMATCH #372
|
8 |
+
* Fix - Funding sources Mercado Pago and BLIK can't be disabled #383
|
9 |
+
* Fix - Customer details not available in order and name gets replaced by xxx@dcc2.paypal.com #378
|
10 |
+
* Fix - 3D Secure failing for certain credit card types with PayPal Card Processing #379
|
11 |
+
* Fix - Error messages are not cleared even when checkout is re-attempted (DCC) #366
|
12 |
+
* Add - New additions for system report status #377
|
13 |
+
|
14 |
= 1.6.2 - 2021-11-22 =
|
15 |
* Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
|
16 |
* Fix - Can't checkout to certain countries with optional postcode #330
|
modules/ppcp-api-client/services.php
CHANGED
@@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient;
|
|
12 |
use Psr\Container\ContainerInterface;
|
13 |
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
14 |
use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
|
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\LoginSeller;
|
17 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
@@ -48,31 +49,31 @@ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
|
|
48 |
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
49 |
|
50 |
return array(
|
51 |
-
'api.host'
|
52 |
return PAYPAL_API_URL;
|
53 |
},
|
54 |
-
'api.paypal-host'
|
55 |
return PAYPAL_API_URL;
|
56 |
},
|
57 |
-
'api.partner_merchant_id'
|
58 |
return '';
|
59 |
},
|
60 |
-
'api.merchant_email'
|
61 |
return '';
|
62 |
},
|
63 |
-
'api.merchant_id'
|
64 |
return '';
|
65 |
},
|
66 |
-
'api.key'
|
67 |
return '';
|
68 |
},
|
69 |
-
'api.secret'
|
70 |
return '';
|
71 |
},
|
72 |
-
'api.prefix'
|
73 |
return 'WC-';
|
74 |
},
|
75 |
-
'api.bearer'
|
76 |
$cache = new Cache( 'ppcp-paypal-bearer' );
|
77 |
$key = $container->get( 'api.key' );
|
78 |
$secret = $container->get( 'api.secret' );
|
@@ -88,7 +89,7 @@ return array(
|
|
88 |
$settings
|
89 |
);
|
90 |
},
|
91 |
-
'api.endpoint.partners'
|
92 |
return new PartnersEndpoint(
|
93 |
$container->get( 'api.host' ),
|
94 |
$container->get( 'api.bearer' ),
|
@@ -98,10 +99,10 @@ return array(
|
|
98 |
$container->get( 'api.merchant_id' )
|
99 |
);
|
100 |
},
|
101 |
-
'api.factory.sellerstatus'
|
102 |
return new SellerStatusFactory();
|
103 |
},
|
104 |
-
'api.endpoint.payment-token'
|
105 |
return new PaymentTokenEndpoint(
|
106 |
$container->get( 'api.host' ),
|
107 |
$container->get( 'api.bearer' ),
|
@@ -110,7 +111,7 @@ return array(
|
|
110 |
$container->get( 'api.prefix' )
|
111 |
);
|
112 |
},
|
113 |
-
'api.endpoint.webhook'
|
114 |
|
115 |
return new WebhookEndpoint(
|
116 |
$container->get( 'api.host' ),
|
@@ -120,7 +121,7 @@ return array(
|
|
120 |
$container->get( 'woocommerce.logger.woocommerce' )
|
121 |
);
|
122 |
},
|
123 |
-
'api.endpoint.partner-referrals'
|
124 |
|
125 |
return new PartnerReferrals(
|
126 |
$container->get( 'api.host' ),
|
@@ -129,18 +130,19 @@ return array(
|
|
129 |
$container->get( 'woocommerce.logger.woocommerce' )
|
130 |
);
|
131 |
},
|
132 |
-
'api.endpoint.identity-token'
|
133 |
-
|
134 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
135 |
$prefix = $container->get( 'api.prefix' );
|
|
|
136 |
return new IdentityToken(
|
137 |
$container->get( 'api.host' ),
|
138 |
$container->get( 'api.bearer' ),
|
139 |
$logger,
|
140 |
-
$prefix
|
|
|
141 |
);
|
142 |
},
|
143 |
-
'api.endpoint.payments'
|
144 |
$authorizations_factory = $container->get( 'api.factory.authorization' );
|
145 |
$capture_factory = $container->get( 'api.factory.capture' );
|
146 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
@@ -153,7 +155,7 @@ return array(
|
|
153 |
$logger
|
154 |
);
|
155 |
},
|
156 |
-
'api.endpoint.login-seller'
|
157 |
|
158 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
159 |
return new LoginSeller(
|
@@ -162,7 +164,7 @@ return array(
|
|
162 |
$logger
|
163 |
);
|
164 |
},
|
165 |
-
'api.endpoint.order'
|
166 |
$order_factory = $container->get( 'api.factory.order' );
|
167 |
$patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
|
168 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
@@ -189,47 +191,54 @@ return array(
|
|
189 |
$subscription_helper
|
190 |
);
|
191 |
},
|
192 |
-
'api.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
return new PayPalRequestIdRepository();
|
194 |
},
|
195 |
-
'api.repository.application-context'
|
196 |
|
197 |
$settings = $container->get( 'wcgateway.settings' );
|
198 |
return new ApplicationContextRepository( $settings );
|
199 |
},
|
200 |
-
'api.repository.partner-referrals-data'
|
201 |
|
202 |
$merchant_email = $container->get( 'api.merchant_email' );
|
203 |
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
204 |
return new PartnerReferralsData( $merchant_email, $dcc_applies );
|
205 |
},
|
206 |
-
'api.repository.cart'
|
207 |
$factory = $container->get( 'api.factory.purchase-unit' );
|
208 |
return new CartRepository( $factory );
|
209 |
},
|
210 |
-
'api.repository.payee'
|
211 |
$merchant_email = $container->get( 'api.merchant_email' );
|
212 |
$merchant_id = $container->get( 'api.merchant_id' );
|
213 |
return new PayeeRepository( $merchant_email, $merchant_id );
|
214 |
},
|
215 |
-
'api.factory.application-context'
|
216 |
return new ApplicationContextFactory();
|
217 |
},
|
218 |
-
'api.factory.payment-token'
|
219 |
return new PaymentTokenFactory();
|
220 |
},
|
221 |
-
'api.factory.webhook'
|
222 |
return new WebhookFactory();
|
223 |
},
|
224 |
-
'api.factory.webhook-event'
|
225 |
return new WebhookEventFactory();
|
226 |
},
|
227 |
-
'api.factory.capture'
|
228 |
|
229 |
$amount_factory = $container->get( 'api.factory.amount' );
|
230 |
return new CaptureFactory( $amount_factory );
|
231 |
},
|
232 |
-
'api.factory.purchase-unit'
|
233 |
|
234 |
$amount_factory = $container->get( 'api.factory.amount' );
|
235 |
$payee_repository = $container->get( 'api.repository.payee' );
|
@@ -249,34 +258,39 @@ return array(
|
|
249 |
$prefix
|
250 |
);
|
251 |
},
|
252 |
-
'api.factory.patch-collection-factory'
|
253 |
return new PatchCollectionFactory();
|
254 |
},
|
255 |
-
'api.factory.payee'
|
256 |
return new PayeeFactory();
|
257 |
},
|
258 |
-
'api.factory.item'
|
259 |
-
return new ItemFactory(
|
|
|
|
|
260 |
},
|
261 |
-
'api.factory.shipping'
|
262 |
$address_factory = $container->get( 'api.factory.address' );
|
263 |
return new ShippingFactory( $address_factory );
|
264 |
},
|
265 |
-
'api.factory.amount'
|
266 |
$item_factory = $container->get( 'api.factory.item' );
|
267 |
-
return new AmountFactory(
|
|
|
|
|
|
|
268 |
},
|
269 |
-
'api.factory.payer'
|
270 |
$address_factory = $container->get( 'api.factory.address' );
|
271 |
return new PayerFactory( $address_factory );
|
272 |
},
|
273 |
-
'api.factory.address'
|
274 |
return new AddressFactory();
|
275 |
},
|
276 |
-
'api.factory.payment-source'
|
277 |
return new PaymentSourceFactory();
|
278 |
},
|
279 |
-
'api.factory.order'
|
280 |
$purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
|
281 |
$payer_factory = $container->get( 'api.factory.payer' );
|
282 |
$application_context_repository = $container->get( 'api.repository.application-context' );
|
@@ -290,15 +304,278 @@ return array(
|
|
290 |
$payment_source_factory
|
291 |
);
|
292 |
},
|
293 |
-
'api.factory.payments'
|
294 |
$authorizations_factory = $container->get( 'api.factory.authorization' );
|
295 |
$capture_factory = $container->get( 'api.factory.capture' );
|
296 |
return new PaymentsFactory( $authorizations_factory, $capture_factory );
|
297 |
},
|
298 |
-
'api.factory.authorization'
|
299 |
return new AuthorizationFactory();
|
300 |
},
|
301 |
-
'api.helpers.dccapplies'
|
302 |
-
return new DccApplies(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
},
|
304 |
);
|
12 |
use Psr\Container\ContainerInterface;
|
13 |
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
14 |
use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
15 |
+
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingAgreementsEndpoint;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
|
17 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\LoginSeller;
|
18 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
49 |
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
50 |
|
51 |
return array(
|
52 |
+
'api.host' => function( ContainerInterface $container ) : string {
|
53 |
return PAYPAL_API_URL;
|
54 |
},
|
55 |
+
'api.paypal-host' => function( ContainerInterface $container ) : string {
|
56 |
return PAYPAL_API_URL;
|
57 |
},
|
58 |
+
'api.partner_merchant_id' => static function () : string {
|
59 |
return '';
|
60 |
},
|
61 |
+
'api.merchant_email' => function () : string {
|
62 |
return '';
|
63 |
},
|
64 |
+
'api.merchant_id' => function () : string {
|
65 |
return '';
|
66 |
},
|
67 |
+
'api.key' => static function (): string {
|
68 |
return '';
|
69 |
},
|
70 |
+
'api.secret' => static function (): string {
|
71 |
return '';
|
72 |
},
|
73 |
+
'api.prefix' => static function (): string {
|
74 |
return 'WC-';
|
75 |
},
|
76 |
+
'api.bearer' => static function ( ContainerInterface $container ): Bearer {
|
77 |
$cache = new Cache( 'ppcp-paypal-bearer' );
|
78 |
$key = $container->get( 'api.key' );
|
79 |
$secret = $container->get( 'api.secret' );
|
89 |
$settings
|
90 |
);
|
91 |
},
|
92 |
+
'api.endpoint.partners' => static function ( ContainerInterface $container ) : PartnersEndpoint {
|
93 |
return new PartnersEndpoint(
|
94 |
$container->get( 'api.host' ),
|
95 |
$container->get( 'api.bearer' ),
|
99 |
$container->get( 'api.merchant_id' )
|
100 |
);
|
101 |
},
|
102 |
+
'api.factory.sellerstatus' => static function ( ContainerInterface $container ) : SellerStatusFactory {
|
103 |
return new SellerStatusFactory();
|
104 |
},
|
105 |
+
'api.endpoint.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenEndpoint {
|
106 |
return new PaymentTokenEndpoint(
|
107 |
$container->get( 'api.host' ),
|
108 |
$container->get( 'api.bearer' ),
|
111 |
$container->get( 'api.prefix' )
|
112 |
);
|
113 |
},
|
114 |
+
'api.endpoint.webhook' => static function ( ContainerInterface $container ) : WebhookEndpoint {
|
115 |
|
116 |
return new WebhookEndpoint(
|
117 |
$container->get( 'api.host' ),
|
121 |
$container->get( 'woocommerce.logger.woocommerce' )
|
122 |
);
|
123 |
},
|
124 |
+
'api.endpoint.partner-referrals' => static function ( ContainerInterface $container ) : PartnerReferrals {
|
125 |
|
126 |
return new PartnerReferrals(
|
127 |
$container->get( 'api.host' ),
|
130 |
$container->get( 'woocommerce.logger.woocommerce' )
|
131 |
);
|
132 |
},
|
133 |
+
'api.endpoint.identity-token' => static function ( ContainerInterface $container ) : IdentityToken {
|
|
|
134 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
135 |
$prefix = $container->get( 'api.prefix' );
|
136 |
+
$settings = $container->get( 'wcgateway.settings' );
|
137 |
return new IdentityToken(
|
138 |
$container->get( 'api.host' ),
|
139 |
$container->get( 'api.bearer' ),
|
140 |
$logger,
|
141 |
+
$prefix,
|
142 |
+
$settings
|
143 |
);
|
144 |
},
|
145 |
+
'api.endpoint.payments' => static function ( ContainerInterface $container ): PaymentsEndpoint {
|
146 |
$authorizations_factory = $container->get( 'api.factory.authorization' );
|
147 |
$capture_factory = $container->get( 'api.factory.capture' );
|
148 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
155 |
$logger
|
156 |
);
|
157 |
},
|
158 |
+
'api.endpoint.login-seller' => static function ( ContainerInterface $container ) : LoginSeller {
|
159 |
|
160 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
161 |
return new LoginSeller(
|
164 |
$logger
|
165 |
);
|
166 |
},
|
167 |
+
'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint {
|
168 |
$order_factory = $container->get( 'api.factory.order' );
|
169 |
$patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
|
170 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
191 |
$subscription_helper
|
192 |
);
|
193 |
},
|
194 |
+
'api.endpoint.billing-agreements' => static function ( ContainerInterface $container ): BillingAgreementsEndpoint {
|
195 |
+
return new BillingAgreementsEndpoint(
|
196 |
+
$container->get( 'api.host' ),
|
197 |
+
$container->get( 'api.bearer' ),
|
198 |
+
$container->get( 'woocommerce.logger.woocommerce' )
|
199 |
+
);
|
200 |
+
},
|
201 |
+
'api.repository.paypal-request-id' => static function( ContainerInterface $container ) : PayPalRequestIdRepository {
|
202 |
return new PayPalRequestIdRepository();
|
203 |
},
|
204 |
+
'api.repository.application-context' => static function( ContainerInterface $container ) : ApplicationContextRepository {
|
205 |
|
206 |
$settings = $container->get( 'wcgateway.settings' );
|
207 |
return new ApplicationContextRepository( $settings );
|
208 |
},
|
209 |
+
'api.repository.partner-referrals-data' => static function ( ContainerInterface $container ) : PartnerReferralsData {
|
210 |
|
211 |
$merchant_email = $container->get( 'api.merchant_email' );
|
212 |
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
213 |
return new PartnerReferralsData( $merchant_email, $dcc_applies );
|
214 |
},
|
215 |
+
'api.repository.cart' => static function ( ContainerInterface $container ): CartRepository {
|
216 |
$factory = $container->get( 'api.factory.purchase-unit' );
|
217 |
return new CartRepository( $factory );
|
218 |
},
|
219 |
+
'api.repository.payee' => static function ( ContainerInterface $container ): PayeeRepository {
|
220 |
$merchant_email = $container->get( 'api.merchant_email' );
|
221 |
$merchant_id = $container->get( 'api.merchant_id' );
|
222 |
return new PayeeRepository( $merchant_email, $merchant_id );
|
223 |
},
|
224 |
+
'api.factory.application-context' => static function ( ContainerInterface $container ) : ApplicationContextFactory {
|
225 |
return new ApplicationContextFactory();
|
226 |
},
|
227 |
+
'api.factory.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenFactory {
|
228 |
return new PaymentTokenFactory();
|
229 |
},
|
230 |
+
'api.factory.webhook' => static function ( ContainerInterface $container ): WebhookFactory {
|
231 |
return new WebhookFactory();
|
232 |
},
|
233 |
+
'api.factory.webhook-event' => static function ( ContainerInterface $container ): WebhookEventFactory {
|
234 |
return new WebhookEventFactory();
|
235 |
},
|
236 |
+
'api.factory.capture' => static function ( ContainerInterface $container ): CaptureFactory {
|
237 |
|
238 |
$amount_factory = $container->get( 'api.factory.amount' );
|
239 |
return new CaptureFactory( $amount_factory );
|
240 |
},
|
241 |
+
'api.factory.purchase-unit' => static function ( ContainerInterface $container ): PurchaseUnitFactory {
|
242 |
|
243 |
$amount_factory = $container->get( 'api.factory.amount' );
|
244 |
$payee_repository = $container->get( 'api.repository.payee' );
|
258 |
$prefix
|
259 |
);
|
260 |
},
|
261 |
+
'api.factory.patch-collection-factory' => static function ( ContainerInterface $container ): PatchCollectionFactory {
|
262 |
return new PatchCollectionFactory();
|
263 |
},
|
264 |
+
'api.factory.payee' => static function ( ContainerInterface $container ): PayeeFactory {
|
265 |
return new PayeeFactory();
|
266 |
},
|
267 |
+
'api.factory.item' => static function ( ContainerInterface $container ): ItemFactory {
|
268 |
+
return new ItemFactory(
|
269 |
+
$container->get( 'api.shop.currency' )
|
270 |
+
);
|
271 |
},
|
272 |
+
'api.factory.shipping' => static function ( ContainerInterface $container ): ShippingFactory {
|
273 |
$address_factory = $container->get( 'api.factory.address' );
|
274 |
return new ShippingFactory( $address_factory );
|
275 |
},
|
276 |
+
'api.factory.amount' => static function ( ContainerInterface $container ): AmountFactory {
|
277 |
$item_factory = $container->get( 'api.factory.item' );
|
278 |
+
return new AmountFactory(
|
279 |
+
$item_factory,
|
280 |
+
$container->get( 'api.shop.currency' )
|
281 |
+
);
|
282 |
},
|
283 |
+
'api.factory.payer' => static function ( ContainerInterface $container ): PayerFactory {
|
284 |
$address_factory = $container->get( 'api.factory.address' );
|
285 |
return new PayerFactory( $address_factory );
|
286 |
},
|
287 |
+
'api.factory.address' => static function ( ContainerInterface $container ): AddressFactory {
|
288 |
return new AddressFactory();
|
289 |
},
|
290 |
+
'api.factory.payment-source' => static function ( ContainerInterface $container ): PaymentSourceFactory {
|
291 |
return new PaymentSourceFactory();
|
292 |
},
|
293 |
+
'api.factory.order' => static function ( ContainerInterface $container ): OrderFactory {
|
294 |
$purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
|
295 |
$payer_factory = $container->get( 'api.factory.payer' );
|
296 |
$application_context_repository = $container->get( 'api.repository.application-context' );
|
304 |
$payment_source_factory
|
305 |
);
|
306 |
},
|
307 |
+
'api.factory.payments' => static function ( ContainerInterface $container ): PaymentsFactory {
|
308 |
$authorizations_factory = $container->get( 'api.factory.authorization' );
|
309 |
$capture_factory = $container->get( 'api.factory.capture' );
|
310 |
return new PaymentsFactory( $authorizations_factory, $capture_factory );
|
311 |
},
|
312 |
+
'api.factory.authorization' => static function ( ContainerInterface $container ): AuthorizationFactory {
|
313 |
return new AuthorizationFactory();
|
314 |
},
|
315 |
+
'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies {
|
316 |
+
return new DccApplies(
|
317 |
+
$container->get( 'api.dcc-supported-country-currency-matrix' ),
|
318 |
+
$container->get( 'api.dcc-supported-country-card-matrix' ),
|
319 |
+
$container->get( 'api.shop.currency' ),
|
320 |
+
$container->get( 'api.shop.country' )
|
321 |
+
);
|
322 |
+
},
|
323 |
+
|
324 |
+
'api.shop.currency' => static function ( ContainerInterface $container ) : string {
|
325 |
+
return get_woocommerce_currency();
|
326 |
+
},
|
327 |
+
'api.shop.country' => static function ( ContainerInterface $container ) : string {
|
328 |
+
$location = wc_get_base_location();
|
329 |
+
return $location['country'];
|
330 |
+
},
|
331 |
+
'api.shop.is-psd2-country' => static function ( ContainerInterface $container ) : bool {
|
332 |
+
return in_array(
|
333 |
+
$container->get( 'api.shop.country' ),
|
334 |
+
$container->get( 'api.psd2-countries' ),
|
335 |
+
true
|
336 |
+
);
|
337 |
+
},
|
338 |
+
'api.shop.is-currency-supported' => static function ( ContainerInterface $container ) : bool {
|
339 |
+
return in_array(
|
340 |
+
$container->get( 'api.shop.currency' ),
|
341 |
+
$container->get( 'api.supported-currencies' ),
|
342 |
+
true
|
343 |
+
);
|
344 |
+
},
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Currencies supported by PayPal.
|
348 |
+
*
|
349 |
+
* From https://developer.paypal.com/docs/reports/reference/paypal-supported-currencies/
|
350 |
+
*/
|
351 |
+
'api.supported-currencies' => static function ( ContainerInterface $container ) : array {
|
352 |
+
return array(
|
353 |
+
'AUD',
|
354 |
+
'BRL',
|
355 |
+
'CAD',
|
356 |
+
'CNY',
|
357 |
+
'CZK',
|
358 |
+
'DKK',
|
359 |
+
'EUR',
|
360 |
+
'HKD',
|
361 |
+
'HUF',
|
362 |
+
'ILS',
|
363 |
+
'JPY',
|
364 |
+
'MYR',
|
365 |
+
'MXN',
|
366 |
+
'TWD',
|
367 |
+
'NZD',
|
368 |
+
'NOK',
|
369 |
+
'PHP',
|
370 |
+
'PLN',
|
371 |
+
'GBP',
|
372 |
+
'RUB',
|
373 |
+
'SGD',
|
374 |
+
'SEK',
|
375 |
+
'CHF',
|
376 |
+
'THB',
|
377 |
+
'USD',
|
378 |
+
);
|
379 |
+
},
|
380 |
+
|
381 |
+
/**
|
382 |
+
* The matrix which countries and currency combinations can be used for DCC.
|
383 |
+
*/
|
384 |
+
'api.dcc-supported-country-currency-matrix' => static function ( ContainerInterface $container ) : array {
|
385 |
+
return array(
|
386 |
+
'AU' => array(
|
387 |
+
'AUD',
|
388 |
+
'CAD',
|
389 |
+
'CHF',
|
390 |
+
'CZK',
|
391 |
+
'DKK',
|
392 |
+
'EUR',
|
393 |
+
'GBP',
|
394 |
+
'HKD',
|
395 |
+
'HUF',
|
396 |
+
'JPY',
|
397 |
+
'NOK',
|
398 |
+
'NZD',
|
399 |
+
'PLN',
|
400 |
+
'SEK',
|
401 |
+
'SGD',
|
402 |
+
'USD',
|
403 |
+
),
|
404 |
+
'ES' => array(
|
405 |
+
'AUD',
|
406 |
+
'CAD',
|
407 |
+
'CHF',
|
408 |
+
'CZK',
|
409 |
+
'DKK',
|
410 |
+
'EUR',
|
411 |
+
'GBP',
|
412 |
+
'HKD',
|
413 |
+
'HUF',
|
414 |
+
'JPY',
|
415 |
+
'NOK',
|
416 |
+
'NZD',
|
417 |
+
'PLN',
|
418 |
+
'SEK',
|
419 |
+
'SGD',
|
420 |
+
'USD',
|
421 |
+
),
|
422 |
+
'FR' => array(
|
423 |
+
'AUD',
|
424 |
+
'CAD',
|
425 |
+
'CHF',
|
426 |
+
'CZK',
|
427 |
+
'DKK',
|
428 |
+
'EUR',
|
429 |
+
'GBP',
|
430 |
+
'HKD',
|
431 |
+
'HUF',
|
432 |
+
'JPY',
|
433 |
+
'NOK',
|
434 |
+
'NZD',
|
435 |
+
'PLN',
|
436 |
+
'SEK',
|
437 |
+
'SGD',
|
438 |
+
'USD',
|
439 |
+
),
|
440 |
+
'GB' => array(
|
441 |
+
'AUD',
|
442 |
+
'CAD',
|
443 |
+
'CHF',
|
444 |
+
'CZK',
|
445 |
+
'DKK',
|
446 |
+
'EUR',
|
447 |
+
'GBP',
|
448 |
+
'HKD',
|
449 |
+
'HUF',
|
450 |
+
'JPY',
|
451 |
+
'NOK',
|
452 |
+
'NZD',
|
453 |
+
'PLN',
|
454 |
+
'SEK',
|
455 |
+
'SGD',
|
456 |
+
'USD',
|
457 |
+
),
|
458 |
+
'IT' => array(
|
459 |
+
'AUD',
|
460 |
+
'CAD',
|
461 |
+
'CHF',
|
462 |
+
'CZK',
|
463 |
+
'DKK',
|
464 |
+
'EUR',
|
465 |
+
'GBP',
|
466 |
+
'HKD',
|
467 |
+
'HUF',
|
468 |
+
'JPY',
|
469 |
+
'NOK',
|
470 |
+
'NZD',
|
471 |
+
'PLN',
|
472 |
+
'SEK',
|
473 |
+
'SGD',
|
474 |
+
'USD',
|
475 |
+
),
|
476 |
+
'US' => array(
|
477 |
+
'AUD',
|
478 |
+
'CAD',
|
479 |
+
'EUR',
|
480 |
+
'GBP',
|
481 |
+
'JPY',
|
482 |
+
'USD',
|
483 |
+
),
|
484 |
+
'CA' => array(
|
485 |
+
'AUD',
|
486 |
+
'CAD',
|
487 |
+
'CHF',
|
488 |
+
'CZK',
|
489 |
+
'DKK',
|
490 |
+
'EUR',
|
491 |
+
'GBP',
|
492 |
+
'HKD',
|
493 |
+
'HUF',
|
494 |
+
'JPY',
|
495 |
+
'NOK',
|
496 |
+
'NZD',
|
497 |
+
'PLN',
|
498 |
+
'SEK',
|
499 |
+
'SGD',
|
500 |
+
'USD',
|
501 |
+
),
|
502 |
+
);
|
503 |
+
},
|
504 |
+
|
505 |
+
/**
|
506 |
+
* Which countries support which credit cards. Empty credit card arrays mean no restriction on currency.
|
507 |
+
*/
|
508 |
+
'api.dcc-supported-country-card-matrix' => static function ( ContainerInterface $container ) : array {
|
509 |
+
return array(
|
510 |
+
'AU' => array(
|
511 |
+
'mastercard' => array(),
|
512 |
+
'visa' => array(),
|
513 |
+
),
|
514 |
+
'ES' => array(
|
515 |
+
'mastercard' => array(),
|
516 |
+
'visa' => array(),
|
517 |
+
'amex' => array( 'EUR' ),
|
518 |
+
),
|
519 |
+
'FR' => array(
|
520 |
+
'mastercard' => array(),
|
521 |
+
'visa' => array(),
|
522 |
+
'amex' => array( 'EUR' ),
|
523 |
+
),
|
524 |
+
'GB' => array(
|
525 |
+
'mastercard' => array(),
|
526 |
+
'visa' => array(),
|
527 |
+
'amex' => array( 'GBP', 'USD' ),
|
528 |
+
),
|
529 |
+
'IT' => array(
|
530 |
+
'mastercard' => array(),
|
531 |
+
'visa' => array(),
|
532 |
+
'amex' => array( 'EUR' ),
|
533 |
+
),
|
534 |
+
'US' => array(
|
535 |
+
'mastercard' => array(),
|
536 |
+
'visa' => array(),
|
537 |
+
'amex' => array( 'USD' ),
|
538 |
+
'discover' => array( 'USD' ),
|
539 |
+
),
|
540 |
+
'CA' => array(
|
541 |
+
'mastercard' => array(),
|
542 |
+
'visa' => array(),
|
543 |
+
'amex' => array( 'CAD' ),
|
544 |
+
'jcb' => array( 'CAD' ),
|
545 |
+
),
|
546 |
+
);
|
547 |
+
},
|
548 |
+
|
549 |
+
'api.psd2-countries' => static function ( ContainerInterface $container ) : array {
|
550 |
+
return array(
|
551 |
+
'AT',
|
552 |
+
'BE',
|
553 |
+
'BG',
|
554 |
+
'CY',
|
555 |
+
'CZ',
|
556 |
+
'DK',
|
557 |
+
'EE',
|
558 |
+
'FI',
|
559 |
+
'FR',
|
560 |
+
'DE',
|
561 |
+
'GB',
|
562 |
+
'GR',
|
563 |
+
'HU',
|
564 |
+
'IE',
|
565 |
+
'IT',
|
566 |
+
'LV',
|
567 |
+
'LT',
|
568 |
+
'LU',
|
569 |
+
'MT',
|
570 |
+
'NL',
|
571 |
+
'NO',
|
572 |
+
'PL',
|
573 |
+
'PT',
|
574 |
+
'RO',
|
575 |
+
'SK',
|
576 |
+
'SI',
|
577 |
+
'ES',
|
578 |
+
'SE',
|
579 |
+
);
|
580 |
},
|
581 |
);
|
modules/ppcp-api-client/src/Endpoint/BillingAgreementsEndpoint.php
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The billing agreements endpoint.
|
4 |
+
*
|
5 |
+
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
|
6 |
+
*/
|
7 |
+
|
8 |
+
declare(strict_types=1);
|
9 |
+
|
10 |
+
namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
|
11 |
+
|
12 |
+
use stdClass;
|
13 |
+
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
14 |
+
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
15 |
+
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
16 |
+
use Psr\Log\LoggerInterface;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Class BillingAgreementsEndpoint
|
20 |
+
*/
|
21 |
+
class BillingAgreementsEndpoint {
|
22 |
+
use RequestTrait;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* The host.
|
26 |
+
*
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
private $host;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* The bearer.
|
33 |
+
*
|
34 |
+
* @var Bearer
|
35 |
+
*/
|
36 |
+
private $bearer;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* The logger.
|
40 |
+
*
|
41 |
+
* @var LoggerInterface
|
42 |
+
*/
|
43 |
+
private $logger;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* BillingAgreementsEndpoint constructor.
|
47 |
+
*
|
48 |
+
* @param string $host The host.
|
49 |
+
* @param Bearer $bearer The bearer.
|
50 |
+
* @param LoggerInterface $logger The logger.
|
51 |
+
*/
|
52 |
+
public function __construct(
|
53 |
+
string $host,
|
54 |
+
Bearer $bearer,
|
55 |
+
LoggerInterface $logger
|
56 |
+
) {
|
57 |
+
$this->host = $host;
|
58 |
+
$this->bearer = $bearer;
|
59 |
+
$this->logger = $logger;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Creates a billing agreement token.
|
64 |
+
*
|
65 |
+
* @param string $description The description.
|
66 |
+
* @param string $return_url The return URL.
|
67 |
+
* @param string $cancel_url The cancel URL.
|
68 |
+
*
|
69 |
+
* @throws RuntimeException If the request fails.
|
70 |
+
* @throws PayPalApiException If the request fails.
|
71 |
+
*/
|
72 |
+
public function create_token( string $description, string $return_url, string $cancel_url ): stdClass {
|
73 |
+
$data = array(
|
74 |
+
'description' => $description,
|
75 |
+
'payer' => array(
|
76 |
+
'payment_method' => 'PAYPAL',
|
77 |
+
),
|
78 |
+
'plan' => array(
|
79 |
+
'type' => 'MERCHANT_INITIATED_BILLING',
|
80 |
+
'merchant_preferences' => array(
|
81 |
+
'return_url' => $return_url,
|
82 |
+
'cancel_url' => $cancel_url,
|
83 |
+
'skip_shipping_address' => true,
|
84 |
+
),
|
85 |
+
),
|
86 |
+
);
|
87 |
+
|
88 |
+
$bearer = $this->bearer->bearer();
|
89 |
+
$url = trailingslashit( $this->host ) . 'v1/billing-agreements/agreement-tokens';
|
90 |
+
$args = array(
|
91 |
+
'method' => 'POST',
|
92 |
+
'headers' => array(
|
93 |
+
'Authorization' => 'Bearer ' . $bearer->token(),
|
94 |
+
'Content-Type' => 'application/json',
|
95 |
+
),
|
96 |
+
'body' => wp_json_encode( $data ),
|
97 |
+
);
|
98 |
+
$response = $this->request( $url, $args );
|
99 |
+
|
100 |
+
if ( is_wp_error( $response ) || ! is_array( $response ) ) {
|
101 |
+
throw new RuntimeException( 'Not able to create a billing agreement token.' );
|
102 |
+
}
|
103 |
+
|
104 |
+
$json = json_decode( $response['body'] );
|
105 |
+
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
106 |
+
if ( 201 !== $status_code ) {
|
107 |
+
throw new PayPalApiException(
|
108 |
+
$json,
|
109 |
+
$status_code
|
110 |
+
);
|
111 |
+
}
|
112 |
+
|
113 |
+
return $json;
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Checks if reference transactions are enabled in account.
|
118 |
+
*
|
119 |
+
* @throws RuntimeException If the request fails (no auth, no connection, etc.).
|
120 |
+
*/
|
121 |
+
public function reference_transaction_enabled(): bool {
|
122 |
+
try {
|
123 |
+
$this->create_token(
|
124 |
+
'Checking if reference transactions are enabled',
|
125 |
+
'https://example.com/return',
|
126 |
+
'https://example.com/cancel'
|
127 |
+
);
|
128 |
+
|
129 |
+
return true;
|
130 |
+
} catch ( PayPalApiException $exception ) {
|
131 |
+
return false;
|
132 |
+
}
|
133 |
+
}
|
134 |
+
}
|
modules/ppcp-api-client/src/Endpoint/IdentityToken.php
CHANGED
@@ -14,6 +14,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Token;
|
|
14 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
16 |
use Psr\Log\LoggerInterface;
|
|
|
17 |
|
18 |
/**
|
19 |
* Class IdentityToken
|
@@ -50,6 +51,13 @@ class IdentityToken {
|
|
50 |
*/
|
51 |
private $prefix;
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
/**
|
54 |
* IdentityToken constructor.
|
55 |
*
|
@@ -57,12 +65,14 @@ class IdentityToken {
|
|
57 |
* @param Bearer $bearer The bearer.
|
58 |
* @param LoggerInterface $logger The logger.
|
59 |
* @param string $prefix The prefix.
|
|
|
60 |
*/
|
61 |
-
public function __construct( string $host, Bearer $bearer, LoggerInterface $logger, string $prefix ) {
|
62 |
-
$this->host
|
63 |
-
$this->bearer
|
64 |
-
$this->logger
|
65 |
-
$this->prefix
|
|
|
66 |
}
|
67 |
|
68 |
/**
|
@@ -84,7 +94,11 @@ class IdentityToken {
|
|
84 |
'Content-Type' => 'application/json',
|
85 |
),
|
86 |
);
|
87 |
-
if (
|
|
|
|
|
|
|
|
|
88 |
$args['body'] = wp_json_encode( array( 'customer_id' => $this->prefix . $customer_id ) );
|
89 |
}
|
90 |
|
14 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
16 |
use Psr\Log\LoggerInterface;
|
17 |
+
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
18 |
|
19 |
/**
|
20 |
* Class IdentityToken
|
51 |
*/
|
52 |
private $prefix;
|
53 |
|
54 |
+
/**
|
55 |
+
* The settings
|
56 |
+
*
|
57 |
+
* @var Settings
|
58 |
+
*/
|
59 |
+
private $settings;
|
60 |
+
|
61 |
/**
|
62 |
* IdentityToken constructor.
|
63 |
*
|
65 |
* @param Bearer $bearer The bearer.
|
66 |
* @param LoggerInterface $logger The logger.
|
67 |
* @param string $prefix The prefix.
|
68 |
+
* @param Settings $settings The settings.
|
69 |
*/
|
70 |
+
public function __construct( string $host, Bearer $bearer, LoggerInterface $logger, string $prefix, Settings $settings ) {
|
71 |
+
$this->host = $host;
|
72 |
+
$this->bearer = $bearer;
|
73 |
+
$this->logger = $logger;
|
74 |
+
$this->prefix = $prefix;
|
75 |
+
$this->settings = $settings;
|
76 |
}
|
77 |
|
78 |
/**
|
94 |
'Content-Type' => 'application/json',
|
95 |
),
|
96 |
);
|
97 |
+
if (
|
98 |
+
$customer_id
|
99 |
+
&& ( $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) )
|
100 |
+
&& defined( 'PPCP_FLAG_SUBSCRIPTION' ) && PPCP_FLAG_SUBSCRIPTION
|
101 |
+
) {
|
102 |
$args['body'] = wp_json_encode( array( 'customer_id' => $this->prefix . $customer_id ) );
|
103 |
}
|
104 |
|
modules/ppcp-api-client/src/Factory/AmountFactory.php
CHANGED
@@ -28,13 +28,22 @@ class AmountFactory {
|
|
28 |
*/
|
29 |
private $item_factory;
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
/**
|
32 |
* AmountFactory constructor.
|
33 |
*
|
34 |
* @param ItemFactory $item_factory The Item factory.
|
|
|
35 |
*/
|
36 |
-
public function __construct( ItemFactory $item_factory ) {
|
37 |
$this->item_factory = $item_factory;
|
|
|
38 |
}
|
39 |
|
40 |
/**
|
@@ -45,8 +54,7 @@ class AmountFactory {
|
|
45 |
* @return Amount
|
46 |
*/
|
47 |
public function from_wc_cart( \WC_Cart $cart ): Amount {
|
48 |
-
$
|
49 |
-
$total = new Money( (float) $cart->get_total( 'numeric' ), $currency );
|
50 |
|
51 |
$total_fees_amount = 0;
|
52 |
$fees = WC()->session->get( 'ppcp_fees' );
|
@@ -57,22 +65,22 @@ class AmountFactory {
|
|
57 |
}
|
58 |
|
59 |
$item_total = $cart->get_cart_contents_total() + $cart->get_discount_total() + $total_fees_amount;
|
60 |
-
$item_total = new Money( (float) $item_total, $currency );
|
61 |
$shipping = new Money(
|
62 |
(float) $cart->get_shipping_total() + $cart->get_shipping_tax(),
|
63 |
-
$currency
|
64 |
);
|
65 |
|
66 |
$taxes = new Money(
|
67 |
-
|
68 |
-
$currency
|
69 |
);
|
70 |
|
71 |
$discount = null;
|
72 |
if ( $cart->get_discount_total() ) {
|
73 |
$discount = new Money(
|
74 |
(float) $cart->get_discount_total() + $cart->get_discount_tax(),
|
75 |
-
$currency
|
76 |
);
|
77 |
}
|
78 |
|
28 |
*/
|
29 |
private $item_factory;
|
30 |
|
31 |
+
/**
|
32 |
+
* 3-letter currency code of the shop.
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
private $currency;
|
37 |
+
|
38 |
/**
|
39 |
* AmountFactory constructor.
|
40 |
*
|
41 |
* @param ItemFactory $item_factory The Item factory.
|
42 |
+
* @param string $currency 3-letter currency code of the shop.
|
43 |
*/
|
44 |
+
public function __construct( ItemFactory $item_factory, string $currency ) {
|
45 |
$this->item_factory = $item_factory;
|
46 |
+
$this->currency = $currency;
|
47 |
}
|
48 |
|
49 |
/**
|
54 |
* @return Amount
|
55 |
*/
|
56 |
public function from_wc_cart( \WC_Cart $cart ): Amount {
|
57 |
+
$total = new Money( (float) $cart->get_total( 'numeric' ), $this->currency );
|
|
|
58 |
|
59 |
$total_fees_amount = 0;
|
60 |
$fees = WC()->session->get( 'ppcp_fees' );
|
65 |
}
|
66 |
|
67 |
$item_total = $cart->get_cart_contents_total() + $cart->get_discount_total() + $total_fees_amount;
|
68 |
+
$item_total = new Money( (float) $item_total, $this->currency );
|
69 |
$shipping = new Money(
|
70 |
(float) $cart->get_shipping_total() + $cart->get_shipping_tax(),
|
71 |
+
$this->currency
|
72 |
);
|
73 |
|
74 |
$taxes = new Money(
|
75 |
+
$cart->get_subtotal_tax(),
|
76 |
+
$this->currency
|
77 |
);
|
78 |
|
79 |
$discount = null;
|
80 |
if ( $cart->get_discount_total() ) {
|
81 |
$discount = new Money(
|
82 |
(float) $cart->get_discount_total() + $cart->get_discount_tax(),
|
83 |
+
$this->currency
|
84 |
);
|
85 |
}
|
86 |
|
modules/ppcp-api-client/src/Factory/ItemFactory.php
CHANGED
@@ -17,7 +17,21 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
|
17 |
* Class ItemFactory
|
18 |
*/
|
19 |
class ItemFactory {
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
/**
|
23 |
* Creates items based off a WooCommerce cart.
|
@@ -27,9 +41,8 @@ class ItemFactory {
|
|
27 |
* @return Item[]
|
28 |
*/
|
29 |
public function from_wc_cart( \WC_Cart $cart ): array {
|
30 |
-
$
|
31 |
-
|
32 |
-
static function ( array $item ) use ( $currency ): Item {
|
33 |
$product = $item['data'];
|
34 |
|
35 |
/**
|
@@ -43,10 +56,10 @@ class ItemFactory {
|
|
43 |
$price_without_tax = (float) wc_get_price_excluding_tax( $product );
|
44 |
$price_without_tax_rounded = round( $price_without_tax, 2 );
|
45 |
$tax = round( $price - $price_without_tax_rounded, 2 );
|
46 |
-
$tax = new Money( $tax, $currency );
|
47 |
return new Item(
|
48 |
mb_substr( $product->get_name(), 0, 127 ),
|
49 |
-
new Money( $price_without_tax_rounded, $currency ),
|
50 |
$quantity,
|
51 |
mb_substr( wp_strip_all_tags( $product->get_description() ), 0, 127 ),
|
52 |
$tax,
|
@@ -61,13 +74,13 @@ class ItemFactory {
|
|
61 |
$fees_from_session = WC()->session->get( 'ppcp_fees' );
|
62 |
if ( $fees_from_session ) {
|
63 |
$fees = array_map(
|
64 |
-
|
65 |
return new Item(
|
66 |
$fee->name,
|
67 |
-
new Money( (float) $fee->amount, $currency ),
|
68 |
1,
|
69 |
'',
|
70 |
-
new Money( (float) $fee->tax, $currency )
|
71 |
);
|
72 |
},
|
73 |
$fees_from_session
|
17 |
* Class ItemFactory
|
18 |
*/
|
19 |
class ItemFactory {
|
20 |
+
/**
|
21 |
+
* 3-letter currency code of the shop.
|
22 |
+
*
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
private $currency;
|
26 |
|
27 |
+
/**
|
28 |
+
* ItemFactory constructor.
|
29 |
+
*
|
30 |
+
* @param string $currency 3-letter currency code of the shop.
|
31 |
+
*/
|
32 |
+
public function __construct( string $currency ) {
|
33 |
+
$this->currency = $currency;
|
34 |
+
}
|
35 |
|
36 |
/**
|
37 |
* Creates items based off a WooCommerce cart.
|
41 |
* @return Item[]
|
42 |
*/
|
43 |
public function from_wc_cart( \WC_Cart $cart ): array {
|
44 |
+
$items = array_map(
|
45 |
+
function ( array $item ): Item {
|
|
|
46 |
$product = $item['data'];
|
47 |
|
48 |
/**
|
56 |
$price_without_tax = (float) wc_get_price_excluding_tax( $product );
|
57 |
$price_without_tax_rounded = round( $price_without_tax, 2 );
|
58 |
$tax = round( $price - $price_without_tax_rounded, 2 );
|
59 |
+
$tax = new Money( $tax, $this->currency );
|
60 |
return new Item(
|
61 |
mb_substr( $product->get_name(), 0, 127 ),
|
62 |
+
new Money( $price_without_tax_rounded, $this->currency ),
|
63 |
$quantity,
|
64 |
mb_substr( wp_strip_all_tags( $product->get_description() ), 0, 127 ),
|
65 |
$tax,
|
74 |
$fees_from_session = WC()->session->get( 'ppcp_fees' );
|
75 |
if ( $fees_from_session ) {
|
76 |
$fees = array_map(
|
77 |
+
function ( \stdClass $fee ): Item {
|
78 |
return new Item(
|
79 |
$fee->name,
|
80 |
+
new Money( (float) $fee->amount, $this->currency ),
|
81 |
1,
|
82 |
'',
|
83 |
+
new Money( (float) $fee->tax, $this->currency )
|
84 |
);
|
85 |
},
|
86 |
$fees_from_session
|
modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php
CHANGED
@@ -119,10 +119,9 @@ class PurchaseUnitFactory {
|
|
119 |
$reference_id = 'default';
|
120 |
$description = '';
|
121 |
$payee = $this->payee_repository->payee();
|
122 |
-
$
|
123 |
-
$
|
124 |
$retry = $order->get_meta( 'ppcp-retry' ) ? '-' . $order->get_meta( 'ppcp-retry' ) : '';
|
125 |
-
$invoice_id = $this->prefix . $wc_order_id . $retry;
|
126 |
$soft_descriptor = '';
|
127 |
|
128 |
$purchase_unit = new PurchaseUnit(
|
119 |
$reference_id = 'default';
|
120 |
$description = '';
|
121 |
$payee = $this->payee_repository->payee();
|
122 |
+
$custom_id = (string) $order->get_id();
|
123 |
+
$invoice_id = $this->prefix . $order->get_order_number();
|
124 |
$retry = $order->get_meta( 'ppcp-retry' ) ? '-' . $order->get_meta( 'ppcp-retry' ) : '';
|
|
|
125 |
$soft_descriptor = '';
|
126 |
|
127 |
$purchase_unit = new PurchaseUnit(
|
modules/ppcp-api-client/src/Helper/DccApplies.php
CHANGED
@@ -19,169 +19,50 @@ class DccApplies {
|
|
19 |
*
|
20 |
* @var array
|
21 |
*/
|
22 |
-
private $allowed_country_currency_matrix
|
23 |
-
'AU' => array(
|
24 |
-
'AUD',
|
25 |
-
'CAD',
|
26 |
-
'CHF',
|
27 |
-
'CZK',
|
28 |
-
'DKK',
|
29 |
-
'EUR',
|
30 |
-
'GBP',
|
31 |
-
'HKD',
|
32 |
-
'HUF',
|
33 |
-
'JPY',
|
34 |
-
'NOK',
|
35 |
-
'NZD',
|
36 |
-
'PLN',
|
37 |
-
'SEK',
|
38 |
-
'SGD',
|
39 |
-
'USD',
|
40 |
-
),
|
41 |
-
'ES' => array(
|
42 |
-
'AUD',
|
43 |
-
'CAD',
|
44 |
-
'CHF',
|
45 |
-
'CZK',
|
46 |
-
'DKK',
|
47 |
-
'EUR',
|
48 |
-
'GBP',
|
49 |
-
'HKD',
|
50 |
-
'HUF',
|
51 |
-
'JPY',
|
52 |
-
'NOK',
|
53 |
-
'NZD',
|
54 |
-
'PLN',
|
55 |
-
'SEK',
|
56 |
-
'SGD',
|
57 |
-
'USD',
|
58 |
-
),
|
59 |
-
'FR' => array(
|
60 |
-
'AUD',
|
61 |
-
'CAD',
|
62 |
-
'CHF',
|
63 |
-
'CZK',
|
64 |
-
'DKK',
|
65 |
-
'EUR',
|
66 |
-
'GBP',
|
67 |
-
'HKD',
|
68 |
-
'HUF',
|
69 |
-
'JPY',
|
70 |
-
'NOK',
|
71 |
-
'NZD',
|
72 |
-
'PLN',
|
73 |
-
'SEK',
|
74 |
-
'SGD',
|
75 |
-
'USD',
|
76 |
-
),
|
77 |
-
'GB' => array(
|
78 |
-
'AUD',
|
79 |
-
'CAD',
|
80 |
-
'CHF',
|
81 |
-
'CZK',
|
82 |
-
'DKK',
|
83 |
-
'EUR',
|
84 |
-
'GBP',
|
85 |
-
'HKD',
|
86 |
-
'HUF',
|
87 |
-
'JPY',
|
88 |
-
'NOK',
|
89 |
-
'NZD',
|
90 |
-
'PLN',
|
91 |
-
'SEK',
|
92 |
-
'SGD',
|
93 |
-
'USD',
|
94 |
-
),
|
95 |
-
'IT' => array(
|
96 |
-
'AUD',
|
97 |
-
'CAD',
|
98 |
-
'CHF',
|
99 |
-
'CZK',
|
100 |
-
'DKK',
|
101 |
-
'EUR',
|
102 |
-
'GBP',
|
103 |
-
'HKD',
|
104 |
-
'HUF',
|
105 |
-
'JPY',
|
106 |
-
'NOK',
|
107 |
-
'NZD',
|
108 |
-
'PLN',
|
109 |
-
'SEK',
|
110 |
-
'SGD',
|
111 |
-
'USD',
|
112 |
-
),
|
113 |
-
'US' => array(
|
114 |
-
'AUD',
|
115 |
-
'CAD',
|
116 |
-
'EUR',
|
117 |
-
'GBP',
|
118 |
-
'JPY',
|
119 |
-
'USD',
|
120 |
-
),
|
121 |
-
'CA' => array(
|
122 |
-
'AUD',
|
123 |
-
'CAD',
|
124 |
-
'CHF',
|
125 |
-
'CZK',
|
126 |
-
'DKK',
|
127 |
-
'EUR',
|
128 |
-
'GBP',
|
129 |
-
'HKD',
|
130 |
-
'HUF',
|
131 |
-
'JPY',
|
132 |
-
'NOK',
|
133 |
-
'NZD',
|
134 |
-
'PLN',
|
135 |
-
'SEK',
|
136 |
-
'SGD',
|
137 |
-
'USD',
|
138 |
-
),
|
139 |
-
);
|
140 |
|
141 |
/**
|
142 |
* Which countries support which credit cards. Empty credit card arrays mean no restriction on
|
143 |
-
* currency.
|
144 |
*
|
145 |
* @var array
|
146 |
*/
|
147 |
-
private $country_card_matrix
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
),
|
184 |
-
);
|
185 |
|
186 |
/**
|
187 |
* Returns whether DCC can be used in the current country and the current currency used.
|
@@ -189,12 +70,10 @@ class DccApplies {
|
|
189 |
* @return bool
|
190 |
*/
|
191 |
public function for_country_currency(): bool {
|
192 |
-
$country
|
193 |
-
$currency = get_woocommerce_currency();
|
194 |
-
if ( ! in_array( $country, array_keys( $this->allowed_country_currency_matrix ), true ) ) {
|
195 |
return false;
|
196 |
}
|
197 |
-
$applies = in_array( $currency, $this->allowed_country_currency_matrix[ $country ], true );
|
198 |
return $applies;
|
199 |
}
|
200 |
|
@@ -204,13 +83,12 @@ class DccApplies {
|
|
204 |
* @return array
|
205 |
*/
|
206 |
public function valid_cards() : array {
|
207 |
-
$
|
208 |
-
$
|
209 |
-
if ( ! isset( $this->country_card_matrix[ $country ] ) ) {
|
210 |
return $cards;
|
211 |
}
|
212 |
|
213 |
-
$supported_currencies = $this->country_card_matrix[ $country ];
|
214 |
foreach ( $supported_currencies as $card => $currencies ) {
|
215 |
if ( $this->can_process_card( $card ) ) {
|
216 |
$cards[] = $card;
|
@@ -233,11 +111,10 @@ class DccApplies {
|
|
233 |
* @return bool
|
234 |
*/
|
235 |
public function can_process_card( string $card ) : bool {
|
236 |
-
|
237 |
-
if ( ! isset( $this->country_card_matrix[ $country ] ) ) {
|
238 |
return false;
|
239 |
}
|
240 |
-
if ( ! isset( $this->country_card_matrix[ $country ][ $card ] ) ) {
|
241 |
return false;
|
242 |
}
|
243 |
|
@@ -245,19 +122,7 @@ class DccApplies {
|
|
245 |
* If the supported currencies array is empty, there are no
|
246 |
* restrictions, which currencies are supported by a card.
|
247 |
*/
|
248 |
-
$supported_currencies = $this->country_card_matrix[ $country ][ $card ];
|
249 |
-
$currency
|
250 |
-
return empty( $supported_currencies ) || in_array( $currency, $supported_currencies, true );
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* Returns the country code of the shop.
|
255 |
-
*
|
256 |
-
* @return string
|
257 |
-
*/
|
258 |
-
private function country() : string {
|
259 |
-
$region = wc_get_base_location();
|
260 |
-
$country = $region['country'];
|
261 |
-
return $country;
|
262 |
}
|
263 |
}
|
19 |
*
|
20 |
* @var array
|
21 |
*/
|
22 |
+
private $allowed_country_currency_matrix;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
/**
|
25 |
* Which countries support which credit cards. Empty credit card arrays mean no restriction on
|
26 |
+
* currency.
|
27 |
*
|
28 |
* @var array
|
29 |
*/
|
30 |
+
private $country_card_matrix;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* 3-letter currency code of the shop.
|
34 |
+
*
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
private $currency;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* 2-letter country code of the shop.
|
41 |
+
*
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
private $country;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* DccApplies constructor.
|
48 |
+
*
|
49 |
+
* @param array $allowed_country_currency_matrix The matrix which countries and currency combinations can be used for DCC.
|
50 |
+
* @param array $country_card_matrix Which countries support which credit cards. Empty credit card arrays mean no restriction on
|
51 |
+
* currency.
|
52 |
+
* @param string $currency 3-letter currency code of the shop.
|
53 |
+
* @param string $country 2-letter country code of the shop.
|
54 |
+
*/
|
55 |
+
public function __construct(
|
56 |
+
array $allowed_country_currency_matrix,
|
57 |
+
array $country_card_matrix,
|
58 |
+
string $currency,
|
59 |
+
string $country
|
60 |
+
) {
|
61 |
+
$this->allowed_country_currency_matrix = $allowed_country_currency_matrix;
|
62 |
+
$this->country_card_matrix = $country_card_matrix;
|
63 |
+
$this->currency = $currency;
|
64 |
+
$this->country = $country;
|
65 |
+
}
|
|
|
|
|
66 |
|
67 |
/**
|
68 |
* Returns whether DCC can be used in the current country and the current currency used.
|
70 |
* @return bool
|
71 |
*/
|
72 |
public function for_country_currency(): bool {
|
73 |
+
if ( ! in_array( $this->country, array_keys( $this->allowed_country_currency_matrix ), true ) ) {
|
|
|
|
|
74 |
return false;
|
75 |
}
|
76 |
+
$applies = in_array( $this->currency, $this->allowed_country_currency_matrix[ $this->country ], true );
|
77 |
return $applies;
|
78 |
}
|
79 |
|
83 |
* @return array
|
84 |
*/
|
85 |
public function valid_cards() : array {
|
86 |
+
$cards = array();
|
87 |
+
if ( ! isset( $this->country_card_matrix[ $this->country ] ) ) {
|
|
|
88 |
return $cards;
|
89 |
}
|
90 |
|
91 |
+
$supported_currencies = $this->country_card_matrix[ $this->country ];
|
92 |
foreach ( $supported_currencies as $card => $currencies ) {
|
93 |
if ( $this->can_process_card( $card ) ) {
|
94 |
$cards[] = $card;
|
111 |
* @return bool
|
112 |
*/
|
113 |
public function can_process_card( string $card ) : bool {
|
114 |
+
if ( ! isset( $this->country_card_matrix[ $this->country ] ) ) {
|
|
|
115 |
return false;
|
116 |
}
|
117 |
+
if ( ! isset( $this->country_card_matrix[ $this->country ][ $card ] ) ) {
|
118 |
return false;
|
119 |
}
|
120 |
|
122 |
* If the supported currencies array is empty, there are no
|
123 |
* restrictions, which currencies are supported by a card.
|
124 |
*/
|
125 |
+
$supported_currencies = $this->country_card_matrix[ $this->country ][ $card ];
|
126 |
+
return empty( $supported_currencies ) || in_array( $this->currency, $supported_currencies, true );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
}
|
128 |
}
|
modules/ppcp-button/assets/css/hosted-fields.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#payment ul.payment_methods li img.ppcp-card-icon{padding:0 0 3px 3px;max-height:25px;display:inline-block}.payments-sdk-contingency-handler{z-index:1000 !important}.ppcp-credit-card-gateway-form-field-disabled{opacity:.5 !important}
|
1 |
+
#payment ul.payment_methods li img.ppcp-card-icon{padding:0 0 3px 3px;max-height:25px;display:inline-block}.payments-sdk-contingency-handler{z-index:1000 !important}.ppcp-credit-card-gateway-form-field-disabled{opacity:.5 !important}.ppcp-dcc-order-button{float:right}
|
modules/ppcp-button/assets/js/button.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
(()=>{"use strict";var __webpack_modules__={94:()=>{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.wrapper.classList.contains('woocommerce-error')) {\n return;\n }\n\n this.wrapper.classList.remove('woocommerce-error');\n this.wrapper.innerText = '';\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 })\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\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/ActionHandler/CartActionHandler.js\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 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\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 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 init() {\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 if (document.querySelector('form.cart') === null) {\n return false;\n }\n\n return true;\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 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 })\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\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 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.message(data.data.message, true);\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/ContextBootstrap/CheckoutBootstap.js\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 }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n jQuery(document).on('hosted_fields_loaded', () => {\n jQuery('#saved-credit-card').on('change', () => {\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n });\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\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 }\n\n switchBetweenPayPalandOrderButton() {\n jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n\n displayPlaceOrderButtonForSavedCreditCards() {\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n return;\n }\n\n if (jQuery('#saved-credit-card').length && jQuery('#saved-credit-card').val() !== '') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n this.disableCreditCardFields();\n } else {\n jQuery('#place_order').hide();\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n this.enableCreditCardFields();\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/ContextBootstrap/PayNowBootstrap.js\n\n\n\nclass PayNowBootstrap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n });\n this.switchBetweenPayPalandOrderButton();\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 }\n\n switchBetweenPayPalandOrderButton() {\n const urlParams = new URLSearchParams(window.location.search);\n\n if (urlParams.has('change_payment_method')) {\n return;\n }\n\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\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) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\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 }).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\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 this.formSubmissionSubscribed = false;\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 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\n if (!this.formSubmissionSubscribed) {\n document.querySelector(wrapper + ' button').addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n this.formSubmissionSubscribed = 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.save_card ? 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 this.currentHostedFieldsInstance.submit(hostedFieldsData).then(payload => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n }).catch(err => {\n console.error(err);\n this.spinner.unblock();\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() {\n this.target = 'form.woocommerce-checkout';\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/button.js\n\n\n\n\n\n\n\n\n\n\n\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 renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway);\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 const script = document.createElement('script');\n script.addEventListener('load', event => {\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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LENBQUN1USxnQkFBVCxDQUNJLGtCQURKLEVBRUksTUFBTTtBQUNGLE1BQUksQ0FBQyxPQUFRek0scUJBQWIsRUFBcUM7QUFDakN3QixJQUFBQSxPQUFPLENBQUNDLEtBQVIsQ0FBYyx3Q0FBZDtBQUNBO0FBQ0g7O0FBQ0QsUUFBTWdOLE1BQU0sR0FBR3ZTLFFBQVEsQ0FBQ3dCLGFBQVQsQ0FBdUIsUUFBdkIsQ0FBZjtBQUVBK1EsRUFBQUEsTUFBTSxDQUFDaEMsZ0JBQVAsQ0FBd0IsTUFBeEIsRUFBaUNWLEtBQUQsSUFBVztBQUN2Q3lELElBQUFBLFNBQVM7QUFDWixHQUZEO0FBR0FmLEVBQUFBLE1BQU0sQ0FBQzlRLFlBQVAsQ0FBb0IsS0FBcEIsRUFBMkJxQyxxQkFBcUIsQ0FBQ3NDLE1BQXRCLENBQTZCMk4sR0FBeEQ7QUFDQTVHLEVBQUFBLE1BQU0sQ0FBQzZHLE9BQVAsQ0FBZWxRLHFCQUFxQixDQUFDbVEsaUJBQXJDLEVBQXdEMUwsT0FBeEQsQ0FDSzJMLFFBQUQsSUFBYztBQUNWM0IsSUFBQUEsTUFBTSxDQUFDOVEsWUFBUCxDQUFvQnlTLFFBQVEsQ0FBQyxDQUFELENBQTVCLEVBQWlDQSxRQUFRLENBQUMsQ0FBRCxDQUF6QztBQUNILEdBSEw7O0FBTUEsTUFBSXBRLHFCQUFxQixDQUFDcVEsY0FBdEIsQ0FBcUNDLGFBQXpDLEVBQXdEO0FBQ3BEOUIsSUFBQUEsNEJBQTRCLENBQUNDLE1BQUQsRUFBU3pPLHFCQUFxQixDQUFDcVEsY0FBL0IsQ0FBNUI7QUFDQTtBQUNIOztBQUVEblUsRUFBQUEsUUFBUSxDQUFDNEMsSUFBVCxDQUFjNkgsTUFBZCxDQUFxQjhILE1BQXJCO0FBQ0gsQ0F6QkwiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRXJyb3JIYW5kbGVyLmpzP2U2NWEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanM/YzQ1NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1BheWVyRGF0YS5qcz8yYWYxIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyLmpzPzgyY2YiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcC5qcz9kNTUyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvVXBkYXRlQ2FydC5qcz9lNDIyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyLmpzP2UxOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0VudGl0eS9Qcm9kdWN0LmpzPzlmZmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIuanM/ZDliNyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAuanM/N2MxOSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAuanM/NWU5NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanM/OTMwNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXIuanM/ODUxNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwLmpzP2M4NTUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwLmpzP2Q5ZjUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyLmpzP2ZhOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9EY2NJbnB1dEZhY3RvcnkuanM/MmEyZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyLmpzPzM4N2EiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIuanM/ZWUwYiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyLmpzP2NkMDIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9TcGlubmVyLmpzPzE3MDgiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9idXR0b24uanM/MDYwZiJdLCJzb3VyY2VzQ29udGVudCI6WyJjbGFzcyBFcnJvckhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoZ2VuZXJpY0Vycm9yVGV4dClcbiAgICB7XG4gICAgICAgIHRoaXMuZ2VuZXJpY0Vycm9yVGV4dCA9IGdlbmVyaWNFcnJvclRleHQ7XG4gICAgICAgIHRoaXMud3JhcHBlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53b29jb21tZXJjZS1ub3RpY2VzLXdyYXBwZXInKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd1bC53b29jb21tZXJjZS1lcnJvcicpO1xuICAgIH1cblxuICAgIGdlbmVyaWNFcnJvcigpIHtcbiAgICAgICAgaWYgKHRoaXMud3JhcHBlci5jbGFzc0xpc3QuY29udGFpbnMoJ3BwY3AtcGVyc2lzdCcpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICB0aGlzLm1lc3NhZ2UodGhpcy5nZW5lcmljRXJyb3JUZXh0KVxuICAgIH1cblxuICAgIGFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudChlcnJvck1lc3NhZ2VFbGVtZW50KVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QucmVwbGFjZVdpdGgoZXJyb3JNZXNzYWdlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgbWVzc2FnZSh0ZXh0LCBwZXJzaXN0ID0gZmFsc2UpXG4gICAge1xuICAgICAgICBpZighIHR5cGVvZiBTdHJpbmcgfHwgdGV4dC5sZW5ndGggPT09IDApe1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIG5ldyBtZXNzYWdlIHRleHQgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCl7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwZXJzaXN0KSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmFkZCgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZSgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbWVzc2FnZU5vZGUgPSB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3RJdGVtKHRleHQpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5hcHBlbmRDaGlsZChtZXNzYWdlTm9kZSk7XG5cbiAgICAgICAgalF1ZXJ5LnNjcm9sbF90b19ub3RpY2VzKGpRdWVyeSgnLndvb2NvbW1lcmNlLW5vdGljZXMtd3JhcHBlcicpKVxuICAgIH1cblxuICAgIHByZXBhcmVNZXNzYWdlc0xpc3QoKVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpe1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdjbGFzcycsICd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdyb2xlJywgJ2FsZXJ0Jyk7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuYXBwZW5kQ2hpbGQodGhpcy5tZXNzYWdlc0xpc3QpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0obWVzc2FnZSlcbiAgICB7XG4gICAgICAgIGNvbnN0IGxpID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgICAgbGkuaW5uZXJIVE1MID0gbWVzc2FnZTtcblxuICAgICAgICByZXR1cm4gbGk7XG4gICAgfVxuXG4gICAgc2FuaXRpemUodGV4dClcbiAgICB7XG4gICAgICAgIGNvbnN0IHRleHRhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcbiAgICAgICAgdGV4dGFyZWEuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgcmV0dXJuIHRleHRhcmVhLnZhbHVlLnJlcGxhY2UoJ0Vycm9yOiAnLCAnJyk7XG4gICAgfVxuXG4gICAgY2xlYXIoKVxuICAgIHtcbiAgICAgICAgaWYgKCEgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5jb250YWlucygnd29vY29tbWVyY2UtZXJyb3InKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QucmVtb3ZlKCd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICB0aGlzLndyYXBwZXIuaW5uZXJUZXh0ID0gJyc7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFcnJvckhhbmRsZXI7XG4iLCJjb25zdCBvbkFwcHJvdmUgPSAoY29udGV4dCwgZXJyb3JIYW5kbGVyKSA9PiB7XG4gICAgcmV0dXJuIChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGNvbnRleHQuY29uZmlnLnJlZGlyZWN0O1xuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiZXhwb3J0IGNvbnN0IHBheWVyRGF0YSA9ICgpID0+IHtcbiAgICBjb25zdCBwYXllciA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5wYXllcjtcbiAgICBpZiAoISBwYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwaG9uZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpIHx8IHR5cGVvZiBwYXllci5waG9uZSAhPT0gJ3VuZGVmaW5lZCcpID9cbiAgICB7XG4gICAgICAgIHBob25lX3R5cGU6XCJIT01FXCIsXG4gICAgICAgICAgICBwaG9uZV9udW1iZXI6e1xuICAgICAgICAgICAgbmF0aW9uYWxfbnVtYmVyIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKS52YWx1ZSA6IHBheWVyLnBob25lLnBob25lX251bWJlci5uYXRpb25hbF9udW1iZXJcbiAgICAgICAgfVxuICAgIH0gOiBudWxsO1xuICAgIGNvbnN0IHBheWVyRGF0YSA9IHtcbiAgICAgICAgZW1haWxfYWRkcmVzczooZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpLnZhbHVlIDogcGF5ZXIuZW1haWxfYWRkcmVzcyxcbiAgICAgICAgbmFtZSA6IHtcbiAgICAgICAgICAgIHN1cm5hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuc3VybmFtZSxcbiAgICAgICAgICAgIGdpdmVuX25hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5naXZlbl9uYW1lXG4gICAgICAgIH0sXG4gICAgICAgIGFkZHJlc3MgOiB7XG4gICAgICAgICAgICBjb3VudHJ5X2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuY291bnRyeV9jb2RlLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8xLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8yLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8xLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMixcbiAgICAgICAgICAgIHBvc3RhbF9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MucG9zdGFsX2NvZGVcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAocGhvbmUpIHtcbiAgICAgICAgcGF5ZXJEYXRhLnBob25lID0gcGhvbmU7XG4gICAgfVxuICAgIHJldHVybiBwYXllckRhdGE7XG59XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENhcnRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOiBvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIpLFxuICAgICAgICAgICAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgTWluaUNhcnRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbignd2NfZnJhZ21lbnRzX2xvYWRlZCB3Y19mcmFnbWVudHNfcmVmcmVzaGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcikgIT09XG4gICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKVxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWluaUNhcnRCb290c3RhcDsiLCJpbXBvcnQgUHJvZHVjdCBmcm9tIFwiLi4vRW50aXR5L1Byb2R1Y3RcIjtcbmNsYXNzIFVwZGF0ZUNhcnQge1xuXG4gICAgY29uc3RydWN0b3IoZW5kcG9pbnQsIG5vbmNlKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludCA9IGVuZHBvaW50O1xuICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25SZXNvbHZlXG4gICAgICogQHBhcmFtIHtQcm9kdWN0W119IHByb2R1Y3RzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAgICovXG4gICAgdXBkYXRlKG9uUmVzb2x2ZSwgcHJvZHVjdHMpXG4gICAge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZmV0Y2goXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qc29uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gb25SZXNvbHZlKHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVcGRhdGVDYXJ0OyIsIi8qKlxuICogV2hlbiB5b3UgY2FuJ3QgYWRkIHNvbWV0aGluZyB0byB0aGUgY2FydCwgdGhlIFBheVBhbCBidXR0b25zIHNob3VsZCBub3Qgc2hvdy5cbiAqIFRoZXJlZm9yZSB3ZSBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiBhbmQgc2hvdy9oaWRlIHRoZSBidXR0b25zIGFjY29yZGluZ2x5LlxuICovXG5cbmNsYXNzIEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2hvd0NhbGxiYWNrLCBoaWRlQ2FsbGJhY2spXG4gICAge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnNob3dDYWxsYmFjayA9IHNob3dDYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2sgPSBoaWRlQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKVxuICAgIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0geyBhdHRyaWJ1dGVzIDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNob3dDYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgZGlzY29ubmVjdCgpXG4gICAge1xuICAgICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcjsiLCJjbGFzcyBQcm9kdWN0IHtcblxuICAgIGNvbnN0cnVjdG9yKGlkLCBxdWFudGl0eSwgdmFyaWF0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMucXVhbnRpdHkgPSBxdWFudGl0eTtcbiAgICAgICAgdGhpcy52YXJpYXRpb25zID0gdmFyaWF0aW9ucztcbiAgICB9XG5cbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6dGhpcy5pZCxcbiAgICAgICAgICAgIHF1YW50aXR5OnRoaXMucXVhbnRpdHksXG4gICAgICAgICAgICB2YXJpYXRpb25zOnRoaXMudmFyaWF0aW9uc1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0OyIsImltcG9ydCBCdXR0b25zVG9nZ2xlTGlzdGVuZXIgZnJvbSAnLi4vSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lcic7XG5pbXBvcnQgUHJvZHVjdCBmcm9tICcuLi9FbnRpdHkvUHJvZHVjdCc7XG5pbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHVwZGF0ZUNhcnQsXG4gICAgICAgIHNob3dCdXR0b25DYWxsYmFjayxcbiAgICAgICAgaGlkZUJ1dHRvbkNhbGxiYWNrLFxuICAgICAgICBmb3JtRWxlbWVudCxcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhcnQgPSB1cGRhdGVDYXJ0O1xuICAgICAgICB0aGlzLnNob3dCdXR0b25DYWxsYmFjayA9IHNob3dCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2sgPSBoaWRlQnV0dG9uQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnQgPSBmb3JtRWxlbWVudDtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpXG4gICAge1xuXG4gICAgICAgIGlmICggdGhpcy5oYXNWYXJpYXRpb25zKCkgKSB7XG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlX2FkZF90b19jYXJ0X2J1dHRvbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUJ1dHRvbkNhbGxiYWNrXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuaW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiB0aGlzLmNyZWF0ZU9yZGVyKCksXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU9yZGVyKClcbiAgICB7XG4gICAgICAgIHZhciBnZXRQcm9kdWN0cyA9IG51bGw7XG4gICAgICAgIGlmICghIHRoaXMuaXNHcm91cGVkUHJvZHVjdCgpICkge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cImFkZC10by1jYXJ0XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcXR5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25hbWU9XCJxdWFudGl0eVwiXScpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhdGlvbnMgPSB0aGlzLnZhcmlhdGlvbnMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBQcm9kdWN0KGlkLCBxdHksIHZhcmlhdGlvbnMpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFByb2R1Y3RzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwibnVtYmVyXCJdJykuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBlbGVtZW50LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpLm1hdGNoKC9xdWFudGl0eVxcWyhbXFxkXSopXFxdLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50TmFtZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHBhcnNlSW50KGVsZW1lbnROYW1lWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMucHVzaChuZXcgUHJvZHVjdChpZCwgcXVhbnRpdHksIG51bGwpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICBjb25zdCBvblJlc29sdmUgPSAocHVyY2hhc2VfdW5pdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnVwZGF0ZUNhcnQudXBkYXRlKG9uUmVzb2x2ZSwgZ2V0UHJvZHVjdHMoKSk7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU9yZGVyO1xuICAgIH1cblxuICAgIHZhcmlhdGlvbnMoKVxuICAgIHtcblxuICAgICAgICBpZiAoISB0aGlzLmhhc1ZhcmlhdGlvbnMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFsuLi50aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZV49J2F0dHJpYnV0ZV8nXVwiKV0ubWFwKFxuICAgICAgICAgICAgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOmVsZW1lbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ZWxlbWVudC5uYW1lXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICBoYXNWYXJpYXRpb25zKClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygndmFyaWF0aW9uc19mb3JtJyk7XG4gICAgfVxuXG4gICAgaXNHcm91cGVkUHJvZHVjdCgpXG4gICAge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyb3VwZWRfZm9ybScpO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhcnQgZnJvbSBcIi4uL0hlbHBlci9VcGRhdGVDYXJ0XCI7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIgZnJvbSBcIi4uL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXJcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXksXG4gICAgICAgICAgICBuZXcgVXBkYXRlQ2FydChcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5ub25jZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgbGV0IHByaWNlVGV4dCA9IFwiMFwiO1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlSW50KHByaWNlVGV4dC5yZXBsYWNlKC8oW15cXGQsXFwuXFxzXSopL2csICcnKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXJXaXRoQW1vdW50KGFtb3VudClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JyksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXA7IiwiaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuXG5jbGFzcyBDYXJ0Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscyB1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0Qm9vdHN0cmFwO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICBzcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmNvZGUgPT09IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbnMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhY3Rpb25zLnJlc3RhcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwbGFjZV9vcmRlcicpLmNsaWNrKClcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENoZWNrb3V0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMuc3Bpbm5lcjtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IHRoaXMuZXJyb3JIYW5kbGVyO1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtU2VsZWN0b3IgPSB0aGlzLmNvbmZpZy5jb250ZXh0ID09PSAnY2hlY2tvdXQnID8gJ2Zvcm0uY2hlY2tvdXQnIDogJ2Zvcm0jb3JkZXJfcmV2aWV3JztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSBqUXVlcnkoZm9ybVNlbGVjdG9yKS5zZXJpYWxpemUoKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlYWNjb3VudCA9IGpRdWVyeSgnI2NyZWF0ZWFjY291bnQnKS5pcyhcIjpjaGVja2VkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyX2lkOnRoaXMuY29uZmlnLm9yZGVyX2lkLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOmZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWFjY291bnQ6IGNyZWF0ZWFjY291bnRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vaGFuZGxlIGJvdGggbWVzc2FnZXMgc2VudCBmcm9tIFdvb2NvbW1lcmNlIChkYXRhLm1lc3NhZ2VzKSBhbmQgdGhpcyBwbHVnaW4gKGRhdGEuZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKGRhdGEubWVzc2FnZXMpICE9PSAndW5kZWZpbmVkJyApXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5hcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhkYXRhLm1lc3NhZ2VzLCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJ3VsJylcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3BwY3AtcmVzdW1lLW9yZGVyJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGRhdGEuZGF0YS5wdXJjaGFzZV91bml0c1swXS5jdXN0b21faWQpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVNlbGVjdG9yKS5hcHBlbmQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6b25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyLCB0aGlzLnNwaW5uZXIpLFxuICAgICAgICAgICAgb25DYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDaGVja291dEFjdGlvbkhhbmRsZXIgZnJvbSAnLi4vQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXInO1xuXG5jbGFzcyBDaGVja291dEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKClcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLlxuICAgICAgICAgIG9uKCd1cGRhdGVkX2NoZWNrb3V0IHBheW1lbnRfbWV0aG9kX3NlbGVjdGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpXG4gICAgICAgICAgICAgIHRoaXMuZGlzcGxheVBsYWNlT3JkZXJCdXR0b25Gb3JTYXZlZENyZWRpdENhcmRzKClcblxuICAgICAgICAgIH0pXG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50KS5vbignaG9zdGVkX2ZpZWxkc19sb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKVxuICAgICAgICB0aGlzLmRpc3BsYXlQbGFjZU9yZGVyQnV0dG9uRm9yU2F2ZWRDcmVkaXRDYXJkcygpXG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLmNhbmNlbF93cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKSAhPT0gbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PSBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2JykpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2Jykuc2V0QXR0cmlidXRlKCdzdHlsZScsICcnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IENoZWNrb3V0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpIHtcbiAgICAgICAgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQgb3B0aW9uOmZpcnN0JykudmFsKCkpO1xuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICAgJ2lucHV0W25hbWU9XCJwYXltZW50X21ldGhvZFwiXTpjaGVja2VkJykudmFsKCk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kICE9PSAncHBjcC1nYXRld2F5JyAmJiBjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgalF1ZXJ5KCcjcGxhY2Vfb3JkZXInKS5oaWRlKCk7XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyKClcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS5sZW5ndGggJiYgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoKSAhPT0gJycpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcilcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpXG4gICAgICAgICAgICB0aGlzLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLmVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgZmFsc2UpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEJvb3RzdGFwXG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2hlY2tvdXRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgUGF5Tm93Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5cbiAgICAgICAgb24oJ3VwZGF0ZWRfY2hlY2tvdXQgcGF5bWVudF9tZXRob2Rfc2VsZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24uY2FuY2VsX3dyYXBwZXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PSBudWxsIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcikgIT09IG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKSkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICAgICAgdGhpcy5zcGlubmVyXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgc3dpdGNoQmV0d2VlblBheVBhbGFuZE9yZGVyQnV0dG9uKCkge1xuICAgICAgICBjb25zdCB1cmxQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpXG4gICAgICAgIGlmICh1cmxQYXJhbXMuaGFzKCdjaGFuZ2VfcGF5bWVudF9tZXRob2QnKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IGpRdWVyeShcbiAgICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuXG4gICAgICAgIGlmIChjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtZ2F0ZXdheScgJiYgY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICBqUXVlcnkoJyNwbGFjZV9vcmRlcicpLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kID09PSAncHBjcC1nYXRld2F5Jykge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnJlbmRlcigpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBheU5vd0Jvb3RzdHJhcDtcbiIsImNsYXNzIFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihjcmVkaXRDYXJkUmVuZGVyZXIsIGRlZmF1bHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIgPSBjcmVkaXRDYXJkUmVuZGVyZXI7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICB0aGlzLnJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLnJlbmRlcihob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICB9XG5cbiAgICByZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSB8fCB0aGlzLmlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHx8ICd1bmRlZmluZWQnID09PSB0eXBlb2YgcGF5cGFsLkJ1dHRvbnMgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdHlsZSA9IHdyYXBwZXIgPT09IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ud3JhcHBlciA/IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24uc3R5bGUgOiB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLm1pbmlfY2FydF9zdHlsZTtcbiAgICAgICAgcGF5cGFsLkJ1dHRvbnMoe1xuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAuLi5jb250ZXh0Q29uZmlnLFxuICAgICAgICB9KS5yZW5kZXIod3JhcHBlcik7XG4gICAgfVxuXG4gICAgaXNBbHJlYWR5UmVuZGVyZWQod3JhcHBlcikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5oYXNDaGlsZE5vZGVzKCk7XG4gICAgfVxuXG4gICAgaGlkZUJ1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHNob3dCdXR0b25zKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgICAgIGlmICghIGRvbUVsZW1lbnQgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZG9tRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmRpc2FibGVGaWVsZHMoKTtcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5lbmFibGVGaWVsZHMoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlcmVyO1xuIiwiY29uc3QgZGNjSW5wdXRGYWN0b3J5ID0gKG9yaWdpbmFsKSA9PiB7XG4gICAgY29uc3Qgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUob3JpZ2luYWwpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2lkJywgb3JpZ2luYWwuaWQpO1xuICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzKS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICBpZiAoISBzdHlsZXNbcHJvcF0gfHwgISBpc05hTihwcm9wKSApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBuZXdFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KHByb3AsJycgKyBzdHlsZXNbcHJvcF0pO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBkY2NJbnB1dEZhY3Rvcnk7IiwiaW1wb3J0IGRjY0lucHV0RmFjdG9yeSBmcm9tIFwiLi4vSGVscGVyL0RjY0lucHV0RmFjdG9yeVwiO1xuXG5jbGFzcyBDcmVkaXRDYXJkUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoZGVmYXVsdENvbmZpZywgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmNvbnRleHQgIT09ICdjaGVja291dCdcbiAgICAgICAgICAgICAgICAmJiB0aGlzLmRlZmF1bHRDb25maWcuY29udGV4dCAhPT0gJ3BheS1ub3cnXG4gICAgICAgICAgICApXG4gICAgICAgICAgICB8fCB3cmFwcGVyID09PSBudWxsXG4gICAgICAgICAgICB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpID09PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYXlwYWwuSG9zdGVkRmllbGRzID09PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgfHwgISBwYXlwYWwuSG9zdGVkRmllbGRzLmlzRWxpZ2libGUoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZXJFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKTtcbiAgICAgICAgICAgIHdyYXBwZXJFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQod3JhcHBlckVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS50ZWFyZG93bigpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmVycm9yKGBIb3N0ZWQgZmllbGRzIHRlYXJkb3duIGVycm9yOiAke2Vycn1gKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBnYXRlV2F5Qm94ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBheW1lbnRfYm94LnBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpO1xuICAgICAgICBjb25zdCBvbGREaXNwbGF5U3R5bGUgPSBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXk7XG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgICAgY29uc3QgaGlkZURjY0dhdGV3YXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1oaWRlLWRjYycpO1xuICAgICAgICBpZiAoaGlkZURjY0dhdGV3YXkpIHtcbiAgICAgICAgICAgIGhpZGVEY2NHYXRld2F5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaGlkZURjY0dhdGV3YXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlckZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpO1xuXG4gICAgICAgIGNvbnN0IHN0eWxlc1JhdyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNhcmROdW1iZXJGaWVsZCk7XG4gICAgICAgIGxldCBzdHlsZXMgPSB7fTtcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzdHlsZXNSYXcpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgICAgICBpZiAoISBzdHlsZXNSYXdbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHlsZXNbcHJvcF0gPSAnJyArIHN0eWxlc1Jhd1twcm9wXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlciA9IGRjY0lucHV0RmFjdG9yeShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBjYXJkTnVtYmVyRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZE51bWJlciwgY2FyZE51bWJlckZpZWxkKTtcblxuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5RmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5Jyk7XG4gICAgICAgIGNvbnN0IGNhcmRFeHBpcnkgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZEV4cGlyeUZpZWxkKTtcbiAgICAgICAgY2FyZEV4cGlyeUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRFeHBpcnksIGNhcmRFeHBpcnlGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZENvZGVGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKTtcbiAgICAgICAgY29uc3QgY2FyZENvZGUgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZENvZGVGaWVsZCk7XG4gICAgICAgIGNhcmRDb2RlRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZENvZGUsIGNhcmRDb2RlRmllbGQpO1xuXG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9IG9sZERpc3BsYXlTdHlsZTtcblxuICAgICAgICBjb25zdCBmb3JtV3JhcHBlciA9ICcucGF5bWVudF9ib3ggcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHRcbiAgICAgICAgICAgICYmIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0JylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5cGFsLkhvc3RlZEZpZWxkcy5yZW5kZXIoe1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IGNvbnRleHRDb25maWcuY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBzdHlsZXM6IHtcbiAgICAgICAgICAgICAgICAnaW5wdXQnOiBzdHlsZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICAgICAgICBudW1iZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jcmVkaXRfY2FyZF9udW1iZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjdnY6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jdnYsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBleHBpcmF0aW9uRGF0ZToge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLm1tX3l5LFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkudGhlbihob3N0ZWRGaWVsZHMgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJob3N0ZWRfZmllbGRzX2xvYWRlZFwiKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IGhvc3RlZEZpZWxkcztcblxuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdpbnB1dFN1Ym1pdFJlcXVlc3QnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ2NhcmRUeXBlQ2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCAhIGV2ZW50LmNhcmRzLmxlbmd0aCApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZENhcmRzID0gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMudmFsaWRfY2FyZHM7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSB2YWxpZENhcmRzLmluZGV4T2YoZXZlbnQuY2FyZHNbMF0udHlwZSkgIT09IC0xO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbigndmFsaWRpdHlDaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtVmFsaWQgPSBPYmplY3Qua2V5cyhldmVudC5maWVsZHMpLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmZpZWxkc1trZXldLmlzVmFsaWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZvcm1WYWxpZDtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5mb3JtU3VibWlzc2lvblN1YnNjcmliZWQpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIgKyAnIGJ1dHRvbicpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdWJtaXQoY29udGV4dENvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2xhYmVsW2Zvcj1wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJdJykuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgIH1cblxuICAgIGRpc2FibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmFibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc3VibWl0KGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5zcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZm9ybVZhbGlkICYmIHRoaXMuY2FyZFZhbGlkKSB7XG4gICAgICAgICAgICBjb25zdCBzYXZlX2NhcmQgPSB0aGlzLmRlZmF1bHRDb25maWcuc2F2ZV9jYXJkID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICAgICAgbGV0IHZhdWx0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKSA/XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5jaGVja2VkIDogc2F2ZV9jYXJkO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbmZpZy5lbmZvcmNlX3ZhdWx0KSB7XG4gICAgICAgICAgICAgICAgdmF1bHQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY29udGluZ2VuY3kgPSB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5jb250aW5nZW5jeTtcbiAgICAgICAgICAgIGNvbnN0IGhvc3RlZEZpZWxkc0RhdGEgPSB7XG4gICAgICAgICAgICAgICAgdmF1bHQ6IHZhdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGNvbnRpbmdlbmN5ICE9PSAnTk9fM0RfU0VDVVJFJykge1xuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY29udGluZ2VuY2llcyA9IFtjb250aW5nZW5jeV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zdWJtaXQoaG9zdGVkRmllbGRzRGF0YSkudGhlbigocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgIHBheWxvYWQub3JkZXJJRCA9IHBheWxvYWQub3JkZXJJZDtcbiAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0Q29uZmlnLm9uQXBwcm92ZShwYXlsb2FkKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gISB0aGlzLmNhcmRWYWxpZCA/IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jYXJkX25vdF9zdXBwb3J0ZWQgOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuZmllbGRzX25vdF92YWxpZDtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBDcmVkaXRDYXJkUmVuZGVyZXI7XG4iLCJjb25zdCBzdG9yYWdlS2V5ID0gJ3BwY3AtZGF0YS1jbGllbnQtaWQnO1xuXG5jb25zdCB2YWxpZGF0ZVRva2VuID0gKHRva2VuLCB1c2VyKSA9PiB7XG4gICAgaWYgKCEgdG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodG9rZW4udXNlciAhPT0gdXNlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgY29uc3QgaXNFeHBpcmVkID0gY3VycmVudFRpbWUgPj0gdG9rZW4uZXhwaXJhdGlvbiAqIDEwMDA7XG4gICAgcmV0dXJuICEgaXNFeHBpcmVkO1xufVxuXG5jb25zdCBzdG9yZWRUb2tlbkZvclVzZXIgPSAodXNlcikgPT4ge1xuICAgIGNvbnN0IHRva2VuID0gSlNPTi5wYXJzZShzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHN0b3JhZ2VLZXkpKTtcbiAgICBpZiAodmFsaWRhdGVUb2tlbih0b2tlbiwgdXNlcikpIHtcbiAgICAgICAgcmV0dXJuIHRva2VuLnRva2VuO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuY29uc3Qgc3RvcmVUb2tlbiA9ICh0b2tlbikgPT4ge1xuICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oc3RvcmFnZUtleSwgSlNPTi5zdHJpbmdpZnkodG9rZW4pKTtcbn1cblxuY29uc3QgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciA9IChzY3JpcHQsIGNvbmZpZykgPT4ge1xuICAgIGZldGNoKGNvbmZpZy5lbmRwb2ludCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgbm9uY2U6IGNvbmZpZy5ub25jZVxuICAgICAgICB9KVxuICAgIH0pLnRoZW4oKHJlcyk9PntcbiAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgY29uc3QgaXNWYWxpZCA9IHZhbGlkYXRlVG9rZW4oZGF0YSwgY29uZmlnLnVzZXIpO1xuICAgICAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdG9yZVRva2VuKGRhdGEpO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdkYXRhLWNsaWVudC10b2tlbicsIGRhdGEudG9rZW4pO1xuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChzY3JpcHQpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyO1xuIiwiY2xhc3MgTWVzc2FnZVJlbmRlcmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQ6IHRoaXMuY29uZmlnLmFtb3VudCxcbiAgICAgICAgICAgIHBsYWNlbWVudDogdGhpcy5jb25maWcucGxhY2VtZW50LFxuICAgICAgICAgICAgc3R5bGU6IHRoaXMuY29uZmlnLnN0eWxlXG4gICAgICAgIH0pLnJlbmRlcih0aGlzLmNvbmZpZy53cmFwcGVyKTtcbiAgICB9XG5cbiAgICByZW5kZXJXaXRoQW1vdW50KGFtb3VudCkge1xuXG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5ld1dyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgbmV3V3JhcHBlci5zZXRBdHRyaWJ1dGUoJ2lkJywgdGhpcy5jb25maWcud3JhcHBlci5yZXBsYWNlKCcjJywgJycpKTtcblxuICAgICAgICBjb25zdCBzaWJsaW5nID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5uZXh0U2libGluZztcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpO1xuICAgICAgICBzaWJsaW5nLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKG5ld1dyYXBwZXIsIHNpYmxpbmcpO1xuICAgICAgICBwYXlwYWwuTWVzc2FnZXMoe1xuICAgICAgICAgICAgYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcblxuICAgICAgICBpZiAodHlwZW9mIHBheXBhbC5NZXNzYWdlcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHRoaXMuY29uZmlnLndyYXBwZXIgPT09ICd1bmRlZmluZWQnICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBNZXNzYWdlUmVuZGVyZXI7IiwiY2xhc3MgU3Bpbm5lciB7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy50YXJnZXQgPSAnZm9ybS53b29jb21tZXJjZS1jaGVja291dCc7XG4gICAgfVxuXG4gICAgc2V0VGFyZ2V0KHRhcmdldCkge1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICB9XG5cbiAgICBibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkuYmxvY2soe1xuICAgICAgICAgICAgbWVzc2FnZTogbnVsbCxcbiAgICAgICAgICAgIG92ZXJsYXlDU1M6IHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAnI2ZmZicsXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC42XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVuYmxvY2soKSB7XG5cbiAgICAgICAgalF1ZXJ5KCB0aGlzLnRhcmdldCApLnVuYmxvY2soKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNwaW5uZXI7XG4iLCJpbXBvcnQgTWluaUNhcnRCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9NaW5pQ2FydEJvb3RzdGFwJztcbmltcG9ydCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvU2luZ2xlUHJvZHVjdEJvb3RzdGFwJztcbmltcG9ydCBDYXJ0Qm9vdHN0cmFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NhcnRCb290c3RhcCc7XG5pbXBvcnQgQ2hlY2tvdXRCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwJztcbmltcG9ydCBQYXlOb3dCb290c3RyYXAgZnJvbSBcIi4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1BheU5vd0Jvb3RzdHJhcFwiO1xuaW1wb3J0IFJlbmRlcmVyIGZyb20gJy4vbW9kdWxlcy9SZW5kZXJlci9SZW5kZXJlcic7XG5pbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4vbW9kdWxlcy9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENyZWRpdENhcmRSZW5kZXJlciBmcm9tIFwiLi9tb2R1bGVzL1JlbmRlcmVyL0NyZWRpdENhcmRSZW5kZXJlclwiO1xuaW1wb3J0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIgZnJvbSBcIi4vbW9kdWxlcy9EYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyXCI7XG5pbXBvcnQgTWVzc2FnZVJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyXCI7XG5pbXBvcnQgU3Bpbm5lciBmcm9tIFwiLi9tb2R1bGVzL0hlbHBlci9TcGlubmVyXCI7XG5cbmNvbnN0IGJvb3RzdHJhcCA9ICgpID0+IHtcbiAgICBjb25zdCBlcnJvckhhbmRsZXIgPSBuZXcgRXJyb3JIYW5kbGVyKFBheVBhbENvbW1lcmNlR2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyk7XG4gICAgY29uc3Qgc3Bpbm5lciA9IG5ldyBTcGlubmVyKCk7XG4gICAgY29uc3QgY3JlZGl0Q2FyZFJlbmRlcmVyID0gbmV3IENyZWRpdENhcmRSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXksIGVycm9ySGFuZGxlciwgc3Bpbm5lcik7XG4gICAgY29uc3QgcmVuZGVyZXIgPSBuZXcgUmVuZGVyZXIoY3JlZGl0Q2FyZFJlbmRlcmVyLCBQYXlQYWxDb21tZXJjZUdhdGV3YXkpO1xuICAgIGNvbnN0IG1lc3NhZ2VSZW5kZXJlciA9IG5ldyBNZXNzYWdlUmVuZGVyZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1lc3NhZ2VzKTtcbiAgICBjb25zdCBjb250ZXh0ID0gUGF5UGFsQ29tbWVyY2VHYXRld2F5LmNvbnRleHQ7XG4gICAgaWYgKGNvbnRleHQgPT09ICdtaW5pLWNhcnQnIHx8IGNvbnRleHQgPT09ICdwcm9kdWN0Jykge1xuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQgPT09ICcxJykge1xuICAgICAgICAgICAgY29uc3QgbWluaUNhcnRCb290c3RyYXAgPSBuZXcgTWluaUNhcnRCb290c3RhcChcbiAgICAgICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICAgICAgcmVuZGVyZXJcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIG1pbmlDYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncHJvZHVjdCcgJiYgUGF5UGFsQ29tbWVyY2VHYXRld2F5LnNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgIGNvbnN0IHNpbmdsZVByb2R1Y3RCb290c3RyYXAgPSBuZXcgU2luZ2xlUHJvZHVjdEJvb3RzdGFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICk7XG5cbiAgICAgICAgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdjYXJ0Jykge1xuICAgICAgICBjb25zdCBjYXJ0Qm9vdHN0cmFwID0gbmV3IENhcnRCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBjYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBjb25zdCBjaGVja291dEJvb3RzdGFwID0gbmV3IENoZWNrb3V0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcblxuICAgICAgICBjaGVja291dEJvb3RzdGFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ3BheS1ub3cnICkge1xuICAgICAgICBjb25zdCBwYXlOb3dCb290c3RyYXAgPSBuZXcgUGF5Tm93Qm9vdHN0cmFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICAgICBzcGlubmVyXG4gICAgICAgICk7XG4gICAgICAgIHBheU5vd0Jvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgIT09ICdjaGVja291dCcpIHtcbiAgICAgICAgbWVzc2FnZVJlbmRlcmVyLnJlbmRlcigpO1xuICAgIH1cbn07XG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICdET01Db250ZW50TG9hZGVkJyxcbiAgICAoKSA9PiB7XG4gICAgICAgIGlmICghdHlwZW9mIChQYXlQYWxDb21tZXJjZUdhdGV3YXkpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdQYXlQYWwgYnV0dG9uIGNvdWxkIG5vdCBiZSBjb25maWd1cmVkLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gICAgICAgIHNjcmlwdC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBib290c3RyYXAoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ3NyYycsIFBheVBhbENvbW1lcmNlR2F0ZXdheS5idXR0b24udXJsKTtcbiAgICAgICAgT2JqZWN0LmVudHJpZXMoUGF5UGFsQ29tbWVyY2VHYXRld2F5LnNjcmlwdF9hdHRyaWJ1dGVzKS5mb3JFYWNoKFxuICAgICAgICAgICAgKGtleVZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgc2NyaXB0LnNldEF0dHJpYnV0ZShrZXlWYWx1ZVswXSwga2V5VmFsdWVbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQuc2V0X2F0dHJpYnV0ZSkge1xuICAgICAgICAgICAgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlcihzY3JpcHQsIFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChzY3JpcHQpO1xuICAgIH0sXG4pO1xuIl0sIm5hbWVzIjpbIkVycm9ySGFuZGxlciIsImNvbnN0cnVjdG9yIiwiZ2VuZXJpY0Vycm9yVGV4dCIsIndyYXBwZXIiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJtZXNzYWdlc0xpc3QiLCJnZW5lcmljRXJyb3IiLCJjbGFzc0xpc3QiLCJjb250YWlucyIsImNsZWFyIiwibWVzc2FnZSIsImFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudCIsImVycm9yTWVzc2FnZUVsZW1lbnQiLCJwcmVwYXJlTWVzc2FnZXNMaXN0IiwicmVwbGFjZVdpdGgiLCJ0ZXh0IiwicGVyc2lzdCIsIlN0cmluZyIsImxlbmd0aCIsIkVycm9yIiwiYWRkIiwicmVtb3ZlIiwibWVzc2FnZU5vZGUiLCJwcmVwYXJlTWVzc2FnZXNMaXN0SXRlbSIsImFwcGVuZENoaWxkIiwialF1ZXJ5Iiwic2Nyb2xsX3RvX25vdGljZXMiLCJjcmVhdGVFbGVtZW50Iiwic2V0QXR0cmlidXRlIiwibGkiLCJpbm5lckhUTUwiLCJzYW5pdGl6ZSIsInRleHRhcmVhIiwidmFsdWUiLCJyZXBsYWNlIiwiaW5uZXJUZXh0Iiwib25BcHByb3ZlIiwiY29udGV4dCIsImVycm9ySGFuZGxlciIsImRhdGEiLCJhY3Rpb25zIiwiZmV0Y2giLCJjb25maWciLCJhamF4IiwiYXBwcm92ZV9vcmRlciIsImVuZHBvaW50IiwibWV0aG9kIiwiYm9keSIsIkpTT04iLCJzdHJpbmdpZnkiLCJub25jZSIsIm9yZGVyX2lkIiwib3JkZXJJRCIsInRoZW4iLCJyZXMiLCJqc29uIiwic3VjY2VzcyIsInJlc3RhcnQiLCJjYXRjaCIsImVyciIsImxvY2F0aW9uIiwiaHJlZiIsInJlZGlyZWN0IiwicGF5ZXJEYXRhIiwicGF5ZXIiLCJQYXlQYWxDb21tZXJjZUdhdGV3YXkiLCJwaG9uZSIsInBob25lX3R5cGUiLCJwaG9uZV9udW1iZXIiLCJuYXRpb25hbF9udW1iZXIiLCJlbWFpbF9hZGRyZXNzIiwibmFtZSIsInN1cm5hbWUiLCJnaXZlbl9uYW1lIiwiYWRkcmVzcyIsImNvdW50cnlfY29kZSIsImFkZHJlc3NfbGluZV8xIiwiYWRkcmVzc19saW5lXzIiLCJhZG1pbl9hcmVhXzEiLCJhZG1pbl9hcmVhXzIiLCJwb3N0YWxfY29kZSIsIkNhcnRBY3Rpb25IYW5kbGVyIiwiY29uZmlndXJhdGlvbiIsImNyZWF0ZU9yZGVyIiwiYm5Db2RlIiwiYm5fY29kZXMiLCJjcmVhdGVfb3JkZXIiLCJwdXJjaGFzZV91bml0cyIsImJuX2NvZGUiLCJjb25zb2xlIiwiZXJyb3IiLCJpZCIsIm9uRXJyb3IiLCJNaW5pQ2FydEJvb3RzdGFwIiwiZ2F0ZXdheSIsInJlbmRlcmVyIiwiYWN0aW9uSGFuZGxlciIsImluaXQiLCJsYWJlbHMiLCJnZW5lcmljIiwicmVuZGVyIiwib24iLCJzaG91bGRSZW5kZXIiLCJidXR0b24iLCJtaW5pX2NhcnRfd3JhcHBlciIsImhvc3RlZF9maWVsZHMiLCJQcm9kdWN0IiwiVXBkYXRlQ2FydCIsInVwZGF0ZSIsIm9uUmVzb2x2ZSIsInByb2R1Y3RzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJyZXN1bHQiLCJyZXNvbHZlZCIsIkJ1dHRvbnNUb2dnbGVMaXN0ZW5lciIsImVsZW1lbnQiLCJzaG93Q2FsbGJhY2siLCJoaWRlQ2FsbGJhY2siLCJvYnNlcnZlciIsImF0dHJpYnV0ZXMiLCJjYWxsYmFjayIsIk11dGF0aW9uT2JzZXJ2ZXIiLCJvYnNlcnZlIiwiZGlzY29ubmVjdCIsInF1YW50aXR5IiwidmFyaWF0aW9ucyIsIlNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIiwidXBkYXRlQ2FydCIsInNob3dCdXR0b25DYWxsYmFjayIsImhpZGVCdXR0b25DYWxsYmFjayIsImZvcm1FbGVtZW50IiwiaGFzVmFyaWF0aW9ucyIsImdldFByb2R1Y3RzIiwiaXNHcm91cGVkUHJvZHVjdCIsInF0eSIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJmb3JFYWNoIiwiZWxlbWVudE5hbWUiLCJnZXRBdHRyaWJ1dGUiLCJtYXRjaCIsInBhcnNlSW50IiwicHVzaCIsInByb21pc2UiLCJtYXAiLCJTaW5nbGVQcm9kdWN0Qm9vdHN0YXAiLCJtZXNzYWdlcyIsImhpZGVCdXR0b25zIiwiY2hhbmdlX2NhcnQiLCJzaG93QnV0dG9ucyIsInByaWNlVGV4dCIsImFtb3VudCIsInJlbmRlcldpdGhBbW91bnQiLCJDYXJ0Qm9vdHN0cmFwIiwic3Bpbm5lciIsImJsb2NrIiwidW5ibG9jayIsImNvZGUiLCJjbGljayIsIkNoZWNrb3V0QWN0aW9uSGFuZGxlciIsImZvcm1TZWxlY3RvciIsImZvcm1WYWx1ZXMiLCJzZXJpYWxpemUiLCJjcmVhdGVhY2NvdW50IiwiaXMiLCJmb3JtIiwiZG9tUGFyc2VyIiwiRE9NUGFyc2VyIiwicGFyc2VGcm9tU3RyaW5nIiwiaW5wdXQiLCJjdXN0b21faWQiLCJhcHBlbmQiLCJvbkNhbmNlbCIsIkNoZWNrb3V0Qm9vdHN0YXAiLCJzd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24iLCJkaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMiLCJjYW5jZWxfd3JhcHBlciIsInZhbCIsImN1cnJlbnRQYXltZW50TWV0aG9kIiwic2hvdyIsImhpZGUiLCJkaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcyIsImVuYWJsZUNyZWRpdENhcmRGaWVsZHMiLCJhZGRDbGFzcyIsImF0dHIiLCJyZW1vdmVDbGFzcyIsIlBheU5vd0Jvb3RzdHJhcCIsInVybFBhcmFtcyIsIlVSTFNlYXJjaFBhcmFtcyIsIndpbmRvdyIsInNlYXJjaCIsImhhcyIsIlJlbmRlcmVyIiwiY3JlZGl0Q2FyZFJlbmRlcmVyIiwiZGVmYXVsdENvbmZpZyIsImhvc3RlZEZpZWxkc1dyYXBwZXIiLCJjb250ZXh0Q29uZmlnIiwicmVuZGVyQnV0dG9ucyIsImlzQWxyZWFkeVJlbmRlcmVkIiwicGF5cGFsIiwiQnV0dG9ucyIsInN0eWxlIiwibWluaV9jYXJ0X3N0eWxlIiwiaGFzQ2hpbGROb2RlcyIsImRvbUVsZW1lbnQiLCJkaXNwbGF5IiwiZGlzYWJsZUZpZWxkcyIsImVuYWJsZUZpZWxkcyIsImRjY0lucHV0RmFjdG9yeSIsIm9yaWdpbmFsIiwic3R5bGVzIiwiZ2V0Q29tcHV0ZWRTdHlsZSIsIm5ld0VsZW1lbnQiLCJPYmplY3QiLCJ2YWx1ZXMiLCJwcm9wIiwiaXNOYU4iLCJzZXRQcm9wZXJ0eSIsIkNyZWRpdENhcmRSZW5kZXJlciIsImNhcmRWYWxpZCIsImZvcm1WYWxpZCIsImN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSIsImZvcm1TdWJtaXNzaW9uU3Vic2NyaWJlZCIsIkhvc3RlZEZpZWxkcyIsImlzRWxpZ2libGUiLCJ3cmFwcGVyRWxlbWVudCIsInBhcmVudE5vZGUiLCJyZW1vdmVDaGlsZCIsInRlYXJkb3duIiwiZ2F0ZVdheUJveCIsIm9sZERpc3BsYXlTdHlsZSIsImhpZGVEY2NHYXRld2F5IiwiY2FyZE51bWJlckZpZWxkIiwic3R5bGVzUmF3IiwiY2FyZE51bWJlciIsInJlcGxhY2VDaGlsZCIsImNhcmRFeHBpcnlGaWVsZCIsImNhcmRFeHBpcnkiLCJjYXJkQ29kZUZpZWxkIiwiY2FyZENvZGUiLCJmb3JtV3JhcHBlciIsImVuZm9yY2VfdmF1bHQiLCJjaGVja2VkIiwiZmllbGRzIiwibnVtYmVyIiwic2VsZWN0b3IiLCJwbGFjZWhvbGRlciIsImNyZWRpdF9jYXJkX251bWJlciIsImN2diIsImV4cGlyYXRpb25EYXRlIiwibW1feXkiLCJob3N0ZWRGaWVsZHMiLCJkaXNwYXRjaEV2ZW50IiwiQ3VzdG9tRXZlbnQiLCJfc3VibWl0IiwiZXZlbnQiLCJjYXJkcyIsInZhbGlkQ2FyZHMiLCJ2YWxpZF9jYXJkcyIsImluZGV4T2YiLCJ0eXBlIiwia2V5cyIsImV2ZXJ5Iiwia2V5IiwiaXNWYWxpZCIsImFkZEV2ZW50TGlzdGVuZXIiLCJwcmV2ZW50RGVmYXVsdCIsImZpZWxkIiwiYXR0cmlidXRlIiwicmVtb3ZlQXR0cmlidXRlIiwic2F2ZV9jYXJkIiwidmF1bHQiLCJnZXRFbGVtZW50QnlJZCIsImNvbnRpbmdlbmN5IiwiaG9zdGVkRmllbGRzRGF0YSIsImNvbnRpbmdlbmNpZXMiLCJzdWJtaXQiLCJwYXlsb2FkIiwib3JkZXJJZCIsImNhcmRfbm90X3N1cHBvcnRlZCIsImZpZWxkc19ub3RfdmFsaWQiLCJzdG9yYWdlS2V5IiwidmFsaWRhdGVUb2tlbiIsInRva2VuIiwidXNlciIsImN1cnJlbnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJpc0V4cGlyZWQiLCJleHBpcmF0aW9uIiwic3RvcmVkVG9rZW5Gb3JVc2VyIiwicGFyc2UiLCJzZXNzaW9uU3RvcmFnZSIsImdldEl0ZW0iLCJzdG9yZVRva2VuIiwic2V0SXRlbSIsImRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIiLCJzY3JpcHQiLCJNZXNzYWdlUmVuZGVyZXIiLCJNZXNzYWdlcyIsInBsYWNlbWVudCIsIm5ld1dyYXBwZXIiLCJzaWJsaW5nIiwibmV4dFNpYmxpbmciLCJwYXJlbnRFbGVtZW50IiwiaW5zZXJ0QmVmb3JlIiwiU3Bpbm5lciIsInRhcmdldCIsInNldFRhcmdldCIsIm92ZXJsYXlDU1MiLCJiYWNrZ3JvdW5kIiwib3BhY2l0eSIsImJvb3RzdHJhcCIsIm1lc3NhZ2VSZW5kZXJlciIsIm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQiLCJtaW5pQ2FydEJvb3RzdHJhcCIsInNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCIsInNpbmdsZVByb2R1Y3RCb290c3RyYXAiLCJjYXJ0Qm9vdHN0cmFwIiwiY2hlY2tvdXRCb290c3RhcCIsInBheU5vd0Jvb3RzdHJhcCIsInVybCIsImVudHJpZXMiLCJzY3JpcHRfYXR0cmlidXRlcyIsImtleVZhbHVlIiwiZGF0YV9jbGllbnRfaWQiLCJzZXRfYXR0cmlidXRlIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///94\n")}},__webpack_exports__={};__webpack_modules__[94]()})();
|
1 |
+
(()=>{"use strict";var __webpack_modules__={964:()=>{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 })\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\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/ActionHandler/CartActionHandler.js\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 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\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 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 init() {\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 if (document.querySelector('form.cart') === null) {\n return false;\n }\n\n return true;\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 })\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\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 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.message(data.data.message, true);\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\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 = '#place_order';\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 = this.currentPaymentMethod();\n const isPaypal = currentPaymentMethod === 'ppcp-gateway';\n const isCard = currentPaymentMethod === 'ppcp-credit-card-gateway';\n const isSavedCard = isCard && this.isSavedCardSelected();\n const isNotOurGateway = !isPaypal && !isCard;\n setVisible(this.standardOrderButtonSelector, isNotOurGateway || isSavedCard, true);\n setVisible(this.gateway.button.wrapper, isPaypal);\n setVisible(this.gateway.messages.wrapper, isPaypal);\n setVisible(this.gateway.hosted_fields.wrapper, isCard && !isSavedCard);\n\n if (isPaypal) {\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 currentPaymentMethod() {\n return jQuery('input[name=\"payment_method\"]:checked').val();\n }\n\n isSavedCardSelected() {\n const savedCardList = jQuery('#saved-credit-card');\n return savedCardList.length && savedCardList.val() !== '';\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_CheckoutBootstap = (CheckoutBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/PayNowBootstrap.js\n\n\nclass PayNowBootstrap extends ContextBootstrap_CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n super(gateway, renderer, messages, spinner);\n }\n\n updateUi() {\n const urlParams = new URLSearchParams(window.location.search);\n\n if (urlParams.has('change_payment_method')) {\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) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\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 }).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\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 this.formSubmissionSubscribed = false;\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 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\n if (!this.formSubmissionSubscribed) {\n document.querySelector(wrapper + ' button').addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n this.formSubmissionSubscribed = 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.save_card ? 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 console.error(err);\n this.spinner.unblock();\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() {\n this.target = 'form.woocommerce-checkout';\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/button.js\n\n\n\n\n\n\n\n\n\n\n\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 renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway);\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 const script = document.createElement('script');\n script.addEventListener('load', event => {\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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Q0E7QUFDSDs7QUFDRCxRQUFNd08sTUFBTSxHQUFHOVQsUUFBUSxDQUFDd0IsYUFBVCxDQUF1QixRQUF2QixDQUFmO0FBRUFzUyxFQUFBQSxNQUFNLENBQUNwQyxnQkFBUCxDQUF3QixNQUF4QixFQUFpQ1YsS0FBRCxJQUFXO0FBQ3ZDNkQsSUFBQUEsU0FBUztBQUNaLEdBRkQ7QUFHQWYsRUFBQUEsTUFBTSxDQUFDclMsWUFBUCxDQUFvQixLQUFwQixFQUEyQm9DLHFCQUFxQixDQUFDc0MsTUFBdEIsQ0FBNkJtUCxHQUF4RDtBQUNBL0csRUFBQUEsTUFBTSxDQUFDZ0gsT0FBUCxDQUFlMVIscUJBQXFCLENBQUMyUixpQkFBckMsRUFBd0RsTixPQUF4RCxDQUNLbU4sUUFBRCxJQUFjO0FBQ1YzQixJQUFBQSxNQUFNLENBQUNyUyxZQUFQLENBQW9CZ1UsUUFBUSxDQUFDLENBQUQsQ0FBNUIsRUFBaUNBLFFBQVEsQ0FBQyxDQUFELENBQXpDO0FBQ0gsR0FITDs7QUFNQSxNQUFJNVIscUJBQXFCLENBQUM2UixjQUF0QixDQUFxQ0MsYUFBekMsRUFBd0Q7QUFDcEQ5QixJQUFBQSw0QkFBNEIsQ0FBQ0MsTUFBRCxFQUFTalEscUJBQXFCLENBQUM2UixjQUEvQixDQUE1QjtBQUNBO0FBQ0g7O0FBRUQxVixFQUFBQSxRQUFRLENBQUMyQyxJQUFULENBQWM4SCxNQUFkLENBQXFCcUosTUFBckI7QUFDSCxDQXpCTCIsInNvdXJjZXMiOlsid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9FcnJvckhhbmRsZXIuanM/ZTY1YSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JDb250aW51ZS5qcz9jNDU0Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvUGF5ZXJEYXRhLmpzPzJhZjEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXIuanM/ODJjZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9NaW5pQ2FydEJvb3RzdGFwLmpzP2Q1NTIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9VcGRhdGVDYXJ0LmpzP2U0MjIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9CdXR0b25zVG9nZ2xlTGlzdGVuZXIuanM/ZTE5MyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRW50aXR5L1Byb2R1Y3QuanM/OWZmZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9TaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlci5qcz9kOWI3Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1NpbmdsZVByb2R1Y3RCb290c3RhcC5qcz83YzE5Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NhcnRCb290c3RhcC5qcz81ZTk0Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9PbkFwcHJvdmVIYW5kbGVyL29uQXBwcm92ZUZvclBheU5vdy5qcz85MzA1Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NoZWNrb3V0QWN0aW9uSGFuZGxlci5qcz84NTE1Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvSGlkaW5nLmpzPzFkMzYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2hlY2tvdXRCb290c3RhcC5qcz9jODU1Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1BheU5vd0Jvb3RzdHJhcC5qcz9kOWY1Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9SZW5kZXJlci5qcz9mYTkzIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvRGNjSW5wdXRGYWN0b3J5LmpzPzJhMmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL0NyZWRpdENhcmRSZW5kZXJlci5qcz8zODdhIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9EYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyLmpzP2VlMGIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL01lc3NhZ2VSZW5kZXJlci5qcz9jZDAyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvU3Bpbm5lci5qcz8xNzA4Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvYnV0dG9uLmpzPzA2MGYiXSwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgRXJyb3JIYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGdlbmVyaWNFcnJvclRleHQpXG4gICAge1xuICAgICAgICB0aGlzLmdlbmVyaWNFcnJvclRleHQgPSBnZW5lcmljRXJyb3JUZXh0O1xuICAgICAgICB0aGlzLndyYXBwZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcud29vY29tbWVyY2Utbm90aWNlcy13cmFwcGVyJyk7XG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcigndWwud29vY29tbWVyY2UtZXJyb3InKTtcbiAgICB9XG5cbiAgICBnZW5lcmljRXJyb3IoKSB7XG4gICAgICAgIGlmICh0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCdwcGNwLXBlcnNpc3QnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlKHRoaXMuZ2VuZXJpY0Vycm9yVGV4dClcbiAgICB9XG5cbiAgICBhcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoZXJyb3JNZXNzYWdlRWxlbWVudClcbiAgICB7XG4gICAgICAgIGlmKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LnJlcGxhY2VXaXRoKGVycm9yTWVzc2FnZUVsZW1lbnQpO1xuICAgIH1cblxuICAgIG1lc3NhZ2UodGV4dCwgcGVyc2lzdCA9IGZhbHNlKVxuICAgIHtcbiAgICAgICAgaWYoISB0eXBlb2YgU3RyaW5nIHx8IHRleHQubGVuZ3RoID09PSAwKXtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQSBuZXcgbWVzc2FnZSB0ZXh0IG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpe1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlTWVzc2FnZXNMaXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGVyc2lzdCkge1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5hZGQoJ3BwY3AtcGVyc2lzdCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5yZW1vdmUoJ3BwY3AtcGVyc2lzdCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG1lc3NhZ2VOb2RlID0gdGhpcy5wcmVwYXJlTWVzc2FnZXNMaXN0SXRlbSh0ZXh0KTtcbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QuYXBwZW5kQ2hpbGQobWVzc2FnZU5vZGUpO1xuXG4gICAgICAgIGpRdWVyeS5zY3JvbGxfdG9fbm90aWNlcyhqUXVlcnkoJy53b29jb21tZXJjZS1ub3RpY2VzLXdyYXBwZXInKSlcbiAgICB9XG5cbiAgICBwcmVwYXJlTWVzc2FnZXNMaXN0KClcbiAgICB7XG4gICAgICAgIGlmKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKXtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXNMaXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndWwnKTtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnd29vY29tbWVyY2UtZXJyb3InKTtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LnNldEF0dHJpYnV0ZSgncm9sZScsICdhbGVydCcpO1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyLmFwcGVuZENoaWxkKHRoaXMubWVzc2FnZXNMaXN0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByZXBhcmVNZXNzYWdlc0xpc3RJdGVtKG1lc3NhZ2UpXG4gICAge1xuICAgICAgICBjb25zdCBsaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7XG4gICAgICAgIGxpLmlubmVySFRNTCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgcmV0dXJuIGxpO1xuICAgIH1cblxuICAgIHNhbml0aXplKHRleHQpXG4gICAge1xuICAgICAgICBjb25zdCB0ZXh0YXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgICAgIHRleHRhcmVhLmlubmVySFRNTCA9IHRleHQ7XG4gICAgICAgIHJldHVybiB0ZXh0YXJlYS52YWx1ZS5yZXBsYWNlKCdFcnJvcjogJywgJycpO1xuICAgIH1cblxuICAgIGNsZWFyKClcbiAgICB7XG4gICAgICAgIGlmICh0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QuaW5uZXJIVE1MID0gJyc7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFcnJvckhhbmRsZXI7XG4iLCJjb25zdCBvbkFwcHJvdmUgPSAoY29udGV4dCwgZXJyb3JIYW5kbGVyKSA9PiB7XG4gICAgcmV0dXJuIChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGNvbnRleHQuY29uZmlnLnJlZGlyZWN0O1xuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiZXhwb3J0IGNvbnN0IHBheWVyRGF0YSA9ICgpID0+IHtcbiAgICBjb25zdCBwYXllciA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5wYXllcjtcbiAgICBpZiAoISBwYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwaG9uZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpIHx8IHR5cGVvZiBwYXllci5waG9uZSAhPT0gJ3VuZGVmaW5lZCcpID9cbiAgICB7XG4gICAgICAgIHBob25lX3R5cGU6XCJIT01FXCIsXG4gICAgICAgICAgICBwaG9uZV9udW1iZXI6e1xuICAgICAgICAgICAgbmF0aW9uYWxfbnVtYmVyIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKS52YWx1ZSA6IHBheWVyLnBob25lLnBob25lX251bWJlci5uYXRpb25hbF9udW1iZXJcbiAgICAgICAgfVxuICAgIH0gOiBudWxsO1xuICAgIGNvbnN0IHBheWVyRGF0YSA9IHtcbiAgICAgICAgZW1haWxfYWRkcmVzczooZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpLnZhbHVlIDogcGF5ZXIuZW1haWxfYWRkcmVzcyxcbiAgICAgICAgbmFtZSA6IHtcbiAgICAgICAgICAgIHN1cm5hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuc3VybmFtZSxcbiAgICAgICAgICAgIGdpdmVuX25hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5naXZlbl9uYW1lXG4gICAgICAgIH0sXG4gICAgICAgIGFkZHJlc3MgOiB7XG4gICAgICAgICAgICBjb3VudHJ5X2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuY291bnRyeV9jb2RlLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8xLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8yLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8xLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMixcbiAgICAgICAgICAgIHBvc3RhbF9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MucG9zdGFsX2NvZGVcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAocGhvbmUpIHtcbiAgICAgICAgcGF5ZXJEYXRhLnBob25lID0gcGhvbmU7XG4gICAgfVxuICAgIHJldHVybiBwYXllckRhdGE7XG59XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENhcnRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOiBvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIpLFxuICAgICAgICAgICAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgTWluaUNhcnRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbignd2NfZnJhZ21lbnRzX2xvYWRlZCB3Y19mcmFnbWVudHNfcmVmcmVzaGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcikgIT09XG4gICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKVxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWluaUNhcnRCb290c3RhcDsiLCJpbXBvcnQgUHJvZHVjdCBmcm9tIFwiLi4vRW50aXR5L1Byb2R1Y3RcIjtcbmNsYXNzIFVwZGF0ZUNhcnQge1xuXG4gICAgY29uc3RydWN0b3IoZW5kcG9pbnQsIG5vbmNlKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludCA9IGVuZHBvaW50O1xuICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25SZXNvbHZlXG4gICAgICogQHBhcmFtIHtQcm9kdWN0W119IHByb2R1Y3RzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAgICovXG4gICAgdXBkYXRlKG9uUmVzb2x2ZSwgcHJvZHVjdHMpXG4gICAge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZmV0Y2goXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qc29uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gb25SZXNvbHZlKHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVcGRhdGVDYXJ0OyIsIi8qKlxuICogV2hlbiB5b3UgY2FuJ3QgYWRkIHNvbWV0aGluZyB0byB0aGUgY2FydCwgdGhlIFBheVBhbCBidXR0b25zIHNob3VsZCBub3Qgc2hvdy5cbiAqIFRoZXJlZm9yZSB3ZSBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiBhbmQgc2hvdy9oaWRlIHRoZSBidXR0b25zIGFjY29yZGluZ2x5LlxuICovXG5cbmNsYXNzIEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2hvd0NhbGxiYWNrLCBoaWRlQ2FsbGJhY2spXG4gICAge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnNob3dDYWxsYmFjayA9IHNob3dDYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2sgPSBoaWRlQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKVxuICAgIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0geyBhdHRyaWJ1dGVzIDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNob3dDYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgZGlzY29ubmVjdCgpXG4gICAge1xuICAgICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcjsiLCJjbGFzcyBQcm9kdWN0IHtcblxuICAgIGNvbnN0cnVjdG9yKGlkLCBxdWFudGl0eSwgdmFyaWF0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMucXVhbnRpdHkgPSBxdWFudGl0eTtcbiAgICAgICAgdGhpcy52YXJpYXRpb25zID0gdmFyaWF0aW9ucztcbiAgICB9XG5cbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6dGhpcy5pZCxcbiAgICAgICAgICAgIHF1YW50aXR5OnRoaXMucXVhbnRpdHksXG4gICAgICAgICAgICB2YXJpYXRpb25zOnRoaXMudmFyaWF0aW9uc1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0OyIsImltcG9ydCBCdXR0b25zVG9nZ2xlTGlzdGVuZXIgZnJvbSAnLi4vSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lcic7XG5pbXBvcnQgUHJvZHVjdCBmcm9tICcuLi9FbnRpdHkvUHJvZHVjdCc7XG5pbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHVwZGF0ZUNhcnQsXG4gICAgICAgIHNob3dCdXR0b25DYWxsYmFjayxcbiAgICAgICAgaGlkZUJ1dHRvbkNhbGxiYWNrLFxuICAgICAgICBmb3JtRWxlbWVudCxcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhcnQgPSB1cGRhdGVDYXJ0O1xuICAgICAgICB0aGlzLnNob3dCdXR0b25DYWxsYmFjayA9IHNob3dCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2sgPSBoaWRlQnV0dG9uQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnQgPSBmb3JtRWxlbWVudDtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpXG4gICAge1xuXG4gICAgICAgIGlmICggdGhpcy5oYXNWYXJpYXRpb25zKCkgKSB7XG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlX2FkZF90b19jYXJ0X2J1dHRvbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUJ1dHRvbkNhbGxiYWNrXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuaW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiB0aGlzLmNyZWF0ZU9yZGVyKCksXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU9yZGVyKClcbiAgICB7XG4gICAgICAgIHZhciBnZXRQcm9kdWN0cyA9IG51bGw7XG4gICAgICAgIGlmICghIHRoaXMuaXNHcm91cGVkUHJvZHVjdCgpICkge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cImFkZC10by1jYXJ0XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcXR5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25hbWU9XCJxdWFudGl0eVwiXScpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhdGlvbnMgPSB0aGlzLnZhcmlhdGlvbnMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBQcm9kdWN0KGlkLCBxdHksIHZhcmlhdGlvbnMpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFByb2R1Y3RzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwibnVtYmVyXCJdJykuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBlbGVtZW50LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpLm1hdGNoKC9xdWFudGl0eVxcWyhbXFxkXSopXFxdLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50TmFtZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHBhcnNlSW50KGVsZW1lbnROYW1lWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMucHVzaChuZXcgUHJvZHVjdChpZCwgcXVhbnRpdHksIG51bGwpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICBjb25zdCBvblJlc29sdmUgPSAocHVyY2hhc2VfdW5pdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnVwZGF0ZUNhcnQudXBkYXRlKG9uUmVzb2x2ZSwgZ2V0UHJvZHVjdHMoKSk7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU9yZGVyO1xuICAgIH1cblxuICAgIHZhcmlhdGlvbnMoKVxuICAgIHtcblxuICAgICAgICBpZiAoISB0aGlzLmhhc1ZhcmlhdGlvbnMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFsuLi50aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZV49J2F0dHJpYnV0ZV8nXVwiKV0ubWFwKFxuICAgICAgICAgICAgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOmVsZW1lbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ZWxlbWVudC5uYW1lXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICBoYXNWYXJpYXRpb25zKClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygndmFyaWF0aW9uc19mb3JtJyk7XG4gICAgfVxuXG4gICAgaXNHcm91cGVkUHJvZHVjdCgpXG4gICAge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyb3VwZWRfZm9ybScpO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhcnQgZnJvbSBcIi4uL0hlbHBlci9VcGRhdGVDYXJ0XCI7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIgZnJvbSBcIi4uL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXJcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXksXG4gICAgICAgICAgICBuZXcgVXBkYXRlQ2FydChcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5ub25jZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgbGV0IHByaWNlVGV4dCA9IFwiMFwiO1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlSW50KHByaWNlVGV4dC5yZXBsYWNlKC8oW15cXGQsXFwuXFxzXSopL2csICcnKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXJXaXRoQW1vdW50KGFtb3VudClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JyksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXA7IiwiaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuXG5jbGFzcyBDYXJ0Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscyB1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0Qm9vdHN0cmFwO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICBzcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIGVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmNvZGUgPT09IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbnMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhY3Rpb25zLnJlc3RhcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwbGFjZV9vcmRlcicpLmNsaWNrKClcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENoZWNrb3V0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMuc3Bpbm5lcjtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IHRoaXMuZXJyb3JIYW5kbGVyO1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtU2VsZWN0b3IgPSB0aGlzLmNvbmZpZy5jb250ZXh0ID09PSAnY2hlY2tvdXQnID8gJ2Zvcm0uY2hlY2tvdXQnIDogJ2Zvcm0jb3JkZXJfcmV2aWV3JztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSBqUXVlcnkoZm9ybVNlbGVjdG9yKS5zZXJpYWxpemUoKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlYWNjb3VudCA9IGpRdWVyeSgnI2NyZWF0ZWFjY291bnQnKS5pcyhcIjpjaGVja2VkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyX2lkOnRoaXMuY29uZmlnLm9yZGVyX2lkLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOmZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWFjY291bnQ6IGNyZWF0ZWFjY291bnRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vaGFuZGxlIGJvdGggbWVzc2FnZXMgc2VudCBmcm9tIFdvb2NvbW1lcmNlIChkYXRhLm1lc3NhZ2VzKSBhbmQgdGhpcyBwbHVnaW4gKGRhdGEuZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKGRhdGEubWVzc2FnZXMpICE9PSAndW5kZWZpbmVkJyApXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5hcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhkYXRhLm1lc3NhZ2VzLCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJ3VsJylcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3BwY3AtcmVzdW1lLW9yZGVyJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGRhdGEuZGF0YS5wdXJjaGFzZV91bml0c1swXS5jdXN0b21faWQpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVNlbGVjdG9yKS5hcHBlbmQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6b25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyLCB0aGlzLnNwaW5uZXIpLFxuICAgICAgICAgICAgb25DYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QWN0aW9uSGFuZGxlcjtcbiIsImNvbnN0IGdldEVsZW1lbnQgPSAoc2VsZWN0b3JPckVsZW1lbnQpID0+IHtcbiAgICBpZiAodHlwZW9mIHNlbGVjdG9yT3JFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvck9yRWxlbWVudCk7XG4gICAgfVxuICAgIHJldHVybiBzZWxlY3Rvck9yRWxlbWVudDtcbn1cblxuZXhwb3J0IGNvbnN0IGlzVmlzaWJsZSA9IChlbGVtZW50KSA9PiB7XG4gICAgcmV0dXJuICEhKGVsZW1lbnQub2Zmc2V0V2lkdGggfHwgZWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgZWxlbWVudC5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCk7XG59XG5cbmV4cG9ydCBjb25zdCBzZXRWaXNpYmxlID0gKHNlbGVjdG9yT3JFbGVtZW50LCBzaG93LCBpbXBvcnRhbnQgPSBmYWxzZSkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBnZXRFbGVtZW50KHNlbGVjdG9yT3JFbGVtZW50KTtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGVsZW1lbnQuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgnZGlzcGxheScpO1xuXG4gICAgaWYgKCFzaG93KSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPT09ICdub25lJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnZGlzcGxheScsICdub25lJywgaW1wb3J0YW50ID8gJ2ltcG9ydGFudCcgOiAnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA9PT0gJ25vbmUnKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnJlbW92ZVByb3BlcnR5KCdkaXNwbGF5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzdGlsbCBub3QgdmlzaWJsZSAoaWYgc29tZXRoaW5nIGVsc2UgYWRkZWQgZGlzcGxheTogbm9uZSBpbiBDU1MpXG4gICAgICAgIGlmICghaXNWaXNpYmxlKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCdkaXNwbGF5JywgJ2Jsb2NrJyk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5leHBvcnQgY29uc3QgaGlkZSA9IChzZWxlY3Rvck9yRWxlbWVudCwgaW1wb3J0YW50ID0gZmFsc2UpID0+IHtcbiAgICBzZXRWaXNpYmxlKHNlbGVjdG9yT3JFbGVtZW50LCBmYWxzZSwgaW1wb3J0YW50KTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaG93ID0gKHNlbGVjdG9yT3JFbGVtZW50KSA9PiB7XG4gICAgc2V0VmlzaWJsZShzZWxlY3Rvck9yRWxlbWVudCwgdHJ1ZSk7XG59O1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENoZWNrb3V0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NoZWNrb3V0QWN0aW9uSGFuZGxlcic7XG5pbXBvcnQgeyBzZXRWaXNpYmxlIH0gZnJvbSAnLi4vSGVscGVyL0hpZGluZyc7XG5cbmNsYXNzIENoZWNrb3V0Qm9vdHN0YXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcywgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlcztcbiAgICAgICAgdGhpcy5zcGlubmVyID0gc3Bpbm5lcjtcblxuICAgICAgICB0aGlzLnN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciA9ICcjcGxhY2Vfb3JkZXInO1xuXG4gICAgICAgIHRoaXMuYnV0dG9uQ2hhbmdlT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoZWwpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgICAgICAvLyBVbnNlbGVjdCBzYXZlZCBjYXJkLlxuICAgICAgICAvLyBXQyBzYXZlcyBmb3JtIHZhbHVlcywgc28gd2l0aCBvdXIgY3VycmVudCBVSSBpdCB3b3VsZCBiZSBhIGJpdCB3ZWlyZFxuICAgICAgICAvLyBpZiB0aGUgdXNlciBwYWlkIHdpdGggc2F2ZWQsIHRoZW4gYWZ0ZXIgc29tZSB0aW1lIHRyaWVzIHRvIHBheSBhZ2FpbixcbiAgICAgICAgLy8gYnV0IHdhbnRzIHRvIGVudGVyIGEgbmV3IGNhcmQsIGFuZCB0byBkbyB0aGF0IHRoZXkgaGF2ZSB0byBjaG9vc2Ug4oCcU2VsZWN0IHBheW1lbnTigJ0gaW4gdGhlIGxpc3QuXG4gICAgICAgIGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkJykudmFsKGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkIG9wdGlvbjpmaXJzdCcpLnZhbCgpKTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3VwZGF0ZWRfY2hlY2tvdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCBwYXltZW50X21ldGhvZF9zZWxlY3RlZCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50KS5vbignaG9zdGVkX2ZpZWxkc19sb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi5jYW5jZWxfd3JhcHBlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcikgIT09IG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKSAhPT0gbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIgKyAnPmRpdicpKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIgKyAnPmRpdicpLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYWN0aW9uSGFuZGxlciA9IG5ldyBDaGVja291dEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICAgICB0aGlzLnNwaW5uZXJcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsXG4gICAgICAgICAgICBhY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmJ1dHRvbkNoYW5nZU9ic2VydmVyLm9ic2VydmUoXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuc3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yKSxcbiAgICAgICAgICAgIHthdHRyaWJ1dGVzOiB0cnVlfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHVwZGF0ZVVpKCkge1xuICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IHRoaXMuY3VycmVudFBheW1lbnRNZXRob2QoKTtcbiAgICAgICAgY29uc3QgaXNQYXlwYWwgPSBjdXJyZW50UGF5bWVudE1ldGhvZCA9PT0gJ3BwY3AtZ2F0ZXdheSc7XG4gICAgICAgIGNvbnN0IGlzQ2FyZCA9IGN1cnJlbnRQYXltZW50TWV0aG9kID09PSAncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgY29uc3QgaXNTYXZlZENhcmQgPSBpc0NhcmQgJiYgdGhpcy5pc1NhdmVkQ2FyZFNlbGVjdGVkKCk7XG4gICAgICAgIGNvbnN0IGlzTm90T3VyR2F0ZXdheSA9ICFpc1BheXBhbCAmJiAhaXNDYXJkO1xuXG4gICAgICAgIHNldFZpc2libGUodGhpcy5zdGFuZGFyZE9yZGVyQnV0dG9uU2VsZWN0b3IsIGlzTm90T3VyR2F0ZXdheSB8fCBpc1NhdmVkQ2FyZCwgdHJ1ZSk7XG4gICAgICAgIHNldFZpc2libGUodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLCBpc1BheXBhbCk7XG4gICAgICAgIHNldFZpc2libGUodGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIsIGlzUGF5cGFsKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLCBpc0NhcmQgJiYgIWlzU2F2ZWRDYXJkKTtcblxuICAgICAgICBpZiAoaXNQYXlwYWwpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNDYXJkKSB7XG4gICAgICAgICAgICBpZiAoaXNTYXZlZENhcmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgZmFsc2UpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxuXG4gICAgY3VycmVudFBheW1lbnRNZXRob2QoKSB7XG4gICAgICAgIHJldHVybiBqUXVlcnkoJ2lucHV0W25hbWU9XCJwYXltZW50X21ldGhvZFwiXTpjaGVja2VkJykudmFsKCk7XG4gICAgfVxuXG4gICAgaXNTYXZlZENhcmRTZWxlY3RlZCgpIHtcbiAgICAgICAgY29uc3Qgc2F2ZWRDYXJkTGlzdCA9IGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkJyk7XG4gICAgICAgIHJldHVybiBzYXZlZENhcmRMaXN0Lmxlbmd0aCAmJiBzYXZlZENhcmRMaXN0LnZhbCgpICE9PSAnJztcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0Qm9vdHN0YXBcbiIsImltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vQ2hlY2tvdXRCb290c3RhcCdcblxuY2xhc3MgUGF5Tm93Qm9vdHN0cmFwIGV4dGVuZHMgQ2hlY2tvdXRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIsIG1lc3NhZ2VzLCBzcGlubmVyKSB7XG4gICAgICAgIHN1cGVyKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcywgc3Bpbm5lcilcbiAgICB9XG5cbiAgICB1cGRhdGVVaSgpIHtcbiAgICAgICAgY29uc3QgdXJsUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKVxuICAgICAgICBpZiAodXJsUGFyYW1zLmhhcygnY2hhbmdlX3BheW1lbnRfbWV0aG9kJykpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgc3VwZXIudXBkYXRlVWkoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBheU5vd0Jvb3RzdHJhcDtcbiIsImNsYXNzIFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihjcmVkaXRDYXJkUmVuZGVyZXIsIGRlZmF1bHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIgPSBjcmVkaXRDYXJkUmVuZGVyZXI7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICB0aGlzLnJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLnJlbmRlcihob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICB9XG5cbiAgICByZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSB8fCB0aGlzLmlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHx8ICd1bmRlZmluZWQnID09PSB0eXBlb2YgcGF5cGFsLkJ1dHRvbnMgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdHlsZSA9IHdyYXBwZXIgPT09IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ud3JhcHBlciA/IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24uc3R5bGUgOiB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLm1pbmlfY2FydF9zdHlsZTtcbiAgICAgICAgcGF5cGFsLkJ1dHRvbnMoe1xuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAuLi5jb250ZXh0Q29uZmlnLFxuICAgICAgICB9KS5yZW5kZXIod3JhcHBlcik7XG4gICAgfVxuXG4gICAgaXNBbHJlYWR5UmVuZGVyZWQod3JhcHBlcikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5oYXNDaGlsZE5vZGVzKCk7XG4gICAgfVxuXG4gICAgaGlkZUJ1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHNob3dCdXR0b25zKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgICAgIGlmICghIGRvbUVsZW1lbnQgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZG9tRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmRpc2FibGVGaWVsZHMoKTtcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5lbmFibGVGaWVsZHMoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlcmVyO1xuIiwiY29uc3QgZGNjSW5wdXRGYWN0b3J5ID0gKG9yaWdpbmFsKSA9PiB7XG4gICAgY29uc3Qgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUob3JpZ2luYWwpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2lkJywgb3JpZ2luYWwuaWQpO1xuICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzKS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICBpZiAoISBzdHlsZXNbcHJvcF0gfHwgISBpc05hTihwcm9wKSApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBuZXdFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KHByb3AsJycgKyBzdHlsZXNbcHJvcF0pO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBkY2NJbnB1dEZhY3Rvcnk7IiwiaW1wb3J0IGRjY0lucHV0RmFjdG9yeSBmcm9tIFwiLi4vSGVscGVyL0RjY0lucHV0RmFjdG9yeVwiO1xuXG5jbGFzcyBDcmVkaXRDYXJkUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoZGVmYXVsdENvbmZpZywgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmNvbnRleHQgIT09ICdjaGVja291dCdcbiAgICAgICAgICAgICAgICAmJiB0aGlzLmRlZmF1bHRDb25maWcuY29udGV4dCAhPT0gJ3BheS1ub3cnXG4gICAgICAgICAgICApXG4gICAgICAgICAgICB8fCB3cmFwcGVyID09PSBudWxsXG4gICAgICAgICAgICB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpID09PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYXlwYWwuSG9zdGVkRmllbGRzID09PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgfHwgISBwYXlwYWwuSG9zdGVkRmllbGRzLmlzRWxpZ2libGUoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZXJFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKTtcbiAgICAgICAgICAgIHdyYXBwZXJFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQod3JhcHBlckVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS50ZWFyZG93bigpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmVycm9yKGBIb3N0ZWQgZmllbGRzIHRlYXJkb3duIGVycm9yOiAke2Vycn1gKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBnYXRlV2F5Qm94ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBheW1lbnRfYm94LnBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpO1xuICAgICAgICBjb25zdCBvbGREaXNwbGF5U3R5bGUgPSBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXk7XG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgICAgY29uc3QgaGlkZURjY0dhdGV3YXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1oaWRlLWRjYycpO1xuICAgICAgICBpZiAoaGlkZURjY0dhdGV3YXkpIHtcbiAgICAgICAgICAgIGhpZGVEY2NHYXRld2F5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaGlkZURjY0dhdGV3YXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlckZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpO1xuXG4gICAgICAgIGNvbnN0IHN0eWxlc1JhdyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNhcmROdW1iZXJGaWVsZCk7XG4gICAgICAgIGxldCBzdHlsZXMgPSB7fTtcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzdHlsZXNSYXcpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgICAgICBpZiAoISBzdHlsZXNSYXdbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHlsZXNbcHJvcF0gPSAnJyArIHN0eWxlc1Jhd1twcm9wXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlciA9IGRjY0lucHV0RmFjdG9yeShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBjYXJkTnVtYmVyRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZE51bWJlciwgY2FyZE51bWJlckZpZWxkKTtcblxuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5RmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5Jyk7XG4gICAgICAgIGNvbnN0IGNhcmRFeHBpcnkgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZEV4cGlyeUZpZWxkKTtcbiAgICAgICAgY2FyZEV4cGlyeUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRFeHBpcnksIGNhcmRFeHBpcnlGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZENvZGVGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKTtcbiAgICAgICAgY29uc3QgY2FyZENvZGUgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZENvZGVGaWVsZCk7XG4gICAgICAgIGNhcmRDb2RlRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZENvZGUsIGNhcmRDb2RlRmllbGQpO1xuXG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9IG9sZERpc3BsYXlTdHlsZTtcblxuICAgICAgICBjb25zdCBmb3JtV3JhcHBlciA9ICcucGF5bWVudF9ib3ggcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHRcbiAgICAgICAgICAgICYmIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0JylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5cGFsLkhvc3RlZEZpZWxkcy5yZW5kZXIoe1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IGNvbnRleHRDb25maWcuY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBzdHlsZXM6IHtcbiAgICAgICAgICAgICAgICAnaW5wdXQnOiBzdHlsZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICAgICAgICBudW1iZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jcmVkaXRfY2FyZF9udW1iZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjdnY6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jdnYsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBleHBpcmF0aW9uRGF0ZToge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLm1tX3l5LFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkudGhlbihob3N0ZWRGaWVsZHMgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJob3N0ZWRfZmllbGRzX2xvYWRlZFwiKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IGhvc3RlZEZpZWxkcztcblxuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdpbnB1dFN1Ym1pdFJlcXVlc3QnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ2NhcmRUeXBlQ2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCAhIGV2ZW50LmNhcmRzLmxlbmd0aCApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZENhcmRzID0gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMudmFsaWRfY2FyZHM7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSB2YWxpZENhcmRzLmluZGV4T2YoZXZlbnQuY2FyZHNbMF0udHlwZSkgIT09IC0xO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbigndmFsaWRpdHlDaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtVmFsaWQgPSBPYmplY3Qua2V5cyhldmVudC5maWVsZHMpLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmZpZWxkc1trZXldLmlzVmFsaWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZvcm1WYWxpZDtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5mb3JtU3VibWlzc2lvblN1YnNjcmliZWQpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIgKyAnIGJ1dHRvbicpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdWJtaXQoY29udGV4dENvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2xhYmVsW2Zvcj1wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJdJykuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgIH1cblxuICAgIGRpc2FibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmFibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc3VibWl0KGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5zcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZm9ybVZhbGlkICYmIHRoaXMuY2FyZFZhbGlkKSB7XG4gICAgICAgICAgICBjb25zdCBzYXZlX2NhcmQgPSB0aGlzLmRlZmF1bHRDb25maWcuc2F2ZV9jYXJkID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICAgICAgbGV0IHZhdWx0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKSA/XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5jaGVja2VkIDogc2F2ZV9jYXJkO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbmZpZy5lbmZvcmNlX3ZhdWx0KSB7XG4gICAgICAgICAgICAgICAgdmF1bHQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY29udGluZ2VuY3kgPSB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5jb250aW5nZW5jeTtcbiAgICAgICAgICAgIGNvbnN0IGhvc3RlZEZpZWxkc0RhdGEgPSB7XG4gICAgICAgICAgICAgICAgdmF1bHQ6IHZhdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGNvbnRpbmdlbmN5ICE9PSAnTk9fM0RfU0VDVVJFJykge1xuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY29udGluZ2VuY2llcyA9IFtjb250aW5nZW5jeV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmRlZmF1bHRDb25maWcucGF5ZXIpIHtcbiAgICAgICAgICAgICAgICBob3N0ZWRGaWVsZHNEYXRhLmNhcmRob2xkZXJOYW1lID0gdGhpcy5kZWZhdWx0Q29uZmlnLnBheWVyLm5hbWUuZ2l2ZW5fbmFtZSArICcgJyArIHRoaXMuZGVmYXVsdENvbmZpZy5wYXllci5uYW1lLnN1cm5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWhvc3RlZEZpZWxkc0RhdGEuY2FyZGhvbGRlck5hbWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaXJzdE5hbWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZ19maXJzdF9uYW1lJykgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZ19maXJzdF9uYW1lJykudmFsdWUgOiAnJztcbiAgICAgICAgICAgICAgICBjb25zdCBsYXN0TmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2xhc3RfbmFtZScpID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JpbGxpbmdfbGFzdF9uYW1lJykudmFsdWUgOiAnJztcblxuICAgICAgICAgICAgICAgIGlmICghZmlyc3ROYW1lIHx8ICFsYXN0TmFtZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5tZXNzYWdlKHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jYXJkaG9sZGVyX25hbWVfcmVxdWlyZWQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jYXJkaG9sZGVyTmFtZSA9IGZpcnN0TmFtZSArICcgJyArIGxhc3ROYW1lO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zdWJtaXQoaG9zdGVkRmllbGRzRGF0YSkudGhlbigocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgIHBheWxvYWQub3JkZXJJRCA9IHBheWxvYWQub3JkZXJJZDtcbiAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0Q29uZmlnLm9uQXBwcm92ZShwYXlsb2FkKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gISB0aGlzLmNhcmRWYWxpZCA/IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jYXJkX25vdF9zdXBwb3J0ZWQgOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuZmllbGRzX25vdF92YWxpZDtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBDcmVkaXRDYXJkUmVuZGVyZXI7XG4iLCJjb25zdCBzdG9yYWdlS2V5ID0gJ3BwY3AtZGF0YS1jbGllbnQtaWQnO1xuXG5jb25zdCB2YWxpZGF0ZVRva2VuID0gKHRva2VuLCB1c2VyKSA9PiB7XG4gICAgaWYgKCEgdG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodG9rZW4udXNlciAhPT0gdXNlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgY29uc3QgaXNFeHBpcmVkID0gY3VycmVudFRpbWUgPj0gdG9rZW4uZXhwaXJhdGlvbiAqIDEwMDA7XG4gICAgcmV0dXJuICEgaXNFeHBpcmVkO1xufVxuXG5jb25zdCBzdG9yZWRUb2tlbkZvclVzZXIgPSAodXNlcikgPT4ge1xuICAgIGNvbnN0IHRva2VuID0gSlNPTi5wYXJzZShzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHN0b3JhZ2VLZXkpKTtcbiAgICBpZiAodmFsaWRhdGVUb2tlbih0b2tlbiwgdXNlcikpIHtcbiAgICAgICAgcmV0dXJuIHRva2VuLnRva2VuO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuY29uc3Qgc3RvcmVUb2tlbiA9ICh0b2tlbikgPT4ge1xuICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oc3RvcmFnZUtleSwgSlNPTi5zdHJpbmdpZnkodG9rZW4pKTtcbn1cblxuY29uc3QgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciA9IChzY3JpcHQsIGNvbmZpZykgPT4ge1xuICAgIGZldGNoKGNvbmZpZy5lbmRwb2ludCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgbm9uY2U6IGNvbmZpZy5ub25jZVxuICAgICAgICB9KVxuICAgIH0pLnRoZW4oKHJlcyk9PntcbiAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgY29uc3QgaXNWYWxpZCA9IHZhbGlkYXRlVG9rZW4oZGF0YSwgY29uZmlnLnVzZXIpO1xuICAgICAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdG9yZVRva2VuKGRhdGEpO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdkYXRhLWNsaWVudC10b2tlbicsIGRhdGEudG9rZW4pO1xuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChzY3JpcHQpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyO1xuIiwiY2xhc3MgTWVzc2FnZVJlbmRlcmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQ6IHRoaXMuY29uZmlnLmFtb3VudCxcbiAgICAgICAgICAgIHBsYWNlbWVudDogdGhpcy5jb25maWcucGxhY2VtZW50LFxuICAgICAgICAgICAgc3R5bGU6IHRoaXMuY29uZmlnLnN0eWxlXG4gICAgICAgIH0pLnJlbmRlcih0aGlzLmNvbmZpZy53cmFwcGVyKTtcbiAgICB9XG5cbiAgICByZW5kZXJXaXRoQW1vdW50KGFtb3VudCkge1xuXG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5ld1dyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgbmV3V3JhcHBlci5zZXRBdHRyaWJ1dGUoJ2lkJywgdGhpcy5jb25maWcud3JhcHBlci5yZXBsYWNlKCcjJywgJycpKTtcblxuICAgICAgICBjb25zdCBzaWJsaW5nID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5uZXh0U2libGluZztcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpO1xuICAgICAgICBzaWJsaW5nLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKG5ld1dyYXBwZXIsIHNpYmxpbmcpO1xuICAgICAgICBwYXlwYWwuTWVzc2FnZXMoe1xuICAgICAgICAgICAgYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcblxuICAgICAgICBpZiAodHlwZW9mIHBheXBhbC5NZXNzYWdlcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHRoaXMuY29uZmlnLndyYXBwZXIgPT09ICd1bmRlZmluZWQnICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBNZXNzYWdlUmVuZGVyZXI7IiwiY2xhc3MgU3Bpbm5lciB7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy50YXJnZXQgPSAnZm9ybS53b29jb21tZXJjZS1jaGVja291dCc7XG4gICAgfVxuXG4gICAgc2V0VGFyZ2V0KHRhcmdldCkge1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICB9XG5cbiAgICBibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkuYmxvY2soe1xuICAgICAgICAgICAgbWVzc2FnZTogbnVsbCxcbiAgICAgICAgICAgIG92ZXJsYXlDU1M6IHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAnI2ZmZicsXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC42XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVuYmxvY2soKSB7XG5cbiAgICAgICAgalF1ZXJ5KCB0aGlzLnRhcmdldCApLnVuYmxvY2soKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNwaW5uZXI7XG4iLCJpbXBvcnQgTWluaUNhcnRCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9NaW5pQ2FydEJvb3RzdGFwJztcbmltcG9ydCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvU2luZ2xlUHJvZHVjdEJvb3RzdGFwJztcbmltcG9ydCBDYXJ0Qm9vdHN0cmFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NhcnRCb290c3RhcCc7XG5pbXBvcnQgQ2hlY2tvdXRCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwJztcbmltcG9ydCBQYXlOb3dCb290c3RyYXAgZnJvbSBcIi4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1BheU5vd0Jvb3RzdHJhcFwiO1xuaW1wb3J0IFJlbmRlcmVyIGZyb20gJy4vbW9kdWxlcy9SZW5kZXJlci9SZW5kZXJlcic7XG5pbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4vbW9kdWxlcy9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENyZWRpdENhcmRSZW5kZXJlciBmcm9tIFwiLi9tb2R1bGVzL1JlbmRlcmVyL0NyZWRpdENhcmRSZW5kZXJlclwiO1xuaW1wb3J0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIgZnJvbSBcIi4vbW9kdWxlcy9EYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyXCI7XG5pbXBvcnQgTWVzc2FnZVJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyXCI7XG5pbXBvcnQgU3Bpbm5lciBmcm9tIFwiLi9tb2R1bGVzL0hlbHBlci9TcGlubmVyXCI7XG5cbmNvbnN0IGJvb3RzdHJhcCA9ICgpID0+IHtcbiAgICBjb25zdCBlcnJvckhhbmRsZXIgPSBuZXcgRXJyb3JIYW5kbGVyKFBheVBhbENvbW1lcmNlR2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyk7XG4gICAgY29uc3Qgc3Bpbm5lciA9IG5ldyBTcGlubmVyKCk7XG4gICAgY29uc3QgY3JlZGl0Q2FyZFJlbmRlcmVyID0gbmV3IENyZWRpdENhcmRSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXksIGVycm9ySGFuZGxlciwgc3Bpbm5lcik7XG4gICAgY29uc3QgcmVuZGVyZXIgPSBuZXcgUmVuZGVyZXIoY3JlZGl0Q2FyZFJlbmRlcmVyLCBQYXlQYWxDb21tZXJjZUdhdGV3YXkpO1xuICAgIGNvbnN0IG1lc3NhZ2VSZW5kZXJlciA9IG5ldyBNZXNzYWdlUmVuZGVyZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1lc3NhZ2VzKTtcbiAgICBjb25zdCBjb250ZXh0ID0gUGF5UGFsQ29tbWVyY2VHYXRld2F5LmNvbnRleHQ7XG4gICAgaWYgKGNvbnRleHQgPT09ICdtaW5pLWNhcnQnIHx8IGNvbnRleHQgPT09ICdwcm9kdWN0Jykge1xuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQgPT09ICcxJykge1xuICAgICAgICAgICAgY29uc3QgbWluaUNhcnRCb290c3RyYXAgPSBuZXcgTWluaUNhcnRCb290c3RhcChcbiAgICAgICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICAgICAgcmVuZGVyZXJcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIG1pbmlDYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncHJvZHVjdCcgJiYgUGF5UGFsQ29tbWVyY2VHYXRld2F5LnNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgIGNvbnN0IHNpbmdsZVByb2R1Y3RCb290c3RyYXAgPSBuZXcgU2luZ2xlUHJvZHVjdEJvb3RzdGFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICk7XG5cbiAgICAgICAgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdjYXJ0Jykge1xuICAgICAgICBjb25zdCBjYXJ0Qm9vdHN0cmFwID0gbmV3IENhcnRCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBjYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBjb25zdCBjaGVja291dEJvb3RzdGFwID0gbmV3IENoZWNrb3V0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcblxuICAgICAgICBjaGVja291dEJvb3RzdGFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ3BheS1ub3cnICkge1xuICAgICAgICBjb25zdCBwYXlOb3dCb290c3RyYXAgPSBuZXcgUGF5Tm93Qm9vdHN0cmFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICAgICBzcGlubmVyXG4gICAgICAgICk7XG4gICAgICAgIHBheU5vd0Jvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgIT09ICdjaGVja291dCcpIHtcbiAgICAgICAgbWVzc2FnZVJlbmRlcmVyLnJlbmRlcigpO1xuICAgIH1cbn07XG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICdET01Db250ZW50TG9hZGVkJyxcbiAgICAoKSA9PiB7XG4gICAgICAgIGlmICghdHlwZW9mIChQYXlQYWxDb21tZXJjZUdhdGV3YXkpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdQYXlQYWwgYnV0dG9uIGNvdWxkIG5vdCBiZSBjb25maWd1cmVkLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gICAgICAgIHNjcmlwdC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBib290c3RyYXAoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ3NyYycsIFBheVBhbENvbW1lcmNlR2F0ZXdheS5idXR0b24udXJsKTtcbiAgICAgICAgT2JqZWN0LmVudHJpZXMoUGF5UGFsQ29tbWVyY2VHYXRld2F5LnNjcmlwdF9hdHRyaWJ1dGVzKS5mb3JFYWNoKFxuICAgICAgICAgICAgKGtleVZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgc2NyaXB0LnNldEF0dHJpYnV0ZShrZXlWYWx1ZVswXSwga2V5VmFsdWVbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQuc2V0X2F0dHJpYnV0ZSkge1xuICAgICAgICAgICAgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlcihzY3JpcHQsIFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChzY3JpcHQpO1xuICAgIH0sXG4pO1xuIl0sIm5hbWVzIjpbIkVycm9ySGFuZGxlciIsImNvbnN0cnVjdG9yIiwiZ2VuZXJpY0Vycm9yVGV4dCIsIndyYXBwZXIiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJtZXNzYWdlc0xpc3QiLCJnZW5lcmljRXJyb3IiLCJjbGFzc0xpc3QiLCJjb250YWlucyIsImNsZWFyIiwibWVzc2FnZSIsImFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudCIsImVycm9yTWVzc2FnZUVsZW1lbnQiLCJwcmVwYXJlTWVzc2FnZXNMaXN0IiwicmVwbGFjZVdpdGgiLCJ0ZXh0IiwicGVyc2lzdCIsIlN0cmluZyIsImxlbmd0aCIsIkVycm9yIiwiYWRkIiwicmVtb3ZlIiwibWVzc2FnZU5vZGUiLCJwcmVwYXJlTWVzc2FnZXNMaXN0SXRlbSIsImFwcGVuZENoaWxkIiwialF1ZXJ5Iiwic2Nyb2xsX3RvX25vdGljZXMiLCJjcmVhdGVFbGVtZW50Iiwic2V0QXR0cmlidXRlIiwibGkiLCJpbm5lckhUTUwiLCJzYW5pdGl6ZSIsInRleHRhcmVhIiwidmFsdWUiLCJyZXBsYWNlIiwib25BcHByb3ZlIiwiY29udGV4dCIsImVycm9ySGFuZGxlciIsImRhdGEiLCJhY3Rpb25zIiwiZmV0Y2giLCJjb25maWciLCJhamF4IiwiYXBwcm92ZV9vcmRlciIsImVuZHBvaW50IiwibWV0aG9kIiwiYm9keSIsIkpTT04iLCJzdHJpbmdpZnkiLCJub25jZSIsIm9yZGVyX2lkIiwib3JkZXJJRCIsInRoZW4iLCJyZXMiLCJqc29uIiwic3VjY2VzcyIsInJlc3RhcnQiLCJjYXRjaCIsImVyciIsImxvY2F0aW9uIiwiaHJlZiIsInJlZGlyZWN0IiwicGF5ZXJEYXRhIiwicGF5ZXIiLCJQYXlQYWxDb21tZXJjZUdhdGV3YXkiLCJwaG9uZSIsInBob25lX3R5cGUiLCJwaG9uZV9udW1iZXIiLCJuYXRpb25hbF9udW1iZXIiLCJlbWFpbF9hZGRyZXNzIiwibmFtZSIsInN1cm5hbWUiLCJnaXZlbl9uYW1lIiwiYWRkcmVzcyIsImNvdW50cnlfY29kZSIsImFkZHJlc3NfbGluZV8xIiwiYWRkcmVzc19saW5lXzIiLCJhZG1pbl9hcmVhXzEiLCJhZG1pbl9hcmVhXzIiLCJwb3N0YWxfY29kZSIsIkNhcnRBY3Rpb25IYW5kbGVyIiwiY29uZmlndXJhdGlvbiIsImNyZWF0ZU9yZGVyIiwiYm5Db2RlIiwiYm5fY29kZXMiLCJjcmVhdGVfb3JkZXIiLCJwdXJjaGFzZV91bml0cyIsImJuX2NvZGUiLCJjb25zb2xlIiwiZXJyb3IiLCJpZCIsIm9uRXJyb3IiLCJNaW5pQ2FydEJvb3RzdGFwIiwiZ2F0ZXdheSIsInJlbmRlcmVyIiwiYWN0aW9uSGFuZGxlciIsImluaXQiLCJsYWJlbHMiLCJnZW5lcmljIiwicmVuZGVyIiwib24iLCJzaG91bGRSZW5kZXIiLCJidXR0b24iLCJtaW5pX2NhcnRfd3JhcHBlciIsImhvc3RlZF9maWVsZHMiLCJQcm9kdWN0IiwiVXBkYXRlQ2FydCIsInVwZGF0ZSIsIm9uUmVzb2x2ZSIsInByb2R1Y3RzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJyZXN1bHQiLCJyZXNvbHZlZCIsIkJ1dHRvbnNUb2dnbGVMaXN0ZW5lciIsImVsZW1lbnQiLCJzaG93Q2FsbGJhY2siLCJoaWRlQ2FsbGJhY2siLCJvYnNlcnZlciIsImF0dHJpYnV0ZXMiLCJjYWxsYmFjayIsIk11dGF0aW9uT2JzZXJ2ZXIiLCJvYnNlcnZlIiwiZGlzY29ubmVjdCIsInF1YW50aXR5IiwidmFyaWF0aW9ucyIsIlNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIiwidXBkYXRlQ2FydCIsInNob3dCdXR0b25DYWxsYmFjayIsImhpZGVCdXR0b25DYWxsYmFjayIsImZvcm1FbGVtZW50IiwiaGFzVmFyaWF0aW9ucyIsImdldFByb2R1Y3RzIiwiaXNHcm91cGVkUHJvZHVjdCIsInF0eSIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJmb3JFYWNoIiwiZWxlbWVudE5hbWUiLCJnZXRBdHRyaWJ1dGUiLCJtYXRjaCIsInBhcnNlSW50IiwicHVzaCIsInByb21pc2UiLCJtYXAiLCJTaW5nbGVQcm9kdWN0Qm9vdHN0YXAiLCJtZXNzYWdlcyIsImhpZGVCdXR0b25zIiwiY2hhbmdlX2NhcnQiLCJzaG93QnV0dG9ucyIsInByaWNlVGV4dCIsImlubmVyVGV4dCIsImFtb3VudCIsInJlbmRlcldpdGhBbW91bnQiLCJDYXJ0Qm9vdHN0cmFwIiwic3Bpbm5lciIsImJsb2NrIiwidW5ibG9jayIsImNvZGUiLCJjbGljayIsIkNoZWNrb3V0QWN0aW9uSGFuZGxlciIsImZvcm1TZWxlY3RvciIsImZvcm1WYWx1ZXMiLCJzZXJpYWxpemUiLCJjcmVhdGVhY2NvdW50IiwiaXMiLCJmb3JtIiwiZG9tUGFyc2VyIiwiRE9NUGFyc2VyIiwicGFyc2VGcm9tU3RyaW5nIiwiaW5wdXQiLCJjdXN0b21faWQiLCJhcHBlbmQiLCJvbkNhbmNlbCIsImdldEVsZW1lbnQiLCJzZWxlY3Rvck9yRWxlbWVudCIsImlzVmlzaWJsZSIsIm9mZnNldFdpZHRoIiwib2Zmc2V0SGVpZ2h0IiwiZ2V0Q2xpZW50UmVjdHMiLCJzZXRWaXNpYmxlIiwic2hvdyIsImltcG9ydGFudCIsImN1cnJlbnRWYWx1ZSIsInN0eWxlIiwiZ2V0UHJvcGVydHlWYWx1ZSIsInNldFByb3BlcnR5IiwicmVtb3ZlUHJvcGVydHkiLCJoaWRlIiwiQ2hlY2tvdXRCb290c3RhcCIsInN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciIsImJ1dHRvbkNoYW5nZU9ic2VydmVyIiwiZWwiLCJ1cGRhdGVVaSIsInZhbCIsImNhbmNlbF93cmFwcGVyIiwiY3VycmVudFBheW1lbnRNZXRob2QiLCJpc1BheXBhbCIsImlzQ2FyZCIsImlzU2F2ZWRDYXJkIiwiaXNTYXZlZENhcmRTZWxlY3RlZCIsImlzTm90T3VyR2F0ZXdheSIsImRpc2FibGVDcmVkaXRDYXJkRmllbGRzIiwiZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcyIsImFkZENsYXNzIiwiYXR0ciIsInJlbW92ZUNsYXNzIiwic2F2ZWRDYXJkTGlzdCIsIlBheU5vd0Jvb3RzdHJhcCIsInVybFBhcmFtcyIsIlVSTFNlYXJjaFBhcmFtcyIsIndpbmRvdyIsInNlYXJjaCIsImhhcyIsIlJlbmRlcmVyIiwiY3JlZGl0Q2FyZFJlbmRlcmVyIiwiZGVmYXVsdENvbmZpZyIsImhvc3RlZEZpZWxkc1dyYXBwZXIiLCJjb250ZXh0Q29uZmlnIiwicmVuZGVyQnV0dG9ucyIsImlzQWxyZWFkeVJlbmRlcmVkIiwicGF5cGFsIiwiQnV0dG9ucyIsIm1pbmlfY2FydF9zdHlsZSIsImhhc0NoaWxkTm9kZXMiLCJkb21FbGVtZW50IiwiZGlzcGxheSIsImRpc2FibGVGaWVsZHMiLCJlbmFibGVGaWVsZHMiLCJkY2NJbnB1dEZhY3RvcnkiLCJvcmlnaW5hbCIsInN0eWxlcyIsImdldENvbXB1dGVkU3R5bGUiLCJuZXdFbGVtZW50IiwiT2JqZWN0IiwidmFsdWVzIiwicHJvcCIsImlzTmFOIiwiQ3JlZGl0Q2FyZFJlbmRlcmVyIiwiY2FyZFZhbGlkIiwiZm9ybVZhbGlkIiwiY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlIiwiZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkIiwiSG9zdGVkRmllbGRzIiwiaXNFbGlnaWJsZSIsIndyYXBwZXJFbGVtZW50IiwicGFyZW50Tm9kZSIsInJlbW92ZUNoaWxkIiwidGVhcmRvd24iLCJnYXRlV2F5Qm94Iiwib2xkRGlzcGxheVN0eWxlIiwiaGlkZURjY0dhdGV3YXkiLCJjYXJkTnVtYmVyRmllbGQiLCJzdHlsZXNSYXciLCJjYXJkTnVtYmVyIiwicmVwbGFjZUNoaWxkIiwiY2FyZEV4cGlyeUZpZWxkIiwiY2FyZEV4cGlyeSIsImNhcmRDb2RlRmllbGQiLCJjYXJkQ29kZSIsImZvcm1XcmFwcGVyIiwiZW5mb3JjZV92YXVsdCIsImNoZWNrZWQiLCJmaWVsZHMiLCJudW1iZXIiLCJzZWxlY3RvciIsInBsYWNlaG9sZGVyIiwiY3JlZGl0X2NhcmRfbnVtYmVyIiwiY3Z2IiwiZXhwaXJhdGlvbkRhdGUiLCJtbV95eSIsImhvc3RlZEZpZWxkcyIsImRpc3BhdGNoRXZlbnQiLCJDdXN0b21FdmVudCIsIl9zdWJtaXQiLCJldmVudCIsImNhcmRzIiwidmFsaWRDYXJkcyIsInZhbGlkX2NhcmRzIiwiaW5kZXhPZiIsInR5cGUiLCJrZXlzIiwiZXZlcnkiLCJrZXkiLCJpc1ZhbGlkIiwiYWRkRXZlbnRMaXN0ZW5lciIsInByZXZlbnREZWZhdWx0IiwiZmllbGQiLCJhdHRyaWJ1dGUiLCJyZW1vdmVBdHRyaWJ1dGUiLCJzYXZlX2NhcmQiLCJ2YXVsdCIsImdldEVsZW1lbnRCeUlkIiwiY29udGluZ2VuY3kiLCJob3N0ZWRGaWVsZHNEYXRhIiwiY29udGluZ2VuY2llcyIsImNhcmRob2xkZXJOYW1lIiwiZmlyc3ROYW1lIiwibGFzdE5hbWUiLCJjYXJkaG9sZGVyX25hbWVfcmVxdWlyZWQiLCJzdWJtaXQiLCJwYXlsb2FkIiwib3JkZXJJZCIsImNhcmRfbm90X3N1cHBvcnRlZCIsImZpZWxkc19ub3RfdmFsaWQiLCJzdG9yYWdlS2V5IiwidmFsaWRhdGVUb2tlbiIsInRva2VuIiwidXNlciIsImN1cnJlbnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJpc0V4cGlyZWQiLCJleHBpcmF0aW9uIiwic3RvcmVkVG9rZW5Gb3JVc2VyIiwicGFyc2UiLCJzZXNzaW9uU3RvcmFnZSIsImdldEl0ZW0iLCJzdG9yZVRva2VuIiwic2V0SXRlbSIsImRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIiLCJzY3JpcHQiLCJNZXNzYWdlUmVuZGVyZXIiLCJNZXNzYWdlcyIsInBsYWNlbWVudCIsIm5ld1dyYXBwZXIiLCJzaWJsaW5nIiwibmV4dFNpYmxpbmciLCJwYXJlbnRFbGVtZW50IiwiaW5zZXJ0QmVmb3JlIiwiU3Bpbm5lciIsInRhcmdldCIsInNldFRhcmdldCIsIm92ZXJsYXlDU1MiLCJiYWNrZ3JvdW5kIiwib3BhY2l0eSIsImJvb3RzdHJhcCIsIm1lc3NhZ2VSZW5kZXJlciIsIm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQiLCJtaW5pQ2FydEJvb3RzdHJhcCIsInNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCIsInNpbmdsZVByb2R1Y3RCb290c3RyYXAiLCJjYXJ0Qm9vdHN0cmFwIiwiY2hlY2tvdXRCb290c3RhcCIsInBheU5vd0Jvb3RzdHJhcCIsInVybCIsImVudHJpZXMiLCJzY3JpcHRfYXR0cmlidXRlcyIsImtleVZhbHVlIiwiZGF0YV9jbGllbnRfaWQiLCJzZXRfYXR0cmlidXRlIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///964\n")}},__webpack_exports__={};__webpack_modules__[964]()})();
|
modules/ppcp-button/resources/css/hosted-fields.scss
CHANGED
@@ -11,3 +11,7 @@
|
|
11 |
.ppcp-credit-card-gateway-form-field-disabled {
|
12 |
opacity: .5 !important;
|
13 |
}
|
|
|
|
|
|
|
|
11 |
.ppcp-credit-card-gateway-form-field-disabled {
|
12 |
opacity: .5 !important;
|
13 |
}
|
14 |
+
|
15 |
+
.ppcp-dcc-order-button {
|
16 |
+
float: right;
|
17 |
+
}
|
modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
import ErrorHandler from '../ErrorHandler';
|
2 |
import CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';
|
|
|
3 |
|
4 |
class CheckoutBootstap {
|
5 |
constructor(gateway, renderer, messages, spinner) {
|
@@ -7,31 +8,38 @@ class CheckoutBootstap {
|
|
7 |
this.renderer = renderer;
|
8 |
this.messages = messages;
|
9 |
this.spinner = spinner;
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
}
|
11 |
|
12 |
init() {
|
13 |
-
|
14 |
this.render();
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
jQuery(document.body).on('updated_checkout', () => {
|
17 |
this.render()
|
18 |
});
|
19 |
|
20 |
-
jQuery(document.body).
|
21 |
-
|
22 |
-
|
23 |
-
this.displayPlaceOrderButtonForSavedCreditCards()
|
24 |
-
|
25 |
-
})
|
26 |
|
27 |
jQuery(document).on('hosted_fields_loaded', () => {
|
28 |
jQuery('#saved-credit-card').on('change', () => {
|
29 |
-
this.
|
30 |
})
|
31 |
});
|
32 |
|
33 |
-
this.
|
34 |
-
this.displayPlaceOrderButtonForSavedCreditCards()
|
35 |
}
|
36 |
|
37 |
shouldRender() {
|
@@ -60,55 +68,35 @@ class CheckoutBootstap {
|
|
60 |
this.gateway.hosted_fields.wrapper,
|
61 |
actionHandler.configuration(),
|
62 |
);
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
64 |
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
|
|
67 |
|
68 |
-
|
69 |
-
|
|
|
|
|
70 |
|
71 |
-
if (
|
72 |
-
this.
|
73 |
-
this.renderer.hideButtons(this.gateway.messages.wrapper);
|
74 |
-
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
75 |
-
jQuery('#place_order').show();
|
76 |
-
}
|
77 |
-
else {
|
78 |
-
jQuery('#place_order').hide();
|
79 |
-
if (currentPaymentMethod === 'ppcp-gateway') {
|
80 |
-
this.renderer.showButtons(this.gateway.button.wrapper);
|
81 |
-
this.renderer.showButtons(this.gateway.messages.wrapper);
|
82 |
-
this.messages.render()
|
83 |
-
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper)
|
84 |
-
}
|
85 |
-
if (currentPaymentMethod === 'ppcp-credit-card-gateway') {
|
86 |
-
this.renderer.hideButtons(this.gateway.button.wrapper)
|
87 |
-
this.renderer.hideButtons(this.gateway.messages.wrapper)
|
88 |
-
this.renderer.showButtons(this.gateway.hosted_fields.wrapper)
|
89 |
-
}
|
90 |
-
}
|
91 |
-
}
|
92 |
-
|
93 |
-
displayPlaceOrderButtonForSavedCreditCards() {
|
94 |
-
const currentPaymentMethod = jQuery(
|
95 |
-
'input[name="payment_method"]:checked').val();
|
96 |
-
if (currentPaymentMethod !== 'ppcp-credit-card-gateway') {
|
97 |
-
return;
|
98 |
}
|
99 |
|
100 |
-
if (
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
} else {
|
107 |
-
jQuery('#place_order').hide()
|
108 |
-
this.renderer.hideButtons(this.gateway.button.wrapper)
|
109 |
-
this.renderer.hideButtons(this.gateway.messages.wrapper)
|
110 |
-
this.renderer.showButtons(this.gateway.hosted_fields.wrapper)
|
111 |
-
this.enableCreditCardFields()
|
112 |
}
|
113 |
}
|
114 |
|
@@ -137,6 +125,15 @@ class CheckoutBootstap {
|
|
137 |
jQuery('#ppcp-credit-card-vault').attr("disabled", false)
|
138 |
this.renderer.enableCreditCardFields()
|
139 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
}
|
141 |
|
142 |
export default CheckoutBootstap
|
1 |
import ErrorHandler from '../ErrorHandler';
|
2 |
import CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';
|
3 |
+
import { setVisible } from '../Helper/Hiding';
|
4 |
|
5 |
class CheckoutBootstap {
|
6 |
constructor(gateway, renderer, messages, spinner) {
|
8 |
this.renderer = renderer;
|
9 |
this.messages = messages;
|
10 |
this.spinner = spinner;
|
11 |
+
|
12 |
+
this.standardOrderButtonSelector = '#place_order';
|
13 |
+
|
14 |
+
this.buttonChangeObserver = new MutationObserver((el) => {
|
15 |
+
this.updateUi();
|
16 |
+
});
|
17 |
}
|
18 |
|
19 |
init() {
|
|
|
20 |
this.render();
|
21 |
|
22 |
+
// Unselect saved card.
|
23 |
+
// WC saves form values, so with our current UI it would be a bit weird
|
24 |
+
// if the user paid with saved, then after some time tries to pay again,
|
25 |
+
// but wants to enter a new card, and to do that they have to choose “Select payment” in the list.
|
26 |
+
jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());
|
27 |
+
|
28 |
jQuery(document.body).on('updated_checkout', () => {
|
29 |
this.render()
|
30 |
});
|
31 |
|
32 |
+
jQuery(document.body).on('updated_checkout payment_method_selected', () => {
|
33 |
+
this.updateUi();
|
34 |
+
});
|
|
|
|
|
|
|
35 |
|
36 |
jQuery(document).on('hosted_fields_loaded', () => {
|
37 |
jQuery('#saved-credit-card').on('change', () => {
|
38 |
+
this.updateUi();
|
39 |
})
|
40 |
});
|
41 |
|
42 |
+
this.updateUi();
|
|
|
43 |
}
|
44 |
|
45 |
shouldRender() {
|
68 |
this.gateway.hosted_fields.wrapper,
|
69 |
actionHandler.configuration(),
|
70 |
);
|
71 |
+
|
72 |
+
this.buttonChangeObserver.observe(
|
73 |
+
document.querySelector(this.standardOrderButtonSelector),
|
74 |
+
{attributes: true}
|
75 |
+
);
|
76 |
}
|
77 |
|
78 |
+
updateUi() {
|
79 |
+
const currentPaymentMethod = this.currentPaymentMethod();
|
80 |
+
const isPaypal = currentPaymentMethod === 'ppcp-gateway';
|
81 |
+
const isCard = currentPaymentMethod === 'ppcp-credit-card-gateway';
|
82 |
+
const isSavedCard = isCard && this.isSavedCardSelected();
|
83 |
+
const isNotOurGateway = !isPaypal && !isCard;
|
84 |
|
85 |
+
setVisible(this.standardOrderButtonSelector, isNotOurGateway || isSavedCard, true);
|
86 |
+
setVisible(this.gateway.button.wrapper, isPaypal);
|
87 |
+
setVisible(this.gateway.messages.wrapper, isPaypal);
|
88 |
+
setVisible(this.gateway.hosted_fields.wrapper, isCard && !isSavedCard);
|
89 |
|
90 |
+
if (isPaypal) {
|
91 |
+
this.messages.render();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
93 |
|
94 |
+
if (isCard) {
|
95 |
+
if (isSavedCard) {
|
96 |
+
this.disableCreditCardFields();
|
97 |
+
} else {
|
98 |
+
this.enableCreditCardFields();
|
99 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
}
|
101 |
}
|
102 |
|
125 |
jQuery('#ppcp-credit-card-vault').attr("disabled", false)
|
126 |
this.renderer.enableCreditCardFields()
|
127 |
}
|
128 |
+
|
129 |
+
currentPaymentMethod() {
|
130 |
+
return jQuery('input[name="payment_method"]:checked').val();
|
131 |
+
}
|
132 |
+
|
133 |
+
isSavedCardSelected() {
|
134 |
+
const savedCardList = jQuery('#saved-credit-card');
|
135 |
+
return savedCardList.length && savedCardList.val() !== '';
|
136 |
+
}
|
137 |
}
|
138 |
|
139 |
export default CheckoutBootstap
|
modules/ppcp-button/resources/js/modules/ContextBootstrap/PayNowBootstrap.js
CHANGED
@@ -1,86 +1,17 @@
|
|
1 |
-
import
|
2 |
-
import CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';
|
3 |
|
4 |
-
class PayNowBootstrap {
|
5 |
constructor(gateway, renderer, messages, spinner) {
|
6 |
-
|
7 |
-
this.renderer = renderer;
|
8 |
-
this.messages = messages;
|
9 |
-
this.spinner = spinner;
|
10 |
}
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
this.render();
|
15 |
-
|
16 |
-
jQuery(document.body).on('updated_checkout', () => {
|
17 |
-
this.render();
|
18 |
-
});
|
19 |
-
|
20 |
-
jQuery(document.body).
|
21 |
-
on('updated_checkout payment_method_selected', () => {
|
22 |
-
this.switchBetweenPayPalandOrderButton();
|
23 |
-
});
|
24 |
-
this.switchBetweenPayPalandOrderButton();
|
25 |
-
}
|
26 |
-
|
27 |
-
shouldRender() {
|
28 |
-
if (document.querySelector(this.gateway.button.cancel_wrapper)) {
|
29 |
-
return false;
|
30 |
-
}
|
31 |
-
|
32 |
-
return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;
|
33 |
-
}
|
34 |
-
|
35 |
-
render() {
|
36 |
-
if (!this.shouldRender()) {
|
37 |
-
return;
|
38 |
-
}
|
39 |
-
if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {
|
40 |
-
document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');
|
41 |
-
}
|
42 |
-
const actionHandler = new CheckoutActionHandler(
|
43 |
-
PayPalCommerceGateway,
|
44 |
-
new ErrorHandler(this.gateway.labels.error.generic),
|
45 |
-
this.spinner
|
46 |
-
);
|
47 |
-
|
48 |
-
this.renderer.render(
|
49 |
-
this.gateway.button.wrapper,
|
50 |
-
this.gateway.hosted_fields.wrapper,
|
51 |
-
actionHandler.configuration(),
|
52 |
-
);
|
53 |
-
}
|
54 |
-
|
55 |
-
switchBetweenPayPalandOrderButton() {
|
56 |
const urlParams = new URLSearchParams(window.location.search)
|
57 |
if (urlParams.has('change_payment_method')) {
|
58 |
return
|
59 |
}
|
60 |
|
61 |
-
|
62 |
-
'input[name="payment_method"]:checked').val();
|
63 |
-
|
64 |
-
if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {
|
65 |
-
this.renderer.hideButtons(this.gateway.button.wrapper);
|
66 |
-
this.renderer.hideButtons(this.gateway.messages.wrapper);
|
67 |
-
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
68 |
-
jQuery('#place_order').show();
|
69 |
-
}
|
70 |
-
else {
|
71 |
-
jQuery('#place_order').hide();
|
72 |
-
if (currentPaymentMethod === 'ppcp-gateway') {
|
73 |
-
this.renderer.showButtons(this.gateway.button.wrapper);
|
74 |
-
this.renderer.showButtons(this.gateway.messages.wrapper);
|
75 |
-
this.messages.render();
|
76 |
-
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
77 |
-
}
|
78 |
-
if (currentPaymentMethod === 'ppcp-credit-card-gateway') {
|
79 |
-
this.renderer.hideButtons(this.gateway.button.wrapper);
|
80 |
-
this.renderer.hideButtons(this.gateway.messages.wrapper);
|
81 |
-
this.renderer.showButtons(this.gateway.hosted_fields.wrapper);
|
82 |
-
}
|
83 |
-
}
|
84 |
}
|
85 |
}
|
86 |
|
1 |
+
import CheckoutBootstap from './CheckoutBootstap'
|
|
|
2 |
|
3 |
+
class PayNowBootstrap extends CheckoutBootstap {
|
4 |
constructor(gateway, renderer, messages, spinner) {
|
5 |
+
super(gateway, renderer, messages, spinner)
|
|
|
|
|
|
|
6 |
}
|
7 |
|
8 |
+
updateUi() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
const urlParams = new URLSearchParams(window.location.search)
|
10 |
if (urlParams.has('change_payment_method')) {
|
11 |
return
|
12 |
}
|
13 |
|
14 |
+
super.updateUi();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
}
|
16 |
}
|
17 |
|
modules/ppcp-button/resources/js/modules/ErrorHandler.js
CHANGED
@@ -73,11 +73,11 @@ class ErrorHandler {
|
|
73 |
|
74 |
clear()
|
75 |
{
|
76 |
-
if (
|
77 |
return;
|
78 |
}
|
79 |
-
|
80 |
-
this.
|
81 |
}
|
82 |
}
|
83 |
|
73 |
|
74 |
clear()
|
75 |
{
|
76 |
+
if (this.messagesList === null) {
|
77 |
return;
|
78 |
}
|
79 |
+
|
80 |
+
this.messagesList.innerHTML = '';
|
81 |
}
|
82 |
}
|
83 |
|
modules/ppcp-button/resources/js/modules/Helper/Hiding.js
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const getElement = (selectorOrElement) => {
|
2 |
+
if (typeof selectorOrElement === 'string') {
|
3 |
+
return document.querySelector(selectorOrElement);
|
4 |
+
}
|
5 |
+
return selectorOrElement;
|
6 |
+
}
|
7 |
+
|
8 |
+
export const isVisible = (element) => {
|
9 |
+
return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
|
10 |
+
}
|
11 |
+
|
12 |
+
export const setVisible = (selectorOrElement, show, important = false) => {
|
13 |
+
const element = getElement(selectorOrElement);
|
14 |
+
if (!element) {
|
15 |
+
return;
|
16 |
+
}
|
17 |
+
|
18 |
+
const currentValue = element.style.getPropertyValue('display');
|
19 |
+
|
20 |
+
if (!show) {
|
21 |
+
if (currentValue === 'none') {
|
22 |
+
return;
|
23 |
+
}
|
24 |
+
|
25 |
+
element.style.setProperty('display', 'none', important ? 'important' : '');
|
26 |
+
} else {
|
27 |
+
if (currentValue === 'none') {
|
28 |
+
element.style.removeProperty('display');
|
29 |
+
}
|
30 |
+
|
31 |
+
// still not visible (if something else added display: none in CSS)
|
32 |
+
if (!isVisible(element)) {
|
33 |
+
element.style.setProperty('display', 'block');
|
34 |
+
}
|
35 |
+
}
|
36 |
+
};
|
37 |
+
|
38 |
+
export const hide = (selectorOrElement, important = false) => {
|
39 |
+
setVisible(selectorOrElement, false, important);
|
40 |
+
};
|
41 |
+
|
42 |
+
export const show = (selectorOrElement) => {
|
43 |
+
setVisible(selectorOrElement, true);
|
44 |
+
};
|
modules/ppcp-button/resources/js/modules/OnApproveHandler/onApproveForPayNow.js
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
const onApprove = (context, errorHandler, spinner) => {
|
2 |
return (data, actions) => {
|
3 |
spinner.block();
|
|
|
|
|
4 |
return fetch(context.config.ajax.approve_order.endpoint, {
|
5 |
method: 'POST',
|
6 |
body: JSON.stringify({
|
1 |
const onApprove = (context, errorHandler, spinner) => {
|
2 |
return (data, actions) => {
|
3 |
spinner.block();
|
4 |
+
errorHandler.clear();
|
5 |
+
|
6 |
return fetch(context.config.ajax.approve_order.endpoint, {
|
7 |
method: 'POST',
|
8 |
body: JSON.stringify({
|
modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js
CHANGED
@@ -194,6 +194,23 @@ class CreditCardRenderer {
|
|
194 |
if (contingency !== 'NO_3D_SECURE') {
|
195 |
hostedFieldsData.contingencies = [contingency];
|
196 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
this.currentHostedFieldsInstance.submit(hostedFieldsData).then((payload) => {
|
198 |
payload.orderID = payload.orderId;
|
199 |
this.spinner.unblock();
|
194 |
if (contingency !== 'NO_3D_SECURE') {
|
195 |
hostedFieldsData.contingencies = [contingency];
|
196 |
}
|
197 |
+
|
198 |
+
if (this.defaultConfig.payer) {
|
199 |
+
hostedFieldsData.cardholderName = this.defaultConfig.payer.name.given_name + ' ' + this.defaultConfig.payer.name.surname;
|
200 |
+
}
|
201 |
+
if (!hostedFieldsData.cardholderName) {
|
202 |
+
const firstName = document.getElementById('billing_first_name') ? document.getElementById('billing_first_name').value : '';
|
203 |
+
const lastName = document.getElementById('billing_last_name') ? document.getElementById('billing_last_name').value : '';
|
204 |
+
|
205 |
+
if (!firstName || !lastName) {
|
206 |
+
this.spinner.unblock();
|
207 |
+
this.errorHandler.message(this.defaultConfig.hosted_fields.labels.cardholder_name_required);
|
208 |
+
return;
|
209 |
+
}
|
210 |
+
|
211 |
+
hostedFieldsData.cardholderName = firstName + ' ' + lastName;
|
212 |
+
}
|
213 |
+
|
214 |
this.currentHostedFieldsInstance.submit(hostedFieldsData).then((payload) => {
|
215 |
payload.orderID = payload.orderId;
|
216 |
this.spinner.unblock();
|
modules/ppcp-button/services.php
CHANGED
@@ -70,6 +70,7 @@ return array(
|
|
70 |
$environment = $container->get( 'onboarding.environment' );
|
71 |
$payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
|
72 |
$settings_status = $container->get( 'wcgateway.settings.status' );
|
|
|
73 |
return new SmartButton(
|
74 |
$container->get( 'button.url' ),
|
75 |
$container->get( 'session.handler' ),
|
@@ -82,7 +83,8 @@ return array(
|
|
82 |
$messages_apply,
|
83 |
$environment,
|
84 |
$payment_token_repository,
|
85 |
-
$settings_status
|
|
|
86 |
);
|
87 |
},
|
88 |
'button.url' => static function ( ContainerInterface $container ): string {
|
@@ -171,7 +173,9 @@ return array(
|
|
171 |
return new ThreeDSecure( $logger );
|
172 |
},
|
173 |
'button.helper.messages-apply' => static function ( ContainerInterface $container ): MessagesApply {
|
174 |
-
return new MessagesApply(
|
|
|
|
|
175 |
},
|
176 |
|
177 |
'button.is-logged-in' => static function ( ContainerInterface $container ): bool {
|
70 |
$environment = $container->get( 'onboarding.environment' );
|
71 |
$payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
|
72 |
$settings_status = $container->get( 'wcgateway.settings.status' );
|
73 |
+
$currency = $container->get( 'api.shop.currency' );
|
74 |
return new SmartButton(
|
75 |
$container->get( 'button.url' ),
|
76 |
$container->get( 'session.handler' ),
|
83 |
$messages_apply,
|
84 |
$environment,
|
85 |
$payment_token_repository,
|
86 |
+
$settings_status,
|
87 |
+
$currency
|
88 |
);
|
89 |
},
|
90 |
'button.url' => static function ( ContainerInterface $container ): string {
|
173 |
return new ThreeDSecure( $logger );
|
174 |
},
|
175 |
'button.helper.messages-apply' => static function ( ContainerInterface $container ): MessagesApply {
|
176 |
+
return new MessagesApply(
|
177 |
+
$container->get( 'api.shop.country' )
|
178 |
+
);
|
179 |
},
|
180 |
|
181 |
'button.is-logged-in' => static function ( ContainerInterface $container ): bool {
|
modules/ppcp-button/src/Assets/SmartButton.php
CHANGED
@@ -114,6 +114,13 @@ class SmartButton implements SmartButtonInterface {
|
|
114 |
*/
|
115 |
private $payment_token_repository;
|
116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
/**
|
118 |
* SmartButton constructor.
|
119 |
*
|
@@ -129,6 +136,7 @@ class SmartButton implements SmartButtonInterface {
|
|
129 |
* @param Environment $environment The environment object.
|
130 |
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
|
131 |
* @param SettingsStatus $settings_status The Settings status helper.
|
|
|
132 |
*/
|
133 |
public function __construct(
|
134 |
string $module_url,
|
@@ -142,7 +150,8 @@ class SmartButton implements SmartButtonInterface {
|
|
142 |
MessagesApply $messages_apply,
|
143 |
Environment $environment,
|
144 |
PaymentTokenRepository $payment_token_repository,
|
145 |
-
SettingsStatus $settings_status
|
|
|
146 |
) {
|
147 |
|
148 |
$this->module_url = $module_url;
|
@@ -157,6 +166,7 @@ class SmartButton implements SmartButtonInterface {
|
|
157 |
$this->environment = $environment;
|
158 |
$this->payment_token_repository = $payment_token_repository;
|
159 |
$this->settings_status = $settings_status;
|
|
|
160 |
}
|
161 |
|
162 |
/**
|
@@ -564,7 +574,7 @@ class SmartButton implements SmartButtonInterface {
|
|
564 |
|
565 |
printf(
|
566 |
'<div id="%1$s" style="display:none;">
|
567 |
-
<button class="button alt">%2$s</button>
|
568 |
</div><div id="payments-sdk__contingency-lightbox"></div><style id="ppcp-hide-dcc">.payment_method_ppcp-credit-card-gateway {display:none;}</style>',
|
569 |
esc_attr( $id ),
|
570 |
esc_html( $label )
|
@@ -684,17 +694,18 @@ class SmartButton implements SmartButtonInterface {
|
|
684 |
'wrapper' => '#ppcp-hosted-fields',
|
685 |
'mini_cart_wrapper' => '#ppcp-hosted-fields-mini-cart',
|
686 |
'labels' => array(
|
687 |
-
'credit_card_number'
|
688 |
-
'cvv'
|
689 |
-
'mm_yy'
|
690 |
-
'fields_not_valid'
|
691 |
'Unfortunately, your credit card details are not valid.',
|
692 |
'woocommerce-paypal-payments'
|
693 |
),
|
694 |
-
'card_not_supported'
|
695 |
'Unfortunately, we do not support your credit card.',
|
696 |
'woocommerce-paypal-payments'
|
697 |
),
|
|
|
698 |
),
|
699 |
'valid_cards' => $this->dcc_applies->valid_cards(),
|
700 |
'contingency' => $this->get_3ds_contingency(),
|
@@ -749,7 +760,7 @@ class SmartButton implements SmartButtonInterface {
|
|
749 |
|
750 |
$params = array(
|
751 |
'client-id' => $this->client_id,
|
752 |
-
'currency' =>
|
753 |
'integration-date' => PAYPAL_INTEGRATION_DATE,
|
754 |
'components' => implode( ',', $this->components() ),
|
755 |
'vault' => $this->can_save_vault_token() ? 'true' : 'false',
|
114 |
*/
|
115 |
private $payment_token_repository;
|
116 |
|
117 |
+
/**
|
118 |
+
* 3-letter currency code of the shop.
|
119 |
+
*
|
120 |
+
* @var string
|
121 |
+
*/
|
122 |
+
private $currency;
|
123 |
+
|
124 |
/**
|
125 |
* SmartButton constructor.
|
126 |
*
|
136 |
* @param Environment $environment The environment object.
|
137 |
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
|
138 |
* @param SettingsStatus $settings_status The Settings status helper.
|
139 |
+
* @param string $currency 3-letter currency code of the shop.
|
140 |
*/
|
141 |
public function __construct(
|
142 |
string $module_url,
|
150 |
MessagesApply $messages_apply,
|
151 |
Environment $environment,
|
152 |
PaymentTokenRepository $payment_token_repository,
|
153 |
+
SettingsStatus $settings_status,
|
154 |
+
string $currency
|
155 |
) {
|
156 |
|
157 |
$this->module_url = $module_url;
|
166 |
$this->environment = $environment;
|
167 |
$this->payment_token_repository = $payment_token_repository;
|
168 |
$this->settings_status = $settings_status;
|
169 |
+
$this->currency = $currency;
|
170 |
}
|
171 |
|
172 |
/**
|
574 |
|
575 |
printf(
|
576 |
'<div id="%1$s" style="display:none;">
|
577 |
+
<button class="button alt ppcp-dcc-order-button">%2$s</button>
|
578 |
</div><div id="payments-sdk__contingency-lightbox"></div><style id="ppcp-hide-dcc">.payment_method_ppcp-credit-card-gateway {display:none;}</style>',
|
579 |
esc_attr( $id ),
|
580 |
esc_html( $label )
|
694 |
'wrapper' => '#ppcp-hosted-fields',
|
695 |
'mini_cart_wrapper' => '#ppcp-hosted-fields-mini-cart',
|
696 |
'labels' => array(
|
697 |
+
'credit_card_number' => '',
|
698 |
+
'cvv' => '',
|
699 |
+
'mm_yy' => __( 'MM/YY', 'woocommerce-paypal-payments' ),
|
700 |
+
'fields_not_valid' => __(
|
701 |
'Unfortunately, your credit card details are not valid.',
|
702 |
'woocommerce-paypal-payments'
|
703 |
),
|
704 |
+
'card_not_supported' => __(
|
705 |
'Unfortunately, we do not support your credit card.',
|
706 |
'woocommerce-paypal-payments'
|
707 |
),
|
708 |
+
'cardholder_name_required' => __( 'Cardholder\'s first and last name are required, please fill the checkout form required fields.', 'woocommerce-paypal-payments' ),
|
709 |
),
|
710 |
'valid_cards' => $this->dcc_applies->valid_cards(),
|
711 |
'contingency' => $this->get_3ds_contingency(),
|
760 |
|
761 |
$params = array(
|
762 |
'client-id' => $this->client_id,
|
763 |
+
'currency' => $this->currency,
|
764 |
'integration-date' => PAYPAL_INTEGRATION_DATE,
|
765 |
'components' => implode( ',', $this->components() ),
|
766 |
'vault' => $this->can_save_vault_token() ? 'true' : 'false',
|
modules/ppcp-button/src/Helper/MessagesApply.php
CHANGED
@@ -28,14 +28,28 @@ class MessagesApply {
|
|
28 |
'AU',
|
29 |
);
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
/**
|
32 |
* Determines whether a credit messaging is enabled for the shops location country.
|
33 |
*
|
34 |
* @return bool
|
35 |
*/
|
36 |
public function for_country(): bool {
|
37 |
-
$
|
38 |
-
$country = $region['country'];
|
39 |
-
return in_array( $country, $this->countries, true );
|
40 |
}
|
41 |
}
|
28 |
'AU',
|
29 |
);
|
30 |
|
31 |
+
/**
|
32 |
+
* 2-letter country code of the shop.
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
private $country;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* MessagesApply constructor.
|
40 |
+
*
|
41 |
+
* @param string $country 2-letter country code of the shop.
|
42 |
+
*/
|
43 |
+
public function __construct( string $country ) {
|
44 |
+
$this->country = $country;
|
45 |
+
}
|
46 |
+
|
47 |
/**
|
48 |
* Determines whether a credit messaging is enabled for the shops location country.
|
49 |
*
|
50 |
* @return bool
|
51 |
*/
|
52 |
public function for_country(): bool {
|
53 |
+
return in_array( $this->country, $this->countries, true );
|
|
|
|
|
54 |
}
|
55 |
}
|
modules/ppcp-button/src/Helper/MessagesDisclaimers.php
CHANGED
@@ -39,15 +39,28 @@ class MessagesDisclaimers {
|
|
39 |
),
|
40 |
);
|
41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
/**
|
43 |
* Returns a disclaimer link based on country.
|
44 |
*
|
45 |
* @return string
|
46 |
*/
|
47 |
public function link_for_country(): string {
|
48 |
-
$
|
49 |
-
$country = $region['country'];
|
50 |
-
|
51 |
-
return $this->disclaimers[ $country ]['link'] ?? '';
|
52 |
}
|
53 |
}
|
39 |
),
|
40 |
);
|
41 |
|
42 |
+
/**
|
43 |
+
* 2-letter country code of the shop.
|
44 |
+
*
|
45 |
+
* @var string
|
46 |
+
*/
|
47 |
+
private $country;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* MessagesDisclaimers constructor.
|
51 |
+
*
|
52 |
+
* @param string $country 2-letter country code of the shop.
|
53 |
+
*/
|
54 |
+
public function __construct( string $country ) {
|
55 |
+
$this->country = $country;
|
56 |
+
}
|
57 |
+
|
58 |
/**
|
59 |
* Returns a disclaimer link based on country.
|
60 |
*
|
61 |
* @return string
|
62 |
*/
|
63 |
public function link_for_country(): string {
|
64 |
+
return $this->disclaimers[ $this->country ]['link'] ?? '';
|
|
|
|
|
|
|
65 |
}
|
66 |
}
|
modules/ppcp-compat/src/PPEC/PPECHelper.php
CHANGED
@@ -29,6 +29,15 @@ class PPECHelper {
|
|
29 |
const PPEC_SETTINGS_OPTION_NAME = 'woocommerce_ppec_paypal_settings';
|
30 |
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
/**
|
33 |
* Checks if the PayPal Express Checkout plugin is active.
|
34 |
*
|
29 |
const PPEC_SETTINGS_OPTION_NAME = 'woocommerce_ppec_paypal_settings';
|
30 |
|
31 |
|
32 |
+
/**
|
33 |
+
* Checks if the PayPal Express Checkout plugin was configured previously.
|
34 |
+
*
|
35 |
+
* @return bool
|
36 |
+
*/
|
37 |
+
public static function is_plugin_configured() {
|
38 |
+
return is_array( get_option( self::PPEC_SETTINGS_OPTION_NAME ) );
|
39 |
+
}
|
40 |
+
|
41 |
/**
|
42 |
* Checks if the PayPal Express Checkout plugin is active.
|
43 |
*
|
modules/ppcp-compat/src/PPEC/SettingsImporter.php
CHANGED
@@ -142,7 +142,7 @@ class SettingsImporter {
|
|
142 |
$value = array_values(
|
143 |
array_intersect(
|
144 |
array_map( 'strtolower', is_array( $option_value ) ? $option_value : array() ),
|
145 |
-
array( 'card', 'credit', 'sepa', 'bancontact', 'eps', 'giropay', 'ideal', 'mybank', 'p24', 'sofort', 'venmo' )
|
146 |
)
|
147 |
);
|
148 |
|
142 |
$value = array_values(
|
143 |
array_intersect(
|
144 |
array_map( 'strtolower', is_array( $option_value ) ? $option_value : array() ),
|
145 |
+
array( 'card', 'credit', 'sepa', 'bancontact', 'blik', 'eps', 'giropay', 'ideal', 'mercadopago', 'mybank', 'p24', 'sofort', 'venmo' )
|
146 |
)
|
147 |
);
|
148 |
|
modules/ppcp-status-report/src/Renderer.php
CHANGED
@@ -37,9 +37,11 @@ class Renderer {
|
|
37 |
foreach ( $items as $item ) {
|
38 |
?>
|
39 |
<tr>
|
40 |
-
<td data-export-label="<?php echo esc_attr( $item['
|
|
|
|
|
41 |
<td class="help"><?php echo wc_help_tip( $item['description'] ); ?></td>
|
42 |
-
<td><?php echo
|
43 |
</tr>
|
44 |
<?php
|
45 |
}
|
37 |
foreach ( $items as $item ) {
|
38 |
?>
|
39 |
<tr>
|
40 |
+
<td data-export-label="<?php echo esc_attr( $item['exported_label'] ?? $item['label'] ); ?>">
|
41 |
+
<?php echo esc_attr( $item['label'] ); ?>
|
42 |
+
</td>
|
43 |
<td class="help"><?php echo wc_help_tip( $item['description'] ); ?></td>
|
44 |
+
<td><?php echo wp_kses_post( $item['value'] ); ?></td>
|
45 |
</tr>
|
46 |
<?php
|
47 |
}
|
modules/ppcp-status-report/src/StatusReportModule.php
CHANGED
@@ -14,11 +14,13 @@ use Dhii\Modular\Module\ModuleInterface;
|
|
14 |
use Interop\Container\ServiceProviderInterface;
|
15 |
use Psr\Container\ContainerInterface;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
17 |
-
use WooCommerce\PayPalCommerce\ApiClient\
|
18 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
19 |
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
20 |
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
|
|
21 |
use WooCommerce\PayPalCommerce\Onboarding\State;
|
|
|
22 |
|
23 |
/**
|
24 |
* Class StatusReportModule
|
@@ -44,6 +46,8 @@ class StatusReportModule implements ModuleInterface {
|
|
44 |
add_action(
|
45 |
'woocommerce_system_status_report',
|
46 |
function () use ( $c ) {
|
|
|
|
|
47 |
|
48 |
/* @var State $state The state. */
|
49 |
$state = $c->get( 'onboarding.state' );
|
@@ -57,38 +61,93 @@ class StatusReportModule implements ModuleInterface {
|
|
57 |
/* @var MessagesApply $messages_apply The messages apply. */
|
58 |
$messages_apply = $c->get( 'button.helper.messages-apply' );
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
/* @var Renderer $renderer The renderer. */
|
61 |
$renderer = $c->get( 'status-report.renderer' );
|
62 |
|
|
|
|
|
63 |
$items = array(
|
64 |
array(
|
65 |
-
'label'
|
66 |
-
'
|
67 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
),
|
69 |
array(
|
70 |
-
'label'
|
71 |
-
'
|
72 |
-
'
|
|
|
|
|
|
|
73 |
),
|
74 |
array(
|
75 |
-
'label'
|
76 |
-
'
|
77 |
-
'
|
78 |
-
|
79 |
-
|
|
|
80 |
),
|
81 |
array(
|
82 |
-
'label'
|
83 |
-
'
|
84 |
-
'
|
85 |
-
|
86 |
-
|
|
|
87 |
),
|
88 |
array(
|
89 |
-
'label'
|
90 |
-
'
|
91 |
-
'
|
|
|
|
|
|
|
92 |
),
|
93 |
);
|
94 |
|
@@ -112,37 +171,56 @@ class StatusReportModule implements ModuleInterface {
|
|
112 |
*
|
113 |
* @param Bearer $bearer The bearer.
|
114 |
* @param State $state The state.
|
115 |
-
* @return
|
116 |
*/
|
117 |
-
private function onboarded( $bearer, $state ):
|
118 |
try {
|
119 |
$token = $bearer->bearer();
|
120 |
} catch ( RuntimeException $exception ) {
|
121 |
-
return
|
122 |
}
|
123 |
|
124 |
$current_state = $state->current_state();
|
125 |
-
|
126 |
-
return esc_html__( 'Yes', 'woocommerce-paypal-payments' );
|
127 |
-
}
|
128 |
-
|
129 |
-
return esc_html__( 'No', 'woocommerce-paypal-payments' );
|
130 |
}
|
131 |
|
132 |
/**
|
133 |
* It returns whether vaulting is enabled or not.
|
134 |
*
|
135 |
* @param Bearer $bearer The bearer.
|
136 |
-
* @return
|
137 |
*/
|
138 |
-
private function vault_enabled( $bearer ) {
|
139 |
try {
|
140 |
$token = $bearer->bearer();
|
141 |
-
return $token->vaulting_available()
|
142 |
-
? esc_html__( 'Yes', 'woocommerce-paypal-payments' )
|
143 |
-
: esc_html__( 'No', 'woocommerce-paypal-payments' );
|
144 |
} catch ( RuntimeException $exception ) {
|
145 |
-
return
|
146 |
}
|
147 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
}
|
14 |
use Interop\Container\ServiceProviderInterface;
|
15 |
use Psr\Container\ContainerInterface;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
17 |
+
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingAgreementsEndpoint;
|
18 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
19 |
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
20 |
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
21 |
+
use WooCommerce\PayPalCommerce\Compat\PPEC\PPECHelper;
|
22 |
use WooCommerce\PayPalCommerce\Onboarding\State;
|
23 |
+
use WooCommerce\PayPalCommerce\Webhooks\WebhookInfoStorage;
|
24 |
|
25 |
/**
|
26 |
* Class StatusReportModule
|
46 |
add_action(
|
47 |
'woocommerce_system_status_report',
|
48 |
function () use ( $c ) {
|
49 |
+
$settings = $c->get( 'wcgateway.settings' );
|
50 |
+
assert( $settings instanceof ContainerInterface );
|
51 |
|
52 |
/* @var State $state The state. */
|
53 |
$state = $c->get( 'onboarding.state' );
|
61 |
/* @var MessagesApply $messages_apply The messages apply. */
|
62 |
$messages_apply = $c->get( 'button.helper.messages-apply' );
|
63 |
|
64 |
+
$last_webhook_storage = $c->get( 'webhook.last-webhook-storage' );
|
65 |
+
assert( $last_webhook_storage instanceof WebhookInfoStorage );
|
66 |
+
|
67 |
+
$billing_agreements_endpoint = $c->get( 'api.endpoint.billing-agreements' );
|
68 |
+
assert( $billing_agreements_endpoint instanceof BillingAgreementsEndpoint );
|
69 |
+
|
70 |
/* @var Renderer $renderer The renderer. */
|
71 |
$renderer = $c->get( 'status-report.renderer' );
|
72 |
|
73 |
+
$had_ppec_plugin = PPECHelper::is_plugin_configured();
|
74 |
+
|
75 |
$items = array(
|
76 |
array(
|
77 |
+
'label' => esc_html__( 'Onboarded', 'woocommerce-paypal-payments' ),
|
78 |
+
'exported_label' => 'Onboarded',
|
79 |
+
'description' => esc_html__( 'Whether PayPal account is correctly configured or not.', 'woocommerce-paypal-payments' ),
|
80 |
+
'value' => $this->bool_to_html(
|
81 |
+
$this->onboarded( $bearer, $state )
|
82 |
+
),
|
83 |
+
),
|
84 |
+
array(
|
85 |
+
'label' => esc_html__( 'Shop country code', 'woocommerce-paypal-payments' ),
|
86 |
+
'exported_label' => 'Shop country code',
|
87 |
+
'description' => esc_html__( 'Country / State value on Settings / General / Store Address.', 'woocommerce-paypal-payments' ),
|
88 |
+
'value' => $c->get( 'api.shop.country' ),
|
89 |
+
),
|
90 |
+
array(
|
91 |
+
'label' => esc_html__( 'WooCommerce currency supported', 'woocommerce-paypal-payments' ),
|
92 |
+
'exported_label' => 'WooCommerce currency supported',
|
93 |
+
'description' => esc_html__( 'Whether PayPal supports the default store currency or not.', 'woocommerce-paypal-payments' ),
|
94 |
+
'value' => $this->bool_to_html(
|
95 |
+
$c->get( 'api.shop.is-currency-supported' )
|
96 |
+
),
|
97 |
+
),
|
98 |
+
array(
|
99 |
+
'label' => esc_html__( 'PayPal card processing available in country', 'woocommerce-paypal-payments' ),
|
100 |
+
'exported_label' => 'PayPal card processing available in country',
|
101 |
+
'description' => esc_html__( 'Whether PayPal card processing is available in country or not.', 'woocommerce-paypal-payments' ),
|
102 |
+
'value' => $this->bool_to_html(
|
103 |
+
$dcc_applies->for_country_currency()
|
104 |
+
),
|
105 |
+
),
|
106 |
+
array(
|
107 |
+
'label' => esc_html__( 'Pay Later messaging available in country', 'woocommerce-paypal-payments' ),
|
108 |
+
'exported_label' => 'Pay Later messaging available in country',
|
109 |
+
'description' => esc_html__( 'Whether Pay Later is available in country or not.', 'woocommerce-paypal-payments' ),
|
110 |
+
'value' => $this->bool_to_html(
|
111 |
+
$messages_apply->for_country()
|
112 |
+
),
|
113 |
+
),
|
114 |
+
array(
|
115 |
+
'label' => esc_html__( 'Webhook status', 'woocommerce-paypal-payments' ),
|
116 |
+
'exported_label' => 'Webhook status',
|
117 |
+
'description' => esc_html__( 'Whether we received webhooks successfully.', 'woocommerce-paypal-payments' ),
|
118 |
+
'value' => $this->bool_to_html( ! $last_webhook_storage->is_empty() ),
|
119 |
),
|
120 |
array(
|
121 |
+
'label' => esc_html__( 'Vault enabled', 'woocommerce-paypal-payments' ),
|
122 |
+
'exported_label' => 'Vault enabled',
|
123 |
+
'description' => esc_html__( 'Whether vaulting is enabled on PayPal account or not.', 'woocommerce-paypal-payments' ),
|
124 |
+
'value' => $this->bool_to_html(
|
125 |
+
$this->vault_enabled( $bearer )
|
126 |
+
),
|
127 |
),
|
128 |
array(
|
129 |
+
'label' => esc_html__( 'Logging enabled', 'woocommerce-paypal-payments' ),
|
130 |
+
'exported_label' => 'Logging enabled',
|
131 |
+
'description' => esc_html__( 'Whether logging of plugin events and errors is enabled.', 'woocommerce-paypal-payments' ),
|
132 |
+
'value' => $this->bool_to_html(
|
133 |
+
$settings->has( 'logging_enabled' ) && $settings->get( 'logging_enabled' )
|
134 |
+
),
|
135 |
),
|
136 |
array(
|
137 |
+
'label' => esc_html__( 'Reference Transactions', 'woocommerce-paypal-payments' ),
|
138 |
+
'exported_label' => 'Reference Transactions',
|
139 |
+
'description' => esc_html__( 'Whether Reference Transactions are enabled for the connected account', 'woocommerce-paypal-payments' ),
|
140 |
+
'value' => $this->bool_to_html(
|
141 |
+
$this->reference_transaction_enabled( $billing_agreements_endpoint )
|
142 |
+
),
|
143 |
),
|
144 |
array(
|
145 |
+
'label' => esc_html__( 'Used PayPal Checkout plugin', 'woocommerce-paypal-payments' ),
|
146 |
+
'exported_label' => 'Used PayPal Checkout plugin',
|
147 |
+
'description' => esc_html__( 'Whether the PayPal Checkout Gateway plugin was configured previously or not', 'woocommerce-paypal-payments' ),
|
148 |
+
'value' => $this->bool_to_html(
|
149 |
+
$had_ppec_plugin
|
150 |
+
),
|
151 |
),
|
152 |
);
|
153 |
|
171 |
*
|
172 |
* @param Bearer $bearer The bearer.
|
173 |
* @param State $state The state.
|
174 |
+
* @return bool
|
175 |
*/
|
176 |
+
private function onboarded( Bearer $bearer, State $state ): bool {
|
177 |
try {
|
178 |
$token = $bearer->bearer();
|
179 |
} catch ( RuntimeException $exception ) {
|
180 |
+
return false;
|
181 |
}
|
182 |
|
183 |
$current_state = $state->current_state();
|
184 |
+
return $token->is_valid() && $current_state === $state::STATE_ONBOARDED;
|
|
|
|
|
|
|
|
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
* It returns whether vaulting is enabled or not.
|
189 |
*
|
190 |
* @param Bearer $bearer The bearer.
|
191 |
+
* @return bool
|
192 |
*/
|
193 |
+
private function vault_enabled( Bearer $bearer ): bool {
|
194 |
try {
|
195 |
$token = $bearer->bearer();
|
196 |
+
return $token->vaulting_available();
|
|
|
|
|
197 |
} catch ( RuntimeException $exception ) {
|
198 |
+
return false;
|
199 |
}
|
200 |
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Checks if reference transactions are enabled in account.
|
204 |
+
*
|
205 |
+
* @param BillingAgreementsEndpoint $billing_agreements_endpoint The endpoint.
|
206 |
+
*/
|
207 |
+
private function reference_transaction_enabled( BillingAgreementsEndpoint $billing_agreements_endpoint ): bool {
|
208 |
+
try {
|
209 |
+
return $billing_agreements_endpoint->reference_transaction_enabled();
|
210 |
+
} catch ( RuntimeException $exception ) {
|
211 |
+
return false;
|
212 |
+
}
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Converts the bool value to "yes" icon or dash.
|
217 |
+
*
|
218 |
+
* @param bool $value The value.
|
219 |
+
* @return string
|
220 |
+
*/
|
221 |
+
private function bool_to_html( bool $value ): string {
|
222 |
+
return $value
|
223 |
+
? '<mark class="yes"><span class="dashicons dashicons-yes"></span></mark>'
|
224 |
+
: '<mark class="no">–</mark>';
|
225 |
+
}
|
226 |
}
|
modules/ppcp-vaulting/src/VaultingModule.php
CHANGED
@@ -38,6 +38,11 @@ class VaultingModule implements ModuleInterface {
|
|
38 |
*/
|
39 |
public function run( ContainerInterface $container ): void {
|
40 |
|
|
|
|
|
|
|
|
|
|
|
41 |
add_filter(
|
42 |
'woocommerce_account_menu_items',
|
43 |
function( $menu_links ) {
|
38 |
*/
|
39 |
public function run( ContainerInterface $container ): void {
|
40 |
|
41 |
+
$settings = $container->get( 'wcgateway.settings' );
|
42 |
+
if ( ! $settings->has( 'vault_enabled' ) || ! $settings->get( 'vault_enabled' ) ) {
|
43 |
+
return;
|
44 |
+
}
|
45 |
+
|
46 |
add_filter(
|
47 |
'woocommerce_account_menu_items',
|
48 |
function( $menu_links ) {
|
modules/ppcp-wc-gateway/services.php
CHANGED
@@ -680,17 +680,19 @@ return array(
|
|
680 |
'woocommerce-paypal-payments'
|
681 |
),
|
682 |
'options' => array(
|
683 |
-
'card'
|
684 |
-
'credit'
|
685 |
-
'sepa'
|
686 |
-
'bancontact'
|
687 |
-
'
|
688 |
-
'
|
689 |
-
'
|
690 |
-
'
|
691 |
-
'
|
692 |
-
'
|
693 |
-
'
|
|
|
|
|
694 |
),
|
695 |
'screens' => array(
|
696 |
State::STATE_PROGRESSIVE,
|
@@ -1905,7 +1907,7 @@ return array(
|
|
1905 |
),
|
1906 |
'class' => array(),
|
1907 |
'input_class' => array( 'wc-enhanced-select' ),
|
1908 |
-
'default' => '
|
1909 |
'desc_tip' => true,
|
1910 |
'options' => array(
|
1911 |
'NO_3D_SECURE' => __( 'No 3D Secure (transaction will be denied if 3D Secure is required)', 'woocommerce-paypal-payments' ),
|
@@ -2024,6 +2026,8 @@ return array(
|
|
2024 |
},
|
2025 |
|
2026 |
'button.helper.messages-disclaimers' => static function ( ContainerInterface $container ): MessagesDisclaimers {
|
2027 |
-
return new MessagesDisclaimers(
|
|
|
|
|
2028 |
},
|
2029 |
);
|
680 |
'woocommerce-paypal-payments'
|
681 |
),
|
682 |
'options' => array(
|
683 |
+
'card' => _x( 'Credit or debit cards', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
684 |
+
'credit' => _x( 'Pay Later', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
685 |
+
'sepa' => _x( 'SEPA-Lastschrift', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
686 |
+
'bancontact' => _x( 'Bancontact', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
687 |
+
'blik' => _x( 'BLIK', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
688 |
+
'eps' => _x( 'eps', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
689 |
+
'giropay' => _x( 'giropay', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
690 |
+
'ideal' => _x( 'iDEAL', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
691 |
+
'mercadopago' => _x( 'Mercado Pago', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
692 |
+
'mybank' => _x( 'MyBank', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
693 |
+
'p24' => _x( 'Przelewy24', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
694 |
+
'sofort' => _x( 'Sofort', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
695 |
+
'venmo' => _x( 'Venmo', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
696 |
),
|
697 |
'screens' => array(
|
698 |
State::STATE_PROGRESSIVE,
|
1907 |
),
|
1908 |
'class' => array(),
|
1909 |
'input_class' => array( 'wc-enhanced-select' ),
|
1910 |
+
'default' => $container->get( 'api.shop.is-psd2-country' ) ? '3D_SECURE' : 'NO_3D_SECURE',
|
1911 |
'desc_tip' => true,
|
1912 |
'options' => array(
|
1913 |
'NO_3D_SECURE' => __( 'No 3D Secure (transaction will be denied if 3D Secure is required)', 'woocommerce-paypal-payments' ),
|
2026 |
},
|
2027 |
|
2028 |
'button.helper.messages-disclaimers' => static function ( ContainerInterface $container ): MessagesDisclaimers {
|
2029 |
+
return new MessagesDisclaimers(
|
2030 |
+
$container->get( 'api.shop.country' )
|
2031 |
+
);
|
2032 |
},
|
2033 |
);
|
modules/ppcp-wc-gateway/src/Gateway/ProcessPaymentTrait.php
CHANGED
@@ -58,8 +58,8 @@ trait ProcessPaymentTrait {
|
|
58 |
* If customer has chosen a saved credit card payment.
|
59 |
*/
|
60 |
$saved_credit_card = filter_input( INPUT_POST, 'saved_credit_card', FILTER_SANITIZE_STRING );
|
61 |
-
$
|
62 |
-
if ( $saved_credit_card && ! isset( $
|
63 |
|
64 |
$user_id = (int) $wc_order->get_customer_id();
|
65 |
$customer = new \WC_Customer( $user_id );
|
58 |
* If customer has chosen a saved credit card payment.
|
59 |
*/
|
60 |
$saved_credit_card = filter_input( INPUT_POST, 'saved_credit_card', FILTER_SANITIZE_STRING );
|
61 |
+
$change_payment = filter_input( INPUT_POST, 'woocommerce_change_payment', FILTER_SANITIZE_STRING );
|
62 |
+
if ( $saved_credit_card && ! isset( $change_payment ) ) {
|
63 |
|
64 |
$user_id = (int) $wc_order->get_customer_id();
|
65 |
$customer = new \WC_Customer( $user_id );
|
modules/ppcp-webhooks/services.php
CHANGED
@@ -32,11 +32,13 @@ return array(
|
|
32 |
$factory = $container->get( 'api.factory.webhook' );
|
33 |
$endpoint = $container->get( 'api.endpoint.webhook' );
|
34 |
$rest_endpoint = $container->get( 'webhook.endpoint.controller' );
|
|
|
35 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
36 |
return new WebhookRegistrar(
|
37 |
$factory,
|
38 |
$endpoint,
|
39 |
$rest_endpoint,
|
|
|
40 |
$logger
|
41 |
);
|
42 |
},
|
@@ -48,6 +50,7 @@ return array(
|
|
48 |
$verify_request = ! defined( 'PAYPAL_WEBHOOK_REQUEST_VERIFICATION' ) || PAYPAL_WEBHOOK_REQUEST_VERIFICATION;
|
49 |
$webhook_event_factory = $container->get( 'api.factory.webhook-event' );
|
50 |
$simulation = $container->get( 'webhook.status.simulation' );
|
|
|
51 |
|
52 |
return new IncomingWebhookEndpoint(
|
53 |
$webhook_endpoint,
|
@@ -56,6 +59,7 @@ return array(
|
|
56 |
$verify_request,
|
57 |
$webhook_event_factory,
|
58 |
$simulation,
|
|
|
59 |
... $handler
|
60 |
);
|
61 |
},
|
@@ -183,6 +187,13 @@ return array(
|
|
183 |
);
|
184 |
},
|
185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
'webhook.module-url' => static function ( ContainerInterface $container ): string {
|
187 |
return plugins_url(
|
188 |
'/modules/ppcp-webhooks/',
|
32 |
$factory = $container->get( 'api.factory.webhook' );
|
33 |
$endpoint = $container->get( 'api.endpoint.webhook' );
|
34 |
$rest_endpoint = $container->get( 'webhook.endpoint.controller' );
|
35 |
+
$last_webhook_storage = $container->get( 'webhook.last-webhook-storage' );
|
36 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
37 |
return new WebhookRegistrar(
|
38 |
$factory,
|
39 |
$endpoint,
|
40 |
$rest_endpoint,
|
41 |
+
$last_webhook_storage,
|
42 |
$logger
|
43 |
);
|
44 |
},
|
50 |
$verify_request = ! defined( 'PAYPAL_WEBHOOK_REQUEST_VERIFICATION' ) || PAYPAL_WEBHOOK_REQUEST_VERIFICATION;
|
51 |
$webhook_event_factory = $container->get( 'api.factory.webhook-event' );
|
52 |
$simulation = $container->get( 'webhook.status.simulation' );
|
53 |
+
$last_webhook_storage = $container->get( 'webhook.last-webhook-storage' );
|
54 |
|
55 |
return new IncomingWebhookEndpoint(
|
56 |
$webhook_endpoint,
|
59 |
$verify_request,
|
60 |
$webhook_event_factory,
|
61 |
$simulation,
|
62 |
+
$last_webhook_storage,
|
63 |
... $handler
|
64 |
);
|
65 |
},
|
187 |
);
|
188 |
},
|
189 |
|
190 |
+
'webhook.last-webhook-storage' => static function ( ContainerInterface $container ): WebhookInfoStorage {
|
191 |
+
return new WebhookInfoStorage( $container->get( 'webhook.last-webhook-storage.key' ) );
|
192 |
+
},
|
193 |
+
'webhook.last-webhook-storage.key' => static function ( ContainerInterface $container ): string {
|
194 |
+
return 'ppcp-last-webhook';
|
195 |
+
},
|
196 |
+
|
197 |
'webhook.module-url' => static function ( ContainerInterface $container ): string {
|
198 |
return plugins_url(
|
199 |
'/modules/ppcp-webhooks/',
|
modules/ppcp-webhooks/src/Handler/PrefixTrait.php
CHANGED
@@ -31,7 +31,10 @@ trait PrefixTrait {
|
|
31 |
*/
|
32 |
private function sanitize_custom_id( string $custom_id ): int {
|
33 |
|
34 |
-
$id =
|
|
|
|
|
|
|
35 |
return (int) $id;
|
36 |
}
|
37 |
}
|
31 |
*/
|
32 |
private function sanitize_custom_id( string $custom_id ): int {
|
33 |
|
34 |
+
$id = $custom_id;
|
35 |
+
if ( strlen( $this->prefix ) > 0 && 0 === strpos( $id, $this->prefix ) ) {
|
36 |
+
$id = substr( $id, strlen( $this->prefix ) );
|
37 |
+
}
|
38 |
return (int) $id;
|
39 |
}
|
40 |
}
|
modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php
CHANGED
@@ -76,6 +76,13 @@ class IncomingWebhookEndpoint {
|
|
76 |
*/
|
77 |
private $simulation;
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
/**
|
80 |
* IncomingWebhookEndpoint constructor.
|
81 |
*
|
@@ -85,6 +92,7 @@ class IncomingWebhookEndpoint {
|
|
85 |
* @param bool $verify_request Whether requests need to be verified or not.
|
86 |
* @param WebhookEventFactory $webhook_event_factory The webhook event factory.
|
87 |
* @param WebhookSimulation $simulation The simulation handler.
|
|
|
88 |
* @param RequestHandler ...$handlers The handlers, which process a request in the end.
|
89 |
*/
|
90 |
public function __construct(
|
@@ -94,6 +102,7 @@ class IncomingWebhookEndpoint {
|
|
94 |
bool $verify_request,
|
95 |
WebhookEventFactory $webhook_event_factory,
|
96 |
WebhookSimulation $simulation,
|
|
|
97 |
RequestHandler ...$handlers
|
98 |
) {
|
99 |
|
@@ -103,6 +112,7 @@ class IncomingWebhookEndpoint {
|
|
103 |
$this->logger = $logger;
|
104 |
$this->verify_request = $verify_request;
|
105 |
$this->webhook_event_factory = $webhook_event_factory;
|
|
|
106 |
$this->simulation = $simulation;
|
107 |
}
|
108 |
|
@@ -176,6 +186,8 @@ class IncomingWebhookEndpoint {
|
|
176 |
public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
|
177 |
$event = $this->event_from_request( $request );
|
178 |
|
|
|
|
|
179 |
if ( $this->simulation->is_simulation_event( $event ) ) {
|
180 |
$this->logger->info( 'Received simulated webhook.' );
|
181 |
$this->simulation->receive( $event );
|
76 |
*/
|
77 |
private $simulation;
|
78 |
|
79 |
+
/**
|
80 |
+
* The last webhook info storage.
|
81 |
+
*
|
82 |
+
* @var WebhookInfoStorage
|
83 |
+
*/
|
84 |
+
private $last_webhook_storage;
|
85 |
+
|
86 |
/**
|
87 |
* IncomingWebhookEndpoint constructor.
|
88 |
*
|
92 |
* @param bool $verify_request Whether requests need to be verified or not.
|
93 |
* @param WebhookEventFactory $webhook_event_factory The webhook event factory.
|
94 |
* @param WebhookSimulation $simulation The simulation handler.
|
95 |
+
* @param WebhookInfoStorage $last_webhook_storage The last webhook info storage.
|
96 |
* @param RequestHandler ...$handlers The handlers, which process a request in the end.
|
97 |
*/
|
98 |
public function __construct(
|
102 |
bool $verify_request,
|
103 |
WebhookEventFactory $webhook_event_factory,
|
104 |
WebhookSimulation $simulation,
|
105 |
+
WebhookInfoStorage $last_webhook_storage,
|
106 |
RequestHandler ...$handlers
|
107 |
) {
|
108 |
|
112 |
$this->logger = $logger;
|
113 |
$this->verify_request = $verify_request;
|
114 |
$this->webhook_event_factory = $webhook_event_factory;
|
115 |
+
$this->last_webhook_storage = $last_webhook_storage;
|
116 |
$this->simulation = $simulation;
|
117 |
}
|
118 |
|
186 |
public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
|
187 |
$event = $this->event_from_request( $request );
|
188 |
|
189 |
+
$this->last_webhook_storage->save( $event );
|
190 |
+
|
191 |
if ( $this->simulation->is_simulation_event( $event ) ) {
|
192 |
$this->logger->info( 'Received simulated webhook.' );
|
193 |
$this->simulation->receive( $event );
|
modules/ppcp-webhooks/src/WebhookInfoStorage.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Stores the info about webhook events.
|
4 |
+
*
|
5 |
+
* @package WooCommerce\PayPalCommerce\Webhooks
|
6 |
+
*/
|
7 |
+
|
8 |
+
declare(strict_types=1);
|
9 |
+
|
10 |
+
namespace WooCommerce\PayPalCommerce\Webhooks;
|
11 |
+
|
12 |
+
use WooCommerce\PayPalCommerce\ApiClient\Entity\WebhookEvent;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class WebhookInfoStorage
|
16 |
+
*/
|
17 |
+
class WebhookInfoStorage {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* The WP option key.
|
21 |
+
*
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
private $key;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* WebhookInfoStorage constructor.
|
28 |
+
*
|
29 |
+
* @param string $key The WP option key.
|
30 |
+
*/
|
31 |
+
public function __construct(
|
32 |
+
string $key
|
33 |
+
) {
|
34 |
+
$this->key = $key;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Saves the info about webhook event.
|
39 |
+
*
|
40 |
+
* @param WebhookEvent $webhook_event The webhook event to save.
|
41 |
+
*/
|
42 |
+
public function save( WebhookEvent $webhook_event ): void {
|
43 |
+
$data = array(
|
44 |
+
'id' => $webhook_event->id(),
|
45 |
+
'received_time' => time(),
|
46 |
+
);
|
47 |
+
|
48 |
+
update_option( $this->key, $data );
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Returns the stored data or null.
|
53 |
+
*/
|
54 |
+
public function get_data(): ?array {
|
55 |
+
$data = get_option( $this->key );
|
56 |
+
if ( ! $data || ! is_array( $data ) ) {
|
57 |
+
return null;
|
58 |
+
}
|
59 |
+
return $data;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Checks if there is any stored data.
|
64 |
+
*/
|
65 |
+
public function is_empty(): bool {
|
66 |
+
$data = get_option( $this->key );
|
67 |
+
return ! $data || ! is_array( $data );
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Removes the stored data.
|
72 |
+
*/
|
73 |
+
public function clear(): void {
|
74 |
+
delete_option( $this->key );
|
75 |
+
}
|
76 |
+
}
|
modules/ppcp-webhooks/src/WebhookRegistrar.php
CHANGED
@@ -44,6 +44,13 @@ class WebhookRegistrar {
|
|
44 |
*/
|
45 |
private $rest_endpoint;
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
/**
|
48 |
* The logger.
|
49 |
*
|
@@ -57,19 +64,22 @@ class WebhookRegistrar {
|
|
57 |
* @param WebhookFactory $webhook_factory The Webhook factory.
|
58 |
* @param WebhookEndpoint $endpoint The Webhook endpoint.
|
59 |
* @param IncomingWebhookEndpoint $rest_endpoint The WordPress Rest API endpoint.
|
|
|
60 |
* @param LoggerInterface $logger The logger.
|
61 |
*/
|
62 |
public function __construct(
|
63 |
WebhookFactory $webhook_factory,
|
64 |
WebhookEndpoint $endpoint,
|
65 |
IncomingWebhookEndpoint $rest_endpoint,
|
|
|
66 |
LoggerInterface $logger
|
67 |
) {
|
68 |
|
69 |
-
$this->webhook_factory
|
70 |
-
$this->endpoint
|
71 |
-
$this->rest_endpoint
|
72 |
-
$this->
|
|
|
73 |
}
|
74 |
|
75 |
/**
|
@@ -92,6 +102,7 @@ class WebhookRegistrar {
|
|
92 |
self::KEY,
|
93 |
$created->to_array()
|
94 |
);
|
|
|
95 |
$this->logger->info( 'Webhooks subscribed.' );
|
96 |
return true;
|
97 |
} catch ( RuntimeException $error ) {
|
@@ -120,6 +131,7 @@ class WebhookRegistrar {
|
|
120 |
|
121 |
if ( $success ) {
|
122 |
delete_option( self::KEY );
|
|
|
123 |
$this->logger->info( 'Webhooks deleted.' );
|
124 |
}
|
125 |
return $success;
|
44 |
*/
|
45 |
private $rest_endpoint;
|
46 |
|
47 |
+
/**
|
48 |
+
* The last webhook info storage.
|
49 |
+
*
|
50 |
+
* @var WebhookInfoStorage
|
51 |
+
*/
|
52 |
+
private $last_webhook_storage;
|
53 |
+
|
54 |
/**
|
55 |
* The logger.
|
56 |
*
|
64 |
* @param WebhookFactory $webhook_factory The Webhook factory.
|
65 |
* @param WebhookEndpoint $endpoint The Webhook endpoint.
|
66 |
* @param IncomingWebhookEndpoint $rest_endpoint The WordPress Rest API endpoint.
|
67 |
+
* @param WebhookInfoStorage $last_webhook_storage The last webhook info storage.
|
68 |
* @param LoggerInterface $logger The logger.
|
69 |
*/
|
70 |
public function __construct(
|
71 |
WebhookFactory $webhook_factory,
|
72 |
WebhookEndpoint $endpoint,
|
73 |
IncomingWebhookEndpoint $rest_endpoint,
|
74 |
+
WebhookInfoStorage $last_webhook_storage,
|
75 |
LoggerInterface $logger
|
76 |
) {
|
77 |
|
78 |
+
$this->webhook_factory = $webhook_factory;
|
79 |
+
$this->endpoint = $endpoint;
|
80 |
+
$this->rest_endpoint = $rest_endpoint;
|
81 |
+
$this->last_webhook_storage = $last_webhook_storage;
|
82 |
+
$this->logger = $logger;
|
83 |
}
|
84 |
|
85 |
/**
|
102 |
self::KEY,
|
103 |
$created->to_array()
|
104 |
);
|
105 |
+
$this->last_webhook_storage->clear();
|
106 |
$this->logger->info( 'Webhooks subscribed.' );
|
107 |
return true;
|
108 |
} catch ( RuntimeException $error ) {
|
131 |
|
132 |
if ( $success ) {
|
133 |
delete_option( self::KEY );
|
134 |
+
$this->last_webhook_storage->clear();
|
135 |
$this->logger->info( 'Webhooks deleted.' );
|
136 |
}
|
137 |
return $success;
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: woocommerce, paypal, payments, ecommerce, e-commerce, store, sales, sell,
|
|
4 |
Requires at least: 5.3
|
5 |
Tested up to: 5.8
|
6 |
Requires PHP: 7.1
|
7 |
-
Stable tag: 1.6.
|
8 |
License: GPLv2
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -81,6 +81,17 @@ Follow the steps below to connect the plugin to your PayPal account:
|
|
81 |
|
82 |
== Changelog ==
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
= 1.6.2 =
|
85 |
* Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
|
86 |
* Fix - Can't checkout to certain countries with optional postcode #330
|
4 |
Requires at least: 5.3
|
5 |
Tested up to: 5.8
|
6 |
Requires PHP: 7.1
|
7 |
+
Stable tag: 1.6.3
|
8 |
License: GPLv2
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
81 |
|
82 |
== Changelog ==
|
83 |
|
84 |
+
= 1.6.3 =
|
85 |
+
* Fix - Payments fail when using custom order numbers #354
|
86 |
+
* Fix - Do not display saved payments on PayPal buttons if vault option is disabled #358
|
87 |
+
* Fix - Double "Place Order" button #362
|
88 |
+
* Fix - Coupon causes TAX_TOTAL_MISMATCH #372
|
89 |
+
* Fix - Funding sources Mercado Pago and BLIK can't be disabled #383
|
90 |
+
* Fix - Customer details not available in order and name gets replaced by xxx@dcc2.paypal.com #378
|
91 |
+
* Fix - 3D Secure failing for certain credit card types with PayPal Card Processing #379
|
92 |
+
* Fix - Error messages are not cleared even when checkout is re-attempted (DCC) #366
|
93 |
+
* Add - New additions for system report status #377
|
94 |
+
|
95 |
= 1.6.2 =
|
96 |
* Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
|
97 |
* Fix - Can't checkout to certain countries with optional postcode #330
|
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 ComposerAutoloaderInitab4ef10ecf6654ac031f82e5b0cb2339::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 ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c
|
|
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 ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c
|
|
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 ComposerAutoloaderInitab4ef10ecf6654ac031f82e5b0cb2339
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
+
spl_autoload_register(array('ComposerAutoloaderInitab4ef10ecf6654ac031f82e5b0cb2339', 'loadClassLoader'), true, true);
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
+
spl_autoload_unregister(array('ComposerAutoloaderInitab4ef10ecf6654ac031f82e5b0cb2339', '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\ComposerStaticInitab4ef10ecf6654ac031f82e5b0cb2339::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\ComposerStaticInitab4ef10ecf6654ac031f82e5b0cb2339::$files;
|
55 |
} else {
|
56 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
57 |
}
|
58 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
59 |
+
composerRequireab4ef10ecf6654ac031f82e5b0cb2339($fileIdentifier, $file);
|
60 |
}
|
61 |
|
62 |
return $loader;
|
63 |
}
|
64 |
}
|
65 |
|
66 |
+
function composerRequireab4ef10ecf6654ac031f82e5b0cb2339($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 |
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
@@ -131,8 +131,8 @@ class ComposerStaticInit3acb3642cf46c3f8b0d913579e285e9c
|
|
131 |
public static function getInitializer(ClassLoader $loader)
|
132 |
{
|
133 |
return \Closure::bind(function () use ($loader) {
|
134 |
-
$loader->prefixLengthsPsr4 =
|
135 |
-
$loader->prefixDirsPsr4 =
|
136 |
|
137 |
}, null, ClassLoader::class);
|
138 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInitab4ef10ecf6654ac031f82e5b0cb2339
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
131 |
public static function getInitializer(ClassLoader $loader)
|
132 |
{
|
133 |
return \Closure::bind(function () use ($loader) {
|
134 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInitab4ef10ecf6654ac031f82e5b0cb2339::$prefixLengthsPsr4;
|
135 |
+
$loader->prefixDirsPsr4 = ComposerStaticInitab4ef10ecf6654ac031f82e5b0cb2339::$prefixDirsPsr4;
|
136 |
|
137 |
}, null, ClassLoader::class);
|
138 |
}
|
woocommerce-paypal-payments.php
CHANGED
@@ -3,7 +3,7 @@
|
|
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.6.
|
7 |
* Author: WooCommerce
|
8 |
* Author URI: https://woocommerce.com/
|
9 |
* License: GPL-2.0
|
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.6.3
|
7 |
* Author: WooCommerce
|
8 |
* Author URI: https://woocommerce.com/
|
9 |
* License: GPL-2.0
|