WooCommerce PayPal Payments - Version 1.6.5

Version Description

  • Fix - Allow guest users to purchase subscription products #422
  • Fix - Transaction ID missing for renewal order #424
  • Fix - Save your credit card checkbox should be removed in pay for order for subscriptions #420
  • Fix - Null currency error when the Aelia currency switcher plugin is active #426
  • Fix - Hide Reference Transactions check from logs #428
  • Fix - Doubled plugin module URL path causing failure #438
  • Fix - is_ajax deprecated #441
  • Fix - Place order button from PayPal Card Processing does not get translated #290
  • Fix - AMEX missing from supported cards for DCC Australia #432
  • Fix - "Save your Credit Card" text not clickable to change checkbox state #430
  • Fix - Improve DCC error notice when not available #435
  • Enhancement - Add View Logs link #416
Download this release

Release Info

Developer woothemes
Plugin Icon 128x128 WooCommerce PayPal Payments
Version 1.6.5
Comparing to
See all releases

Code changes from version 1.6.4 to 1.6.5

Files changed (31) hide show
  1. changelog.txt +14 -0
  2. modules/ppcp-api-client/services.php +17 -5
  3. modules/ppcp-api-client/src/Endpoint/BillingAgreementsEndpoint.php +11 -5
  4. modules/ppcp-api-client/src/Endpoint/IdentityToken.php +35 -23
  5. modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php +14 -14
  6. modules/ppcp-api-client/src/Endpoint/RequestTrait.php +10 -1
  7. modules/ppcp-api-client/src/Repository/CustomerRepository.php +60 -0
  8. modules/ppcp-button/assets/js/button.js +1 -1
  9. modules/ppcp-button/resources/js/button.js +9 -1
  10. modules/ppcp-button/services.php +1 -1
  11. modules/ppcp-button/src/Assets/SmartButton.php +20 -16
  12. modules/ppcp-button/src/Endpoint/DataClientIdEndpoint.php +1 -1
  13. modules/ppcp-onboarding/services.php +1 -1
  14. modules/ppcp-onboarding/src/Assets/OnboardingAssets.php +3 -3
  15. modules/ppcp-subscription/services.php +3 -1
  16. modules/ppcp-subscription/src/Helper/SubscriptionHelper.php +36 -0
  17. modules/ppcp-subscription/src/RenewalHandler.php +41 -75
  18. modules/ppcp-vaulting/services.php +1 -1
  19. modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php +1 -1
  20. modules/ppcp-vaulting/src/VaultingModule.php +11 -0
  21. modules/ppcp-wc-gateway/services.php +5 -5
  22. modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php +1 -1
  23. modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php +3 -18
  24. modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php +8 -0
  25. modules/ppcp-webhooks/services.php +1 -1
  26. modules/ppcp-webhooks/src/Status/Assets/WebhooksStatusPageAssets.php +2 -2
  27. readme.txt +15 -1
  28. vendor/autoload.php +1 -1
  29. vendor/composer/autoload_real.php +7 -7
  30. vendor/composer/autoload_static.php +3 -3
  31. woocommerce-paypal-payments.php +2 -2
changelog.txt CHANGED
@@ -1,5 +1,19 @@
1
  *** Changelog ***
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  = 1.6.4 - 2021-12-27 =
4
  * Fix - Non admin user cannot save changes to the plugin settings #278
5
  * Fix - Empty space in invoice prefix causes smart buttons to not load #390
1
  *** Changelog ***
2
 
3
+ = 1.6.5 - 2022-01-22 =
4
+ * Fix - Allow guest users to purchase subscription products #422
5
+ * Fix - Transaction ID missing for renewal order #424
6
+ * Fix - Save your credit card checkbox should be removed in pay for order for subscriptions #420
7
+ * Fix - Null currency error when the Aelia currency switcher plugin is active #426
8
+ * Fix - Hide Reference Transactions check from logs #428
9
+ * Fix - Doubled plugin module URL path causing failure #438
10
+ * Fix - is_ajax deprecated #441
11
+ * Fix - Place order button from PayPal Card Processing does not get translated #290
12
+ * Fix - AMEX missing from supported cards for DCC Australia #432
13
+ * Fix - "Save your Credit Card" text not clickable to change checkbox state #430
14
+ * Fix - Improve DCC error notice when not available #435
15
+ * Enhancement - Add View Logs link #416
16
+
17
  = 1.6.4 - 2021-12-27 =
18
  * Fix - Non admin user cannot save changes to the plugin settings #278
19
  * Fix - Empty space in invoice prefix causes smart buttons to not load #390
modules/ppcp-api-client/services.php CHANGED
@@ -43,6 +43,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
43
  use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
44
  use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
45
  use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
 
46
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
47
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
48
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
@@ -108,7 +109,7 @@ return array(
108
  $container->get( 'api.bearer' ),
109
  $container->get( 'api.factory.payment-token' ),
110
  $container->get( 'woocommerce.logger.woocommerce' ),
111
- $container->get( 'api.prefix' )
112
  );
113
  },
114
  'api.endpoint.webhook' => static function ( ContainerInterface $container ) : WebhookEndpoint {
@@ -132,14 +133,14 @@ return array(
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 {
@@ -221,6 +222,10 @@ return array(
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
  },
@@ -322,7 +327,13 @@ return array(
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();
@@ -510,6 +521,7 @@ return array(
510
  'AU' => array(
511
  'mastercard' => array(),
512
  'visa' => array(),
 
513
  ),
514
  'ES' => array(
515
  'mastercard' => array(),
43
  use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
44
  use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
45
  use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
46
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\CustomerRepository;
47
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
48
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
49
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
109
  $container->get( 'api.bearer' ),
110
  $container->get( 'api.factory.payment-token' ),
111
  $container->get( 'woocommerce.logger.woocommerce' ),
112
+ $container->get( 'api.repository.customer' )
113
  );
114
  },
115
  'api.endpoint.webhook' => static function ( ContainerInterface $container ) : WebhookEndpoint {
133
  },
134
  'api.endpoint.identity-token' => static function ( ContainerInterface $container ) : IdentityToken {
135
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
 
136
  $settings = $container->get( 'wcgateway.settings' );
137
+ $customer_repository = $container->get( 'api.repository.customer' );
138
  return new IdentityToken(
139
  $container->get( 'api.host' ),
140
  $container->get( 'api.bearer' ),
141
  $logger,
142
+ $settings,
143
+ $customer_repository
144
  );
145
  },
146
  'api.endpoint.payments' => static function ( ContainerInterface $container ): PaymentsEndpoint {
222
  $merchant_id = $container->get( 'api.merchant_id' );
223
  return new PayeeRepository( $merchant_email, $merchant_id );
224
  },
225
+ 'api.repository.customer' => static function( ContainerInterface $container ): CustomerRepository {
226
+ $prefix = $container->get( 'api.prefix' );
227
+ return new CustomerRepository( $prefix );
228
+ },
229
  'api.factory.application-context' => static function ( ContainerInterface $container ) : ApplicationContextFactory {
230
  return new ApplicationContextFactory();
231
  },
327
  },
328
 
329
  'api.shop.currency' => static function ( ContainerInterface $container ) : string {
330
+ // We use option instead of get_woocommerce_currency
331
+ // because it will not be overridden by currency switching plugins.
332
+ $currency = get_option( 'woocommerce_currency' );
333
+ if ( ! $currency ) {
334
+ return 'NO_CURRENCY'; // Unlikely to happen.
335
+ }
336
+ return $currency;
337
  },
338
  'api.shop.country' => static function ( ContainerInterface $container ) : string {
339
  $location = wc_get_base_location();
521
  'AU' => array(
522
  'mastercard' => array(),
523
  'visa' => array(),
524
+ 'amex' => array( 'AUD' ),
525
  ),
526
  'ES' => array(
527
  'mastercard' => array(),
modules/ppcp-api-client/src/Endpoint/BillingAgreementsEndpoint.php CHANGED
@@ -120,11 +120,17 @@ class BillingAgreementsEndpoint {
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 ) {
120
  */
121
  public function reference_transaction_enabled(): bool {
122
  try {
123
+ $this->is_request_logging_enabled = false;
124
+
125
+ try {
126
+ $this->create_token(
127
+ 'Checking if reference transactions are enabled',
128
+ 'https://example.com/return',
129
+ 'https://example.com/cancel'
130
+ );
131
+ } finally {
132
+ $this->is_request_logging_enabled = true;
133
+ }
134
 
135
  return true;
136
  } catch ( PayPalApiException $exception ) {
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
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
18
 
19
  /**
@@ -45,45 +46,51 @@ class IdentityToken {
45
  private $logger;
46
 
47
  /**
48
- * The prefix.
49
  *
50
- * @var string
51
  */
52
- private $prefix;
53
 
54
  /**
55
- * The settings
56
  *
57
- * @var Settings
58
  */
59
- private $settings;
60
 
61
  /**
62
  * IdentityToken constructor.
63
  *
64
- * @param string $host The host.
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
  /**
79
- * Generates a token for a specific customer.
80
  *
81
- * @param int $customer_id The id of the customer.
82
  *
83
  * @return Token
84
  * @throws RuntimeException If the request fails.
85
  */
86
- public function generate_for_customer( int $customer_id ): Token {
87
 
88
  $bearer = $this->bearer->bearer();
89
  $url = trailingslashit( $this->host ) . 'v1/identity/generate-token';
@@ -95,11 +102,16 @@ class IdentityToken {
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
 
105
  $response = $this->request( $url, $args );
14
  use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
15
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
16
  use Psr\Log\LoggerInterface;
17
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\CustomerRepository;
18
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
19
 
20
  /**
46
  private $logger;
47
 
48
  /**
49
+ * The settings
50
  *
51
+ * @var Settings
52
  */
53
+ private $settings;
54
 
55
  /**
56
+ * The customer repository.
57
  *
58
+ * @var CustomerRepository
59
  */
60
+ protected $customer_repository;
61
 
62
  /**
63
  * IdentityToken constructor.
64
  *
65
+ * @param string $host The host.
66
+ * @param Bearer $bearer The bearer.
67
+ * @param LoggerInterface $logger The logger.
68
+ * @param Settings $settings The settings.
69
+ * @param CustomerRepository $customer_repository The customer repository.
70
  */
71
+ public function __construct(
72
+ string $host,
73
+ Bearer $bearer,
74
+ LoggerInterface $logger,
75
+ Settings $settings,
76
+ CustomerRepository $customer_repository
77
+ ) {
78
+ $this->host = $host;
79
+ $this->bearer = $bearer;
80
+ $this->logger = $logger;
81
+ $this->settings = $settings;
82
+ $this->customer_repository = $customer_repository;
83
  }
84
 
85
  /**
86
+ * Generates a token for a specific user.
87
  *
88
+ * @param int $user_id The id of the user.
89
  *
90
  * @return Token
91
  * @throws RuntimeException If the request fails.
92
  */
93
+ public function generate_for_user( int $user_id ): Token {
94
 
95
  $bearer = $this->bearer->bearer();
96
  $url = trailingslashit( $this->host ) . 'v1/identity/generate-token';
102
  ),
103
  );
104
  if (
105
+ ( $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) )
 
106
  && defined( 'PPCP_FLAG_SUBSCRIPTION' ) && PPCP_FLAG_SUBSCRIPTION
107
  ) {
108
+ $customer_id = $this->customer_repository->customer_id_for_user( ( $user_id ) );
109
+
110
+ $args['body'] = wp_json_encode(
111
+ array(
112
+ 'customer_id' => $customer_id,
113
+ )
114
+ );
115
  }
116
 
117
  $response = $this->request( $url, $args );
modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php CHANGED
@@ -15,6 +15,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
15
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
16
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
17
  use Psr\Log\LoggerInterface;
 
18
 
19
  /**
20
  * Class PaymentTokenEndpoint
@@ -50,12 +51,13 @@ class PaymentTokenEndpoint {
50
  * @var LoggerInterface
51
  */
52
  private $logger;
 
53
  /**
54
- * The prefix.
55
  *
56
- * @var string
57
  */
58
- private $prefix;
59
 
60
  /**
61
  * PaymentTokenEndpoint constructor.
@@ -64,21 +66,21 @@ class PaymentTokenEndpoint {
64
  * @param Bearer $bearer The bearer.
65
  * @param PaymentTokenFactory $factory The payment token factory.
66
  * @param LoggerInterface $logger The logger.
67
- * @param string $prefix The prefix.
68
  */
69
  public function __construct(
70
  string $host,
71
  Bearer $bearer,
72
  PaymentTokenFactory $factory,
73
  LoggerInterface $logger,
74
- string $prefix
75
  ) {
76
 
77
- $this->host = $host;
78
- $this->bearer = $bearer;
79
- $this->factory = $factory;
80
- $this->logger = $logger;
81
- $this->prefix = $prefix;
82
  }
83
 
84
  /**
@@ -91,10 +93,8 @@ class PaymentTokenEndpoint {
91
  */
92
  public function for_user( int $id ): array {
93
  $bearer = $this->bearer->bearer();
94
-
95
- $customer_id = $this->prefix . $id;
96
- $url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/?customer_id=' . $customer_id;
97
- $args = array(
98
  'method' => 'GET',
99
  'headers' => array(
100
  'Authorization' => 'Bearer ' . $bearer->token(),
15
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
16
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
17
  use Psr\Log\LoggerInterface;
18
+ use WooCommerce\PayPalCommerce\ApiClient\Repository\CustomerRepository;
19
 
20
  /**
21
  * Class PaymentTokenEndpoint
51
  * @var LoggerInterface
52
  */
53
  private $logger;
54
+
55
  /**
56
+ * The customer repository.
57
  *
58
+ * @var CustomerRepository
59
  */
60
+ protected $customer_repository;
61
 
62
  /**
63
  * PaymentTokenEndpoint constructor.
66
  * @param Bearer $bearer The bearer.
67
  * @param PaymentTokenFactory $factory The payment token factory.
68
  * @param LoggerInterface $logger The logger.
69
+ * @param CustomerRepository $customer_repository The customer repository.
70
  */
71
  public function __construct(
72
  string $host,
73
  Bearer $bearer,
74
  PaymentTokenFactory $factory,
75
  LoggerInterface $logger,
76
+ CustomerRepository $customer_repository
77
  ) {
78
 
79
+ $this->host = $host;
80
+ $this->bearer = $bearer;
81
+ $this->factory = $factory;
82
+ $this->logger = $logger;
83
+ $this->customer_repository = $customer_repository;
84
  }
85
 
86
  /**
93
  */
94
  public function for_user( int $id ): array {
95
  $bearer = $this->bearer->bearer();
96
+ $url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/?customer_id=' . $this->customer_repository->customer_id_for_user( $id );
97
+ $args = array(
 
 
98
  'method' => 'GET',
99
  'headers' => array(
100
  'Authorization' => 'Bearer ' . $bearer->token(),
modules/ppcp-api-client/src/Endpoint/RequestTrait.php CHANGED
@@ -16,6 +16,13 @@ use WP_Error;
16
  */
17
  trait RequestTrait {
18
 
 
 
 
 
 
 
 
19
  /**
20
  * Performs a request
21
  *
@@ -39,7 +46,9 @@ trait RequestTrait {
39
  }
40
 
41
  $response = wp_remote_get( $url, $args );
42
- $this->logger->debug( $this->request_response_string( $url, $args, $response ) );
 
 
43
  return $response;
44
  }
45
 
16
  */
17
  trait RequestTrait {
18
 
19
+ /**
20
+ * Whether to log the detailed request/response info.
21
+ *
22
+ * @var bool
23
+ */
24
+ protected $is_request_logging_enabled = true;
25
+
26
  /**
27
  * Performs a request
28
  *
46
  }
47
 
48
  $response = wp_remote_get( $url, $args );
49
+ if ( $this->is_request_logging_enabled ) {
50
+ $this->logger->debug( $this->request_response_string( $url, $args, $response ) );
51
+ }
52
  return $response;
53
  }
54
 
modules/ppcp-api-client/src/Repository/CustomerRepository.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The customer repository.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\ApiClient\Repository
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
11
+
12
+ /**
13
+ * Class CustomerRepository
14
+ */
15
+ class CustomerRepository {
16
+ const CLIENT_ID_MAX_LENGTH = 22;
17
+
18
+ /**
19
+ * The prefix.
20
+ *
21
+ * @var string
22
+ */
23
+ protected $prefix;
24
+
25
+ /**
26
+ * CustomerRepository constructor.
27
+ *
28
+ * @param string $prefix The prefix.
29
+ */
30
+ public function __construct( string $prefix ) {
31
+ $this->prefix = $prefix;
32
+ }
33
+
34
+ /**
35
+ * Returns the customer ID for the given user ID.
36
+ *
37
+ * @param int $user_id The user ID.
38
+ * @return string
39
+ */
40
+ public function customer_id_for_user( int $user_id ): string {
41
+ if ( 0 === $user_id ) {
42
+ $guest_customer_id = WC()->session->get( 'ppcp_guest_customer_id' );
43
+ if ( is_string( $guest_customer_id ) && $guest_customer_id ) {
44
+ return $guest_customer_id;
45
+ }
46
+
47
+ $unique_id = substr( $this->prefix . strrev( uniqid() ), 0, self::CLIENT_ID_MAX_LENGTH );
48
+ WC()->session->set( 'ppcp_guest_customer_id', $unique_id );
49
+
50
+ return $unique_id;
51
+ }
52
+
53
+ $guest_customer_id = get_user_meta( $user_id, 'ppcp_guest_customer_id', true );
54
+ if ( $guest_customer_id ) {
55
+ return $guest_customer_id;
56
+ }
57
+
58
+ return $this->prefix . (string) $user_id;
59
+ }
60
+ }
modules/ppcp-button/assets/js/button.js CHANGED
@@ -1 +1 @@
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 funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/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 funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\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, onSmartButtonClick) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n this.onSmartButtonClick = onSmartButtonClick;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig,\n onClick: this.onSmartButtonClick\n }).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\n const onSmartButtonClick = data => {\n window.ppcpFundingSource = data.fundingSource;\n };\n\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick);\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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TCIsInNvdXJjZXMiOlsid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9FcnJvckhhbmRsZXIuanM/ZTY1YSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JDb250aW51ZS5qcz9jNDU0Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvUGF5ZXJEYXRhLmpzPzJhZjEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXIuanM/ODJjZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9NaW5pQ2FydEJvb3RzdGFwLmpzP2Q1NTIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9VcGRhdGVDYXJ0LmpzP2U0MjIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9CdXR0b25zVG9nZ2xlTGlzdGVuZXIuanM/ZTE5MyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRW50aXR5L1Byb2R1Y3QuanM/OWZmZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9TaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlci5qcz9kOWI3Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1NpbmdsZVByb2R1Y3RCb290c3RhcC5qcz83YzE5Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NhcnRCb290c3RhcC5qcz81ZTk0Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9PbkFwcHJvdmVIYW5kbGVyL29uQXBwcm92ZUZvclBheU5vdy5qcz85MzA1Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NoZWNrb3V0QWN0aW9uSGFuZGxlci5qcz84NTE1Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvSGlkaW5nLmpzPzFkMzYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2hlY2tvdXRCb290c3RhcC5qcz9jODU1Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1BheU5vd0Jvb3RzdHJhcC5qcz9kOWY1Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9SZW5kZXJlci5qcz9mYTkzIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvRGNjSW5wdXRGYWN0b3J5LmpzPzJhMmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL0NyZWRpdENhcmRSZW5kZXJlci5qcz8zODdhIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9EYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyLmpzP2VlMGIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL01lc3NhZ2VSZW5kZXJlci5qcz9jZDAyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvU3Bpbm5lci5qcz8xNzA4Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvYnV0dG9uLmpzPzA2MGYiXSwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgRXJyb3JIYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGdlbmVyaWNFcnJvclRleHQpXG4gICAge1xuICAgICAgICB0aGlzLmdlbmVyaWNFcnJvclRleHQgPSBnZW5lcmljRXJyb3JUZXh0O1xuICAgICAgICB0aGlzLndyYXBwZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcud29vY29tbWVyY2Utbm90aWNlcy13cmFwcGVyJyk7XG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcigndWwud29vY29tbWVyY2UtZXJyb3InKTtcbiAgICB9XG5cbiAgICBnZW5lcmljRXJyb3IoKSB7XG4gICAgICAgIGlmICh0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCdwcGNwLXBlcnNpc3QnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlKHRoaXMuZ2VuZXJpY0Vycm9yVGV4dClcbiAgICB9XG5cbiAgICBhcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoZXJyb3JNZXNzYWdlRWxlbWVudClcbiAgICB7XG4gICAgICAgIGlmKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LnJlcGxhY2VXaXRoKGVycm9yTWVzc2FnZUVsZW1lbnQpO1xuICAgIH1cblxuICAgIG1lc3NhZ2UodGV4dCwgcGVyc2lzdCA9IGZhbHNlKVxuICAgIHtcbiAgICAgICAgaWYoISB0eXBlb2YgU3RyaW5nIHx8IHRleHQubGVuZ3RoID09PSAwKXtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQSBuZXcgbWVzc2FnZSB0ZXh0IG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpe1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlTWVzc2FnZXNMaXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGVyc2lzdCkge1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5hZGQoJ3BwY3AtcGVyc2lzdCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5yZW1vdmUoJ3BwY3AtcGVyc2lzdCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG1lc3NhZ2VOb2RlID0gdGhpcy5wcmVwYXJlTWVzc2FnZXNMaXN0SXRlbSh0ZXh0KTtcbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QuYXBwZW5kQ2hpbGQobWVzc2FnZU5vZGUpO1xuXG4gICAgICAgIGpRdWVyeS5zY3JvbGxfdG9fbm90aWNlcyhqUXVlcnkoJy53b29jb21tZXJjZS1ub3RpY2VzLXdyYXBwZXInKSlcbiAgICB9XG5cbiAgICBwcmVwYXJlTWVzc2FnZXNMaXN0KClcbiAgICB7XG4gICAgICAgIGlmKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKXtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXNMaXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndWwnKTtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnd29vY29tbWVyY2UtZXJyb3InKTtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LnNldEF0dHJpYnV0ZSgncm9sZScsICdhbGVydCcpO1xuICAgICAgICAgICAgdGhpcy53cmFwcGVyLmFwcGVuZENoaWxkKHRoaXMubWVzc2FnZXNMaXN0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByZXBhcmVNZXNzYWdlc0xpc3RJdGVtKG1lc3NhZ2UpXG4gICAge1xuICAgICAgICBjb25zdCBsaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7XG4gICAgICAgIGxpLmlubmVySFRNTCA9IG1lc3NhZ2U7XG5cbiAgICAgICAgcmV0dXJuIGxpO1xuICAgIH1cblxuICAgIHNhbml0aXplKHRleHQpXG4gICAge1xuICAgICAgICBjb25zdCB0ZXh0YXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgICAgIHRleHRhcmVhLmlubmVySFRNTCA9IHRleHQ7XG4gICAgICAgIHJldHVybiB0ZXh0YXJlYS52YWx1ZS5yZXBsYWNlKCdFcnJvcjogJywgJycpO1xuICAgIH1cblxuICAgIGNsZWFyKClcbiAgICB7XG4gICAgICAgIGlmICh0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QuaW5uZXJIVE1MID0gJyc7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFcnJvckhhbmRsZXI7XG4iLCJjb25zdCBvbkFwcHJvdmUgPSAoY29udGV4dCwgZXJyb3JIYW5kbGVyKSA9PiB7XG4gICAgcmV0dXJuIChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklELFxuICAgICAgICAgICAgICAgIGZ1bmRpbmdfc291cmNlOiB3aW5kb3cucHBjcEZ1bmRpbmdTb3VyY2UsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhdGlvbi5ocmVmID0gY29udGV4dC5jb25maWcucmVkaXJlY3Q7XG4gICAgICAgIH0pO1xuXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBvbkFwcHJvdmU7XG4iLCJleHBvcnQgY29uc3QgcGF5ZXJEYXRhID0gKCkgPT4ge1xuICAgIGNvbnN0IHBheWVyID0gUGF5UGFsQ29tbWVyY2VHYXRld2F5LnBheWVyO1xuICAgIGlmICghIHBheWVyKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHBob25lID0gKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykgfHwgdHlwZW9mIHBheWVyLnBob25lICE9PSAndW5kZWZpbmVkJykgP1xuICAgIHtcbiAgICAgICAgcGhvbmVfdHlwZTpcIkhPTUVcIixcbiAgICAgICAgICAgIHBob25lX251bWJlcjp7XG4gICAgICAgICAgICBuYXRpb25hbF9udW1iZXIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpLnZhbHVlIDogcGF5ZXIucGhvbmUucGhvbmVfbnVtYmVyLm5hdGlvbmFsX251bWJlclxuICAgICAgICB9XG4gICAgfSA6IG51bGw7XG4gICAgY29uc3QgcGF5ZXJEYXRhID0ge1xuICAgICAgICBlbWFpbF9hZGRyZXNzOihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2VtYWlsJykudmFsdWUgOiBwYXllci5lbWFpbF9hZGRyZXNzLFxuICAgICAgICBuYW1lIDoge1xuICAgICAgICAgICAgc3VybmFtZTogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2xhc3RfbmFtZScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2xhc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5zdXJuYW1lLFxuICAgICAgICAgICAgZ2l2ZW5fbmFtZTogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2ZpcnN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykudmFsdWUgOiBwYXllci5uYW1lLmdpdmVuX25hbWVcbiAgICAgICAgfSxcbiAgICAgICAgYWRkcmVzcyA6IHtcbiAgICAgICAgICAgIGNvdW50cnlfY29kZSA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jb3VudHJ5JykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpLnZhbHVlIDogcGF5ZXIuYWRkcmVzcy5jb3VudHJ5X2NvZGUsXG4gICAgICAgICAgICBhZGRyZXNzX2xpbmVfMSA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19hZGRyZXNzXzEnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19hZGRyZXNzXzEnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRkcmVzc19saW5lXzEsXG4gICAgICAgICAgICBhZGRyZXNzX2xpbmVfMiA6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19hZGRyZXNzXzInKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19hZGRyZXNzXzInKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRkcmVzc19saW5lXzIsXG4gICAgICAgICAgICBhZG1pbl9hcmVhXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19zdGF0ZScpLnZhbHVlIDogcGF5ZXIuYWRkcmVzcy5hZG1pbl9hcmVhXzEsXG4gICAgICAgICAgICBhZG1pbl9hcmVhXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY2l0eScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8yLFxuICAgICAgICAgICAgcG9zdGFsX2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19wb3N0Y29kZScpLnZhbHVlIDogcGF5ZXIuYWRkcmVzcy5wb3N0YWxfY29kZVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGlmIChwaG9uZSkge1xuICAgICAgICBwYXllckRhdGEucGhvbmUgPSBwaG9uZTtcbiAgICB9XG4gICAgcmV0dXJuIHBheWVyRGF0YTtcbn1cbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JDb250aW51ZS5qcyc7XG5pbXBvcnQge3BheWVyRGF0YX0gZnJvbSBcIi4uL0hlbHBlci9QYXllckRhdGFcIjtcblxuY2xhc3MgQ2FydEFjdGlvbkhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnLCBlcnJvckhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgIH1cblxuICAgIGNvbmZpZ3VyYXRpb24oKSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZU9yZGVyID0gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWVyID0gcGF5ZXJEYXRhKCk7XG4gICAgICAgICAgICBjb25zdCBibkNvZGUgPSB0eXBlb2YgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gIT09ICd1bmRlZmluZWQnID9cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgcmV0dXJuIGZldGNoKHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgICAgIHB1cmNoYXNlX3VuaXRzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgYm5fY29kZTpibkNvZGUsXG4gICAgICAgICAgICAgICAgICAgIHBheWVyLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHRcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24ocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENhcnRBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuXG5jbGFzcyBNaW5pQ2FydEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIHRoaXMuYWN0aW9uSGFuZGxlciA9IG51bGw7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLm9uKCd3Y19mcmFnbWVudHNfbG9hZGVkIHdjX2ZyYWdtZW50c19yZWZyZXNoZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24ubWluaV9jYXJ0X3dyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyKSAhPT1cbiAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMubWluaV9jYXJ0X3dyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBNaW5pQ2FydEJvb3RzdGFwOyIsImltcG9ydCBQcm9kdWN0IGZyb20gXCIuLi9FbnRpdHkvUHJvZHVjdFwiO1xuY2xhc3MgVXBkYXRlQ2FydCB7XG5cbiAgICBjb25zdHJ1Y3RvcihlbmRwb2ludCwgbm9uY2UpXG4gICAge1xuICAgICAgICB0aGlzLmVuZHBvaW50ID0gZW5kcG9pbnQ7XG4gICAgICAgIHRoaXMubm9uY2UgPSBub25jZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSBvblJlc29sdmVcbiAgICAgKiBAcGFyYW0ge1Byb2R1Y3RbXX0gcHJvZHVjdHNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx1bmtub3duPn1cbiAgICAgKi9cbiAgICB1cGRhdGUob25SZXNvbHZlLCBwcm9kdWN0cylcbiAgICB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBmZXRjaChcbiAgICAgICAgICAgICAgICB0aGlzLmVuZHBvaW50LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMsXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKFxuICAgICAgICAgICAgICAgIChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0Lmpzb24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChyZXN1bHQuZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZWQgPSBvblJlc29sdmUocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc29sdmVkKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICB9KTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVwZGF0ZUNhcnQ7IiwiLyoqXG4gKiBXaGVuIHlvdSBjYW4ndCBhZGQgc29tZXRoaW5nIHRvIHRoZSBjYXJ0LCB0aGUgUGF5UGFsIGJ1dHRvbnMgc2hvdWxkIG5vdCBzaG93LlxuICogVGhlcmVmb3JlIHdlIGxpc3RlbiBmb3IgY2hhbmdlcyBvbiB0aGUgYWRkIHRvIGNhcnQgYnV0dG9uIGFuZCBzaG93L2hpZGUgdGhlIGJ1dHRvbnMgYWNjb3JkaW5nbHkuXG4gKi9cblxuY2xhc3MgQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIHtcbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50LCBzaG93Q2FsbGJhY2ssIGhpZGVDYWxsYmFjaylcbiAgICB7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc2hvd0NhbGxiYWNrID0gc2hvd0NhbGxiYWNrO1xuICAgICAgICB0aGlzLmhpZGVDYWxsYmFjayA9IGhpZGVDYWxsYmFjaztcbiAgICAgICAgdGhpcy5vYnNlcnZlciA9IG51bGw7XG4gICAgfVxuXG4gICAgaW5pdCgpXG4gICAge1xuICAgICAgICBjb25zdCBjb25maWcgPSB7IGF0dHJpYnV0ZXMgOiB0cnVlIH07XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2Rpc2FibGVkJykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVDYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2hvd0NhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGNhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5vYnNlcnZlci5vYnNlcnZlKHRoaXMuZWxlbWVudCwgY29uZmlnKTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICBkaXNjb25uZWN0KClcbiAgICB7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQnV0dG9uc1RvZ2dsZUxpc3RlbmVyOyIsImNsYXNzIFByb2R1Y3Qge1xuXG4gICAgY29uc3RydWN0b3IoaWQsIHF1YW50aXR5LCB2YXJpYXRpb25zKSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgdGhpcy5xdWFudGl0eSA9IHF1YW50aXR5O1xuICAgICAgICB0aGlzLnZhcmlhdGlvbnMgPSB2YXJpYXRpb25zO1xuICAgIH1cblxuICAgIGRhdGEoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpZDp0aGlzLmlkLFxuICAgICAgICAgICAgcXVhbnRpdHk6dGhpcy5xdWFudGl0eSxcbiAgICAgICAgICAgIHZhcmlhdGlvbnM6dGhpcy52YXJpYXRpb25zXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFByb2R1Y3Q7IiwiaW1wb3J0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciBmcm9tICcuLi9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyJztcbmltcG9ydCBQcm9kdWN0IGZyb20gJy4uL0VudGl0eS9Qcm9kdWN0JztcbmltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JDb250aW51ZSc7XG5pbXBvcnQge3BheWVyRGF0YX0gZnJvbSBcIi4uL0hlbHBlci9QYXllckRhdGFcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgdXBkYXRlQ2FydCxcbiAgICAgICAgc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICBoaWRlQnV0dG9uQ2FsbGJhY2ssXG4gICAgICAgIGZvcm1FbGVtZW50LFxuICAgICAgICBlcnJvckhhbmRsZXJcbiAgICApIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgICAgIHRoaXMudXBkYXRlQ2FydCA9IHVwZGF0ZUNhcnQ7XG4gICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrID0gc2hvd0J1dHRvbkNhbGxiYWNrO1xuICAgICAgICB0aGlzLmhpZGVCdXR0b25DYWxsYmFjayA9IGhpZGVCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5mb3JtRWxlbWVudCA9IGZvcm1FbGVtZW50O1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKClcbiAgICB7XG5cbiAgICAgICAgaWYgKCB0aGlzLmhhc1ZhcmlhdGlvbnMoKSApIHtcbiAgICAgICAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaW5nbGVfYWRkX3RvX2NhcnRfYnV0dG9uJyksXG4gICAgICAgICAgICAgICAgdGhpcy5zaG93QnV0dG9uQ2FsbGJhY2ssXG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2tcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBvYnNlcnZlci5pbml0KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IHRoaXMuY3JlYXRlT3JkZXIoKSxcbiAgICAgICAgICAgIG9uQXBwcm92ZTogb25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyKSxcbiAgICAgICAgICAgIG9uRXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY3JlYXRlT3JkZXIoKVxuICAgIHtcbiAgICAgICAgdmFyIGdldFByb2R1Y3RzID0gbnVsbDtcbiAgICAgICAgaWYgKCEgdGhpcy5pc0dyb3VwZWRQcm9kdWN0KCkgKSB7XG4gICAgICAgICAgICBnZXRQcm9kdWN0cyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tuYW1lPVwiYWRkLXRvLWNhcnRcIl0nKS52YWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBxdHkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cInF1YW50aXR5XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFyaWF0aW9ucyA9IHRoaXMudmFyaWF0aW9ucygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBbbmV3IFByb2R1Y3QoaWQsIHF0eSwgdmFyaWF0aW9ucyldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvZHVjdHMgPSBbXTtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W3R5cGU9XCJudW1iZXJcIl0nKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIGVsZW1lbnQudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbGVtZW50TmFtZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCduYW1lJykubWF0Y2goL3F1YW50aXR5XFxbKFtcXGRdKilcXF0vKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnROYW1lLmxlbmd0aCAhPT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gcGFyc2VJbnQoZWxlbWVudE5hbWVbMV0pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWFudGl0eSA9IHBhcnNlSW50KGVsZW1lbnQudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICBwcm9kdWN0cy5wdXNoKG5ldyBQcm9kdWN0KGlkLCBxdWFudGl0eSwgbnVsbCkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb2R1Y3RzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNyZWF0ZU9yZGVyID0gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgICAgIGNvbnN0IG9uUmVzb2x2ZSA9IChwdXJjaGFzZV91bml0cykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBheWVyID0gcGF5ZXJEYXRhKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZldGNoKHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgYm5fY29kZTpibkNvZGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHRcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMudXBkYXRlQ2FydC51cGRhdGUob25SZXNvbHZlLCBnZXRQcm9kdWN0cygpKTtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gY3JlYXRlT3JkZXI7XG4gICAgfVxuXG4gICAgdmFyaWF0aW9ucygpXG4gICAge1xuXG4gICAgICAgIGlmICghIHRoaXMuaGFzVmFyaWF0aW9ucygpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0gWy4uLnRoaXMuZm9ybUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltuYW1lXj0nYXR0cmlidXRlXyddXCIpXS5tYXAoXG4gICAgICAgICAgICAoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6ZWxlbWVudC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTplbGVtZW50Lm5hbWVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgIH1cblxuICAgIGhhc1ZhcmlhdGlvbnMoKVxuICAgIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybUVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCd2YXJpYXRpb25zX2Zvcm0nKTtcbiAgICB9XG5cbiAgICBpc0dyb3VwZWRQcm9kdWN0KClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnZ3JvdXBlZF9mb3JtJyk7XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXI7XG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgVXBkYXRlQ2FydCBmcm9tIFwiLi4vSGVscGVyL1VwZGF0ZUNhcnRcIjtcbmltcG9ydCBTaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlciBmcm9tIFwiLi4vQWN0aW9uSGFuZGxlci9TaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlclwiO1xuXG5jbGFzcyBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcykge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlcztcbiAgICB9XG5cbiAgICBpbml0KCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JykgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgYWN0aW9uSGFuZGxlciA9IG5ldyBTaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBVcGRhdGVDYXJ0KFxuICAgICAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5hamF4LmNoYW5nZV9jYXJ0LmVuZHBvaW50LFxuICAgICAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5hamF4LmNoYW5nZV9jYXJ0Lm5vbmNlLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICBsZXQgcHJpY2VUZXh0ID0gXCIwXCI7XG4gICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCBpbnMgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIHByaWNlVGV4dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCBpbnMgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpLmlubmVyVGV4dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpLmlubmVyVGV4dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgYW1vdW50ID0gcGFyc2VJbnQocHJpY2VUZXh0LnJlcGxhY2UoLyhbXlxcZCxcXC5cXHNdKikvZywgJycpKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnJlbmRlcldpdGhBbW91bnQoYW1vdW50KVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQnKSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsXG4gICAgICAgICAgICBhY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RCb290c3RhcDsiLCJpbXBvcnQgQ2FydEFjdGlvbkhhbmRsZXIgZnJvbSAnLi4vQWN0aW9uSGFuZGxlci9DYXJ0QWN0aW9uSGFuZGxlcic7XG5pbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5cbmNsYXNzIENhcnRCb290c3RyYXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyKSB7XG4gICAgICAgIHRoaXMuZ2F0ZXdheSA9IGdhdGV3YXk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIgPSByZW5kZXJlcjtcbiAgICB9XG5cbiAgICBpbml0KCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLm9uKCd1cGRhdGVkX2NhcnRfdG90YWxzIHVwZGF0ZWRfY2hlY2tvdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcikgIT09XG4gICAgICAgICAgICBudWxsIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcikgIT09XG4gICAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgYWN0aW9uSGFuZGxlciA9IG5ldyBDYXJ0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsXG4gICAgICAgICAgICBhY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENhcnRCb290c3RyYXA7XG4iLCJjb25zdCBvbkFwcHJvdmUgPSAoY29udGV4dCwgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSA9PiB7XG4gICAgcmV0dXJuIChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgIHNwaW5uZXIuYmxvY2soKTtcbiAgICAgICAgZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgcmV0dXJuIGZldGNoKGNvbnRleHQuY29uZmlnLmFqYXguYXBwcm92ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgbm9uY2U6IGNvbnRleHQuY29uZmlnLmFqYXguYXBwcm92ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICBvcmRlcl9pZDpkYXRhLm9yZGVySUQsXG4gICAgICAgICAgICAgICAgZnVuZGluZ19zb3VyY2U6IHdpbmRvdy5wcGNwRnVuZGluZ1NvdXJjZSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pLnRoZW4oKHJlcyk9PntcbiAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICB9KS50aGVuKChkYXRhKT0+e1xuICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhLmRhdGEuY29kZSA9PT0gMTAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5tZXNzYWdlKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYWN0aW9ucyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGFjdGlvbnMucmVzdGFydCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjdGlvbnMucmVzdGFydCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BsYWNlX29yZGVyJykuY2xpY2soKVxuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiaW1wb3J0IG9uQXBwcm92ZSBmcm9tICcuLi9PbkFwcHJvdmVIYW5kbGVyL29uQXBwcm92ZUZvclBheU5vdy5qcyc7XG5pbXBvcnQge3BheWVyRGF0YX0gZnJvbSBcIi4uL0hlbHBlci9QYXllckRhdGFcIjtcblxuY2xhc3MgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICAgICAgdGhpcy5zcGlubmVyID0gc3Bpbm5lcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBzcGlubmVyID0gdGhpcy5zcGlubmVyO1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JIYW5kbGVyID0gdGhpcy5lcnJvckhhbmRsZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IGZvcm1TZWxlY3RvciA9IHRoaXMuY29uZmlnLmNvbnRleHQgPT09ICdjaGVja291dCcgPyAnZm9ybS5jaGVja291dCcgOiAnZm9ybSNvcmRlcl9yZXZpZXcnO1xuICAgICAgICAgICAgY29uc3QgZm9ybVZhbHVlcyA9IGpRdWVyeShmb3JtU2VsZWN0b3IpLnNlcmlhbGl6ZSgpO1xuXG4gICAgICAgICAgICBjb25zdCBjcmVhdGVhY2NvdW50ID0galF1ZXJ5KCcjY3JlYXRlYWNjb3VudCcpLmlzKFwiOmNoZWNrZWRcIikgPyB0cnVlIDogZmFsc2U7XG5cbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgYm5fY29kZTpibkNvZGUsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6dGhpcy5jb25maWcuY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgb3JkZXJfaWQ6dGhpcy5jb25maWcub3JkZXJfaWQsXG4gICAgICAgICAgICAgICAgICAgIGZvcm06Zm9ybVZhbHVlcyxcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlYWNjb3VudDogY3JlYXRlYWNjb3VudFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgICAgICAgICAgLy9oYW5kbGUgYm90aCBtZXNzYWdlcyBzZW50IGZyb20gV29vY29tbWVyY2UgKGRhdGEubWVzc2FnZXMpIGFuZCB0aGlzIHBsdWdpbiAoZGF0YS5kYXRhLm1lc3NhZ2UpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YoZGF0YS5tZXNzYWdlcykgIT09ICd1bmRlZmluZWQnIClcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZG9tUGFyc2VyID0gbmV3IERPTVBhcnNlcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb21QYXJzZXIucGFyc2VGcm9tU3RyaW5nKGRhdGEubWVzc2FnZXMsICd0ZXh0L2h0bWwnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucXVlcnlTZWxlY3RvcigndWwnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5tZXNzYWdlKGRhdGEuZGF0YS5tZXNzYWdlLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgndHlwZScsICdoaWRkZW4nKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ25hbWUnLCAncHBjcC1yZXN1bWUtb3JkZXInKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3ZhbHVlJywgZGF0YS5kYXRhLnB1cmNoYXNlX3VuaXRzWzBdLmN1c3RvbV9pZCk7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtU2VsZWN0b3IpLmFwcGVuZChpbnB1dCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjcmVhdGVPcmRlcixcbiAgICAgICAgICAgIG9uQXBwcm92ZTpvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIsIHRoaXMuc3Bpbm5lciksXG4gICAgICAgICAgICBvbkNhbmNlbDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9uRXJyb3I6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyO1xuIiwiY29uc3QgZ2V0RWxlbWVudCA9IChzZWxlY3Rvck9yRWxlbWVudCkgPT4ge1xuICAgIGlmICh0eXBlb2Ygc2VsZWN0b3JPckVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yT3JFbGVtZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHNlbGVjdG9yT3JFbGVtZW50O1xufVxuXG5leHBvcnQgY29uc3QgaXNWaXNpYmxlID0gKGVsZW1lbnQpID0+IHtcbiAgICByZXR1cm4gISEoZWxlbWVudC5vZmZzZXRXaWR0aCB8fCBlbGVtZW50Lm9mZnNldEhlaWdodCB8fCBlbGVtZW50LmdldENsaWVudFJlY3RzKCkubGVuZ3RoKTtcbn1cblxuZXhwb3J0IGNvbnN0IHNldFZpc2libGUgPSAoc2VsZWN0b3JPckVsZW1lbnQsIHNob3csIGltcG9ydGFudCA9IGZhbHNlKSA9PiB7XG4gICAgY29uc3QgZWxlbWVudCA9IGdldEVsZW1lbnQoc2VsZWN0b3JPckVsZW1lbnQpO1xuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudFZhbHVlID0gZWxlbWVudC5zdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCdkaXNwbGF5Jyk7XG5cbiAgICBpZiAoIXNob3cpIHtcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA9PT0gJ25vbmUnKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBlbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCdkaXNwbGF5JywgJ25vbmUnLCBpbXBvcnRhbnQgPyAnaW1wb3J0YW50JyA6ICcnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlID09PSAnbm9uZScpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUucmVtb3ZlUHJvcGVydHkoJ2Rpc3BsYXknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHN0aWxsIG5vdCB2aXNpYmxlIChpZiBzb21ldGhpbmcgZWxzZSBhZGRlZCBkaXNwbGF5OiBub25lIGluIENTUylcbiAgICAgICAgaWYgKCFpc1Zpc2libGUoZWxlbWVudCkpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJ2Rpc3BsYXknLCAnYmxvY2snKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbmV4cG9ydCBjb25zdCBoaWRlID0gKHNlbGVjdG9yT3JFbGVtZW50LCBpbXBvcnRhbnQgPSBmYWxzZSkgPT4ge1xuICAgIHNldFZpc2libGUoc2VsZWN0b3JPckVsZW1lbnQsIGZhbHNlLCBpbXBvcnRhbnQpO1xufTtcblxuZXhwb3J0IGNvbnN0IHNob3cgPSAoc2VsZWN0b3JPckVsZW1lbnQpID0+IHtcbiAgICBzZXRWaXNpYmxlKHNlbGVjdG9yT3JFbGVtZW50LCB0cnVlKTtcbn07XG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2hlY2tvdXRBY3Rpb25IYW5kbGVyJztcbmltcG9ydCB7IHNldFZpc2libGUgfSBmcm9tICcuLi9IZWxwZXIvSGlkaW5nJztcblxuY2xhc3MgQ2hlY2tvdXRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIsIG1lc3NhZ2VzLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuZ2F0ZXdheSA9IGdhdGV3YXk7XG4gICAgICAgIHRoaXMucmVuZGVyZXIgPSByZW5kZXJlcjtcbiAgICAgICAgdGhpcy5tZXNzYWdlcyA9IG1lc3NhZ2VzO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuXG4gICAgICAgIHRoaXMuc3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yID0gJyNwbGFjZV9vcmRlcic7XG5cbiAgICAgICAgdGhpcy5idXR0b25DaGFuZ2VPYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChlbCkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBpbml0KCkge1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIC8vIFVuc2VsZWN0IHNhdmVkIGNhcmQuXG4gICAgICAgIC8vIFdDIHNhdmVzIGZvcm0gdmFsdWVzLCBzbyB3aXRoIG91ciBjdXJyZW50IFVJIGl0IHdvdWxkIGJlIGEgYml0IHdlaXJkXG4gICAgICAgIC8vIGlmIHRoZSB1c2VyIHBhaWQgd2l0aCBzYXZlZCwgdGhlbiBhZnRlciBzb21lIHRpbWUgdHJpZXMgdG8gcGF5IGFnYWluLFxuICAgICAgICAvLyBidXQgd2FudHMgdG8gZW50ZXIgYSBuZXcgY2FyZCwgYW5kIHRvIGRvIHRoYXQgdGhleSBoYXZlIHRvIGNob29zZSDigJxTZWxlY3QgcGF5bWVudOKAnSBpbiB0aGUgbGlzdC5cbiAgICAgICAgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQgb3B0aW9uOmZpcnN0JykudmFsKCkpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKClcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLm9uKCd1cGRhdGVkX2NoZWNrb3V0IHBheW1lbnRfbWV0aG9kX3NlbGVjdGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQpLm9uKCdob3N0ZWRfZmllbGRzX2xvYWRlZCcsICgpID0+IHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkJykub24oJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVVpKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnVwZGF0ZVVpKCk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLmNhbmNlbF93cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKSAhPT0gbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PSBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2JykpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2Jykuc2V0QXR0cmlidXRlKCdzdHlsZScsICcnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IENoZWNrb3V0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuYnV0dG9uQ2hhbmdlT2JzZXJ2ZXIub2JzZXJ2ZShcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5zdGFuZGFyZE9yZGVyQnV0dG9uU2VsZWN0b3IpLFxuICAgICAgICAgICAge2F0dHJpYnV0ZXM6IHRydWV9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgdXBkYXRlVWkoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0gdGhpcy5jdXJyZW50UGF5bWVudE1ldGhvZCgpO1xuICAgICAgICBjb25zdCBpc1BheXBhbCA9IGN1cnJlbnRQYXltZW50TWV0aG9kID09PSAncHBjcC1nYXRld2F5JztcbiAgICAgICAgY29uc3QgaXNDYXJkID0gY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknO1xuICAgICAgICBjb25zdCBpc1NhdmVkQ2FyZCA9IGlzQ2FyZCAmJiB0aGlzLmlzU2F2ZWRDYXJkU2VsZWN0ZWQoKTtcbiAgICAgICAgY29uc3QgaXNOb3RPdXJHYXRld2F5ID0gIWlzUGF5cGFsICYmICFpc0NhcmQ7XG5cbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLnN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciwgaXNOb3RPdXJHYXRld2F5IHx8IGlzU2F2ZWRDYXJkLCB0cnVlKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsIGlzUGF5cGFsKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlciwgaXNQYXlwYWwpO1xuICAgICAgICBzZXRWaXNpYmxlKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsIGlzQ2FyZCAmJiAhaXNTYXZlZENhcmQpO1xuXG4gICAgICAgIGlmIChpc1BheXBhbCkge1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0NhcmQpIHtcbiAgICAgICAgICAgIGlmIChpc1NhdmVkQ2FyZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVDcmVkaXRDYXJkRmllbGRzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcygpIHtcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXInKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeVwiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJ2YXVsdFwiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYXR0cihcImRpc2FibGVkXCIsIHRydWUpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKVxuICAgIH1cblxuICAgIGVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCBmYWxzZSlcbiAgICAgICAgdGhpcy5yZW5kZXJlci5lbmFibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBjdXJyZW50UGF5bWVudE1ldGhvZCgpIHtcbiAgICAgICAgcmV0dXJuIGpRdWVyeSgnaW5wdXRbbmFtZT1cInBheW1lbnRfbWV0aG9kXCJdOmNoZWNrZWQnKS52YWwoKTtcbiAgICB9XG5cbiAgICBpc1NhdmVkQ2FyZFNlbGVjdGVkKCkge1xuICAgICAgICBjb25zdCBzYXZlZENhcmRMaXN0ID0galF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKTtcbiAgICAgICAgcmV0dXJuIHNhdmVkQ2FyZExpc3QubGVuZ3RoICYmIHNhdmVkQ2FyZExpc3QudmFsKCkgIT09ICcnO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2hlY2tvdXRCb290c3RhcFxuIiwiaW1wb3J0IENoZWNrb3V0Qm9vdHN0YXAgZnJvbSAnLi9DaGVja291dEJvb3RzdGFwJ1xuXG5jbGFzcyBQYXlOb3dCb290c3RyYXAgZXh0ZW5kcyBDaGVja291dEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgc3VwZXIoZ2F0ZXdheSwgcmVuZGVyZXIsIG1lc3NhZ2VzLCBzcGlubmVyKVxuICAgIH1cblxuICAgIHVwZGF0ZVVpKCkge1xuICAgICAgICBjb25zdCB1cmxQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpXG4gICAgICAgIGlmICh1cmxQYXJhbXMuaGFzKCdjaGFuZ2VfcGF5bWVudF9tZXRob2QnKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBzdXBlci51cGRhdGVVaSgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUGF5Tm93Qm9vdHN0cmFwO1xuIiwiY2xhc3MgUmVuZGVyZXIge1xuICAgIGNvbnN0cnVjdG9yKGNyZWRpdENhcmRSZW5kZXJlciwgZGVmYXVsdENvbmZpZywgb25TbWFydEJ1dHRvbkNsaWNrKSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWc7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyID0gY3JlZGl0Q2FyZFJlbmRlcmVyO1xuICAgICAgICB0aGlzLm9uU21hcnRCdXR0b25DbGljayA9IG9uU21hcnRCdXR0b25DbGljaztcbiAgICB9XG5cbiAgICByZW5kZXIod3JhcHBlciwgaG9zdGVkRmllbGRzV3JhcHBlciwgY29udGV4dENvbmZpZykge1xuXG4gICAgICAgIHRoaXMucmVuZGVyQnV0dG9ucyh3cmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIucmVuZGVyKGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpO1xuICAgIH1cblxuICAgIHJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZykge1xuICAgICAgICBpZiAoISBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpIHx8IHRoaXMuaXNBbHJlYWR5UmVuZGVyZWQod3JhcHBlcikgfHwgJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiBwYXlwYWwuQnV0dG9ucyApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0eWxlID0gd3JhcHBlciA9PT0gdGhpcy5kZWZhdWx0Q29uZmlnLmJ1dHRvbi53cmFwcGVyID8gdGhpcy5kZWZhdWx0Q29uZmlnLmJ1dHRvbi5zdHlsZSA6IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ubWluaV9jYXJ0X3N0eWxlO1xuICAgICAgICBwYXlwYWwuQnV0dG9ucyh7XG4gICAgICAgICAgICBzdHlsZSxcbiAgICAgICAgICAgIC4uLmNvbnRleHRDb25maWcsXG4gICAgICAgICAgICBvbkNsaWNrOiB0aGlzLm9uU21hcnRCdXR0b25DbGljayxcbiAgICAgICAgfSkucmVuZGVyKHdyYXBwZXIpO1xuICAgIH1cblxuICAgIGlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikuaGFzQ2hpbGROb2RlcygpO1xuICAgIH1cblxuICAgIGhpZGVCdXR0b25zKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgICAgIGlmICghIGRvbUVsZW1lbnQgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZG9tRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBzaG93QnV0dG9ucyhlbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGRvbUVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsZW1lbnQpO1xuICAgICAgICBpZiAoISBkb21FbGVtZW50ICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGRvbUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGRpc2FibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5kaXNhYmxlRmllbGRzKCk7XG4gICAgfVxuXG4gICAgZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpIHtcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIuZW5hYmxlRmllbGRzKCk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSZW5kZXJlcjtcbiIsImNvbnN0IGRjY0lucHV0RmFjdG9yeSA9IChvcmlnaW5hbCkgPT4ge1xuICAgIGNvbnN0IHN0eWxlcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKG9yaWdpbmFsKTtcbiAgICBjb25zdCBuZXdFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIG5ld0VsZW1lbnQuc2V0QXR0cmlidXRlKCdpZCcsIG9yaWdpbmFsLmlkKTtcbiAgICBPYmplY3QudmFsdWVzKHN0eWxlcykuZm9yRWFjaCggKHByb3ApID0+IHtcbiAgICAgICAgaWYgKCEgc3R5bGVzW3Byb3BdIHx8ICEgaXNOYU4ocHJvcCkgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbmV3RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eShwcm9wLCcnICsgc3R5bGVzW3Byb3BdKTtcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3RWxlbWVudDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZGNjSW5wdXRGYWN0b3J5OyIsImltcG9ydCBkY2NJbnB1dEZhY3RvcnkgZnJvbSBcIi4uL0hlbHBlci9EY2NJbnB1dEZhY3RvcnlcIjtcblxuY2xhc3MgQ3JlZGl0Q2FyZFJlbmRlcmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGRlZmF1bHRDb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcgPSBkZWZhdWx0Q29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICAgICAgdGhpcy5zcGlubmVyID0gc3Bpbm5lcjtcbiAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5mb3JtVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UgPSBudWxsO1xuICAgICAgICB0aGlzLmZvcm1TdWJtaXNzaW9uU3Vic2NyaWJlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIHJlbmRlcih3cmFwcGVyLCBjb250ZXh0Q29uZmlnKSB7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZy5jb250ZXh0ICE9PSAnY2hlY2tvdXQnXG4gICAgICAgICAgICAgICAgJiYgdGhpcy5kZWZhdWx0Q29uZmlnLmNvbnRleHQgIT09ICdwYXktbm93J1xuICAgICAgICAgICAgKVxuICAgICAgICAgICAgfHwgd3JhcHBlciA9PT0gbnVsbFxuICAgICAgICAgICAgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSA9PT0gbnVsbFxuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlb2YgcGF5cGFsLkhvc3RlZEZpZWxkcyA9PT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgIHx8ICEgcGF5cGFsLkhvc3RlZEZpZWxkcy5pc0VsaWdpYmxlKClcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVyRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcik7XG4gICAgICAgICAgICB3cmFwcGVyRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHdyYXBwZXJFbGVtZW50KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UudGVhcmRvd24oKVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihgSG9zdGVkIGZpZWxkcyB0ZWFyZG93biBlcnJvcjogJHtlcnJ9YCkpO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZ2F0ZVdheUJveCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wYXltZW50X2JveC5wYXltZW50X21ldGhvZF9wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKTtcbiAgICAgICAgY29uc3Qgb2xkRGlzcGxheVN0eWxlID0gZ2F0ZVdheUJveC5zdHlsZS5kaXNwbGF5O1xuICAgICAgICBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXG4gICAgICAgIGNvbnN0IGhpZGVEY2NHYXRld2F5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtaGlkZS1kY2MnKTtcbiAgICAgICAgaWYgKGhpZGVEY2NHYXRld2F5KSB7XG4gICAgICAgICAgICBoaWRlRGNjR2F0ZXdheS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGhpZGVEY2NHYXRld2F5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNhcmROdW1iZXJGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXInKTtcblxuICAgICAgICBjb25zdCBzdHlsZXNSYXcgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBsZXQgc3R5bGVzID0ge307XG4gICAgICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzUmF3KS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICAgICAgaWYgKCEgc3R5bGVzUmF3W3Byb3BdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3R5bGVzW3Byb3BdID0gJycgKyBzdHlsZXNSYXdbcHJvcF07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNhcmROdW1iZXIgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZE51bWJlckZpZWxkKTtcbiAgICAgICAgY2FyZE51bWJlckZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmROdW1iZXIsIGNhcmROdW1iZXJGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZEV4cGlyeUZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeScpO1xuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5ID0gZGNjSW5wdXRGYWN0b3J5KGNhcmRFeHBpcnlGaWVsZCk7XG4gICAgICAgIGNhcmRFeHBpcnlGaWVsZC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjYXJkRXhwaXJ5LCBjYXJkRXhwaXJ5RmllbGQpO1xuXG4gICAgICAgIGNvbnN0IGNhcmRDb2RlRmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyk7XG4gICAgICAgIGNvbnN0IGNhcmRDb2RlID0gZGNjSW5wdXRGYWN0b3J5KGNhcmRDb2RlRmllbGQpO1xuICAgICAgICBjYXJkQ29kZUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRDb2RlLCBjYXJkQ29kZUZpZWxkKTtcblxuICAgICAgICBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXkgPSBvbGREaXNwbGF5U3R5bGU7XG5cbiAgICAgICAgY29uc3QgZm9ybVdyYXBwZXIgPSAnLnBheW1lbnRfYm94IHBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheSc7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZy5lbmZvcmNlX3ZhdWx0XG4gICAgICAgICAgICAmJiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpXG4gICAgICAgICkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5jaGVja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0Jykuc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHBheXBhbC5Ib3N0ZWRGaWVsZHMucmVuZGVyKHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiBjb250ZXh0Q29uZmlnLmNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgc3R5bGVzOiB7XG4gICAgICAgICAgICAgICAgJ2lucHV0Jzogc3R5bGVzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgICAgICAgbnVtYmVyOiB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yOiAnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuY3JlZGl0X2NhcmRfbnVtYmVyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY3Z2OiB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yOiAnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuY3Z2LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXhwaXJhdGlvbkRhdGU6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5tbV95eSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pLnRoZW4oaG9zdGVkRmllbGRzID0+IHtcbiAgICAgICAgICAgIGRvY3VtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwiaG9zdGVkX2ZpZWxkc19sb2FkZWRcIikpO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UgPSBob3N0ZWRGaWVsZHM7XG5cbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbignaW5wdXRTdWJtaXRSZXF1ZXN0JywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N1Ym1pdChjb250ZXh0Q29uZmlnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdjYXJkVHlwZUNoYW5nZScsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICggISBldmVudC5jYXJkcy5sZW5ndGggKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FyZFZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsaWRDYXJkcyA9IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLnZhbGlkX2NhcmRzO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FyZFZhbGlkID0gdmFsaWRDYXJkcy5pbmRleE9mKGV2ZW50LmNhcmRzWzBdLnR5cGUpICE9PSAtMTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ3ZhbGlkaXR5Q2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZm9ybVZhbGlkID0gT2JqZWN0LmtleXMoZXZlbnQuZmllbGRzKS5ldmVyeShmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBldmVudC5maWVsZHNba2V5XS5pc1ZhbGlkO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWQgPSBmb3JtVmFsaWQ7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkKSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyICsgJyBidXR0b24nKS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgICAgICAgICBldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1TdWJtaXNzaW9uU3Vic2NyaWJlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwYXltZW50X21ldGhvZF9wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ2NsaWNrJyxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdsYWJlbFtmb3I9cHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXScpLmNsaWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIClcbiAgICB9XG5cbiAgICBkaXNhYmxlRmllbGRzKCkge1xuICAgICAgICBpZiggdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnNldEF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdudW1iZXInLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnNldEF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdjdnYnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnNldEF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdleHBpcmF0aW9uRGF0ZScsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZW5hYmxlRmllbGRzKCkge1xuICAgICAgICBpZiggdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnJlbW92ZUF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdudW1iZXInLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnJlbW92ZUF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdjdnYnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnJlbW92ZUF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdleHBpcmF0aW9uRGF0ZScsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3N1Ym1pdChjb250ZXh0Q29uZmlnKSB7XG4gICAgICAgIHRoaXMuc3Bpbm5lci5ibG9jaygpO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgIGlmICh0aGlzLmZvcm1WYWxpZCAmJiB0aGlzLmNhcmRWYWxpZCkge1xuICAgICAgICAgICAgY29uc3Qgc2F2ZV9jYXJkID0gdGhpcy5kZWZhdWx0Q29uZmlnLnNhdmVfY2FyZCA/IHRydWUgOiBmYWxzZTtcbiAgICAgICAgICAgIGxldCB2YXVsdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykgP1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuY2hlY2tlZCA6IHNhdmVfY2FyZDtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlZmF1bHRDb25maWcuZW5mb3JjZV92YXVsdCkge1xuICAgICAgICAgICAgICAgIHZhdWx0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGNvbnRpbmdlbmN5ID0gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMuY29udGluZ2VuY3k7XG4gICAgICAgICAgICBjb25zdCBob3N0ZWRGaWVsZHNEYXRhID0ge1xuICAgICAgICAgICAgICAgIHZhdWx0OiB2YXVsdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChjb250aW5nZW5jeSAhPT0gJ05PXzNEX1NFQ1VSRScpIHtcbiAgICAgICAgICAgICAgICBob3N0ZWRGaWVsZHNEYXRhLmNvbnRpbmdlbmNpZXMgPSBbY29udGluZ2VuY3ldO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0Q29uZmlnLnBheWVyKSB7XG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jYXJkaG9sZGVyTmFtZSA9IHRoaXMuZGVmYXVsdENvbmZpZy5wYXllci5uYW1lLmdpdmVuX25hbWUgKyAnICcgKyB0aGlzLmRlZmF1bHRDb25maWcucGF5ZXIubmFtZS5zdXJuYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFob3N0ZWRGaWVsZHNEYXRhLmNhcmRob2xkZXJOYW1lKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlyc3ROYW1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JpbGxpbmdfZmlyc3RfbmFtZScpID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogJyc7XG4gICAgICAgICAgICAgICAgY29uc3QgbGFzdE5hbWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZ19sYXN0X25hbWUnKSA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2xhc3RfbmFtZScpLnZhbHVlIDogJyc7XG5cbiAgICAgICAgICAgICAgICBpZiAoIWZpcnN0TmFtZSB8fCAhbGFzdE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubWVzc2FnZSh0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuY2FyZGhvbGRlcl9uYW1lX3JlcXVpcmVkKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY2FyZGhvbGRlck5hbWUgPSBmaXJzdE5hbWUgKyAnICcgKyBsYXN0TmFtZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc3VibWl0KGhvc3RlZEZpZWxkc0RhdGEpLnRoZW4oKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLm9yZGVySUQgPSBwYXlsb2FkLm9yZGVySWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dENvbmZpZy5vbkFwcHJvdmUocGF5bG9hZCk7XG4gICAgICAgICAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9ICEgdGhpcy5jYXJkVmFsaWQgPyB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuY2FyZF9ub3Rfc3VwcG9ydGVkIDogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmZpZWxkc19ub3RfdmFsaWQ7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5tZXNzYWdlKG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgQ3JlZGl0Q2FyZFJlbmRlcmVyO1xuIiwiY29uc3Qgc3RvcmFnZUtleSA9ICdwcGNwLWRhdGEtY2xpZW50LWlkJztcblxuY29uc3QgdmFsaWRhdGVUb2tlbiA9ICh0b2tlbiwgdXNlcikgPT4ge1xuICAgIGlmICghIHRva2VuKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHRva2VuLnVzZXIgIT09IHVzZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IGlzRXhwaXJlZCA9IGN1cnJlbnRUaW1lID49IHRva2VuLmV4cGlyYXRpb24gKiAxMDAwO1xuICAgIHJldHVybiAhIGlzRXhwaXJlZDtcbn1cblxuY29uc3Qgc3RvcmVkVG9rZW5Gb3JVc2VyID0gKHVzZXIpID0+IHtcbiAgICBjb25zdCB0b2tlbiA9IEpTT04ucGFyc2Uoc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShzdG9yYWdlS2V5KSk7XG4gICAgaWYgKHZhbGlkYXRlVG9rZW4odG9rZW4sIHVzZXIpKSB7XG4gICAgICAgIHJldHVybiB0b2tlbi50b2tlbjtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbmNvbnN0IHN0b3JlVG9rZW4gPSAodG9rZW4pID0+IHtcbiAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKHN0b3JhZ2VLZXksIEpTT04uc3RyaW5naWZ5KHRva2VuKSk7XG59XG5cbmNvbnN0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIgPSAoc2NyaXB0LCBjb25maWcpID0+IHtcbiAgICBmZXRjaChjb25maWcuZW5kcG9pbnQsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIG5vbmNlOiBjb25maWcubm9uY2VcbiAgICAgICAgfSlcbiAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgIH0pLnRoZW4oKGRhdGEpPT57XG4gICAgICAgIGNvbnN0IGlzVmFsaWQgPSB2YWxpZGF0ZVRva2VuKGRhdGEsIGNvbmZpZy51c2VyKTtcbiAgICAgICAgaWYgKCFpc1ZhbGlkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RvcmVUb2tlbihkYXRhKTtcbiAgICAgICAgc2NyaXB0LnNldEF0dHJpYnV0ZSgnZGF0YS1jbGllbnQtdG9rZW4nLCBkYXRhLnRva2VuKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoc2NyaXB0KTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlcjtcbiIsImNsYXNzIE1lc3NhZ2VSZW5kZXJlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoISB0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBwYXlwYWwuTWVzc2FnZXMoe1xuICAgICAgICAgICAgYW1vdW50OiB0aGlzLmNvbmZpZy5hbW91bnQsXG4gICAgICAgICAgICBwbGFjZW1lbnQ6IHRoaXMuY29uZmlnLnBsYWNlbWVudCxcbiAgICAgICAgICAgIHN0eWxlOiB0aGlzLmNvbmZpZy5zdHlsZVxuICAgICAgICB9KS5yZW5kZXIodGhpcy5jb25maWcud3JhcHBlcik7XG4gICAgfVxuXG4gICAgcmVuZGVyV2l0aEFtb3VudChhbW91bnQpIHtcblxuICAgICAgICBpZiAoISB0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBuZXdXcmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIG5ld1dyYXBwZXIuc2V0QXR0cmlidXRlKCdpZCcsIHRoaXMuY29uZmlnLndyYXBwZXIucmVwbGFjZSgnIycsICcnKSk7XG5cbiAgICAgICAgY29uc3Qgc2libGluZyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikubmV4dFNpYmxpbmc7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikucGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpKTtcbiAgICAgICAgc2libGluZy5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShuZXdXcmFwcGVyLCBzaWJsaW5nKTtcbiAgICAgICAgcGF5cGFsLk1lc3NhZ2VzKHtcbiAgICAgICAgICAgIGFtb3VudCxcbiAgICAgICAgICAgIHBsYWNlbWVudDogdGhpcy5jb25maWcucGxhY2VtZW50LFxuICAgICAgICAgICAgc3R5bGU6IHRoaXMuY29uZmlnLnN0eWxlXG4gICAgICAgIH0pLnJlbmRlcih0aGlzLmNvbmZpZy53cmFwcGVyKTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBwYXlwYWwuTWVzc2FnZXMgPT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiB0aGlzLmNvbmZpZy53cmFwcGVyID09PSAndW5kZWZpbmVkJyApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgTWVzc2FnZVJlbmRlcmVyOyIsImNsYXNzIFNwaW5uZXIge1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gJ2Zvcm0ud29vY29tbWVyY2UtY2hlY2tvdXQnO1xuICAgIH1cblxuICAgIHNldFRhcmdldCh0YXJnZXQpIHtcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gICAgfVxuXG4gICAgYmxvY2soKSB7XG5cbiAgICAgICAgalF1ZXJ5KCB0aGlzLnRhcmdldCApLmJsb2NrKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IG51bGwsXG4gICAgICAgICAgICBvdmVybGF5Q1NTOiB7XG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJyNmZmYnLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAuNlxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmJsb2NrKCkge1xuXG4gICAgICAgIGpRdWVyeSggdGhpcy50YXJnZXQgKS51bmJsb2NrKCk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTcGlubmVyO1xuIiwiaW1wb3J0IE1pbmlDYXJ0Qm9vdHN0YXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcCc7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1NpbmdsZVByb2R1Y3RCb290c3RhcCc7XG5pbXBvcnQgQ2FydEJvb3RzdHJhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAnO1xuaW1wb3J0IENoZWNrb3V0Qm9vdHN0YXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2hlY2tvdXRCb290c3RhcCc7XG5pbXBvcnQgUGF5Tm93Qm9vdHN0cmFwIGZyb20gXCIuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9QYXlOb3dCb290c3RyYXBcIjtcbmltcG9ydCBSZW5kZXJlciBmcm9tICcuL21vZHVsZXMvUmVuZGVyZXIvUmVuZGVyZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuL21vZHVsZXMvRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDcmVkaXRDYXJkUmVuZGVyZXIgZnJvbSBcIi4vbW9kdWxlcy9SZW5kZXJlci9DcmVkaXRDYXJkUmVuZGVyZXJcIjtcbmltcG9ydCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyIGZyb20gXCIuL21vZHVsZXMvRGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlclwiO1xuaW1wb3J0IE1lc3NhZ2VSZW5kZXJlciBmcm9tIFwiLi9tb2R1bGVzL1JlbmRlcmVyL01lc3NhZ2VSZW5kZXJlclwiO1xuaW1wb3J0IFNwaW5uZXIgZnJvbSBcIi4vbW9kdWxlcy9IZWxwZXIvU3Bpbm5lclwiO1xuXG5jb25zdCBib290c3RyYXAgPSAoKSA9PiB7XG4gICAgY29uc3QgZXJyb3JIYW5kbGVyID0gbmV3IEVycm9ySGFuZGxlcihQYXlQYWxDb21tZXJjZUdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpO1xuICAgIGNvbnN0IHNwaW5uZXIgPSBuZXcgU3Bpbm5lcigpO1xuICAgIGNvbnN0IGNyZWRpdENhcmRSZW5kZXJlciA9IG5ldyBDcmVkaXRDYXJkUmVuZGVyZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5LCBlcnJvckhhbmRsZXIsIHNwaW5uZXIpO1xuICAgIGNvbnN0IG9uU21hcnRCdXR0b25DbGljayA9IGRhdGEgPT4ge1xuICAgICAgICB3aW5kb3cucHBjcEZ1bmRpbmdTb3VyY2UgPSBkYXRhLmZ1bmRpbmdTb3VyY2U7XG4gICAgfTtcbiAgICBjb25zdCByZW5kZXJlciA9IG5ldyBSZW5kZXJlcihjcmVkaXRDYXJkUmVuZGVyZXIsIFBheVBhbENvbW1lcmNlR2F0ZXdheSwgb25TbWFydEJ1dHRvbkNsaWNrKTtcbiAgICBjb25zdCBtZXNzYWdlUmVuZGVyZXIgPSBuZXcgTWVzc2FnZVJlbmRlcmVyKFBheVBhbENvbW1lcmNlR2F0ZXdheS5tZXNzYWdlcyk7XG4gICAgY29uc3QgY29udGV4dCA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5jb250ZXh0O1xuICAgIGlmIChjb250ZXh0ID09PSAnbWluaS1jYXJ0JyB8fCBjb250ZXh0ID09PSAncHJvZHVjdCcpIHtcbiAgICAgICAgaWYgKFBheVBhbENvbW1lcmNlR2F0ZXdheS5taW5pX2NhcnRfYnV0dG9uc19lbmFibGVkID09PSAnMScpIHtcbiAgICAgICAgICAgIGNvbnN0IG1pbmlDYXJ0Qm9vdHN0cmFwID0gbmV3IE1pbmlDYXJ0Qm9vdHN0YXAoXG4gICAgICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgICAgIHJlbmRlcmVyXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBtaW5pQ2FydEJvb3RzdHJhcC5pbml0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ3Byb2R1Y3QnICYmIFBheVBhbENvbW1lcmNlR2F0ZXdheS5zaW5nbGVfcHJvZHVjdF9idXR0b25zX2VuYWJsZWQgPT09ICcxJykge1xuICAgICAgICBjb25zdCBzaW5nbGVQcm9kdWN0Qm9vdHN0cmFwID0gbmV3IFNpbmdsZVByb2R1Y3RCb290c3RhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICAgICAgbWVzc2FnZVJlbmRlcmVyLFxuICAgICAgICApO1xuXG4gICAgICAgIHNpbmdsZVByb2R1Y3RCb290c3RyYXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAnY2FydCcpIHtcbiAgICAgICAgY29uc3QgY2FydEJvb3RzdHJhcCA9IG5ldyBDYXJ0Qm9vdHN0cmFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICk7XG5cbiAgICAgICAgY2FydEJvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdjaGVja291dCcpIHtcbiAgICAgICAgY29uc3QgY2hlY2tvdXRCb290c3RhcCA9IG5ldyBDaGVja291dEJvb3RzdGFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICAgICBzcGlubmVyXG4gICAgICAgICk7XG5cbiAgICAgICAgY2hlY2tvdXRCb290c3RhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdwYXktbm93JyApIHtcbiAgICAgICAgY29uc3QgcGF5Tm93Qm9vdHN0cmFwID0gbmV3IFBheU5vd0Jvb3RzdHJhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICAgICAgbWVzc2FnZVJlbmRlcmVyLFxuICAgICAgICAgICAgc3Bpbm5lclxuICAgICAgICApO1xuICAgICAgICBwYXlOb3dCb290c3RyYXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ICE9PSAnY2hlY2tvdXQnKSB7XG4gICAgICAgIG1lc3NhZ2VSZW5kZXJlci5yZW5kZXIoKTtcbiAgICB9XG59O1xuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAnRE9NQ29udGVudExvYWRlZCcsXG4gICAgKCkgPT4ge1xuICAgICAgICBpZiAoIXR5cGVvZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5KSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignUGF5UGFsIGJ1dHRvbiBjb3VsZCBub3QgYmUgY29uZmlndXJlZC4nKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblxuICAgICAgICBzY3JpcHQuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgYm9vdHN0cmFwKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdzcmMnLCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuYnV0dG9uLnVybCk7XG4gICAgICAgIE9iamVjdC5lbnRyaWVzKFBheVBhbENvbW1lcmNlR2F0ZXdheS5zY3JpcHRfYXR0cmlidXRlcykuZm9yRWFjaChcbiAgICAgICAgICAgIChrZXlWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoa2V5VmFsdWVbMF0sIGtleVZhbHVlWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkLnNldF9hdHRyaWJ1dGUpIHtcbiAgICAgICAgICAgIGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIoc2NyaXB0LCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoc2NyaXB0KTtcbiAgICB9LFxuKTtcbiJdLCJuYW1lcyI6WyJFcnJvckhhbmRsZXIiLCJjb25zdHJ1Y3RvciIsImdlbmVyaWNFcnJvclRleHQiLCJ3cmFwcGVyIiwiZG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwibWVzc2FnZXNMaXN0IiwiZ2VuZXJpY0Vycm9yIiwiY2xhc3NMaXN0IiwiY29udGFpbnMiLCJjbGVhciIsIm1lc3NhZ2UiLCJhcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQiLCJlcnJvck1lc3NhZ2VFbGVtZW50IiwicHJlcGFyZU1lc3NhZ2VzTGlzdCIsInJlcGxhY2VXaXRoIiwidGV4dCIsInBlcnNpc3QiLCJTdHJpbmciLCJsZW5ndGgiLCJFcnJvciIsImFkZCIsInJlbW92ZSIsIm1lc3NhZ2VOb2RlIiwicHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0iLCJhcHBlbmRDaGlsZCIsImpRdWVyeSIsInNjcm9sbF90b19ub3RpY2VzIiwiY3JlYXRlRWxlbWVudCIsInNldEF0dHJpYnV0ZSIsImxpIiwiaW5uZXJIVE1MIiwic2FuaXRpemUiLCJ0ZXh0YXJlYSIsInZhbHVlIiwicmVwbGFjZSIsIm9uQXBwcm92ZSIsImNvbnRleHQiLCJlcnJvckhhbmRsZXIiLCJkYXRhIiwiYWN0aW9ucyIsImZldGNoIiwiY29uZmlnIiwiYWpheCIsImFwcHJvdmVfb3JkZXIiLCJlbmRwb2ludCIsIm1ldGhvZCIsImJvZHkiLCJKU09OIiwic3RyaW5naWZ5Iiwibm9uY2UiLCJvcmRlcl9pZCIsIm9yZGVySUQiLCJmdW5kaW5nX3NvdXJjZSIsIndpbmRvdyIsInBwY3BGdW5kaW5nU291cmNlIiwidGhlbiIsInJlcyIsImpzb24iLCJzdWNjZXNzIiwicmVzdGFydCIsImNhdGNoIiwiZXJyIiwibG9jYXRpb24iLCJocmVmIiwicmVkaXJlY3QiLCJwYXllckRhdGEiLCJwYXllciIsIlBheVBhbENvbW1lcmNlR2F0ZXdheSIsInBob25lIiwicGhvbmVfdHlwZSIsInBob25lX251bWJlciIsIm5hdGlvbmFsX251bWJlciIsImVtYWlsX2FkZHJlc3MiLCJuYW1lIiwic3VybmFtZSIsImdpdmVuX25hbWUiLCJhZGRyZXNzIiwiY291bnRyeV9jb2RlIiwiYWRkcmVzc19saW5lXzEiLCJhZGRyZXNzX2xpbmVfMiIsImFkbWluX2FyZWFfMSIsImFkbWluX2FyZWFfMiIsInBvc3RhbF9jb2RlIiwiQ2FydEFjdGlvbkhhbmRsZXIiLCJjb25maWd1cmF0aW9uIiwiY3JlYXRlT3JkZXIiLCJibkNvZGUiLCJibl9jb2RlcyIsImNyZWF0ZV9vcmRlciIsInB1cmNoYXNlX3VuaXRzIiwiYm5fY29kZSIsImNvbnNvbGUiLCJlcnJvciIsImlkIiwib25FcnJvciIsIk1pbmlDYXJ0Qm9vdHN0YXAiLCJnYXRld2F5IiwicmVuZGVyZXIiLCJhY3Rpb25IYW5kbGVyIiwiaW5pdCIsImxhYmVscyIsImdlbmVyaWMiLCJyZW5kZXIiLCJvbiIsInNob3VsZFJlbmRlciIsImJ1dHRvbiIsIm1pbmlfY2FydF93cmFwcGVyIiwiaG9zdGVkX2ZpZWxkcyIsIlByb2R1Y3QiLCJVcGRhdGVDYXJ0IiwidXBkYXRlIiwib25SZXNvbHZlIiwicHJvZHVjdHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlc3VsdCIsInJlc29sdmVkIiwiQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIiwiZWxlbWVudCIsInNob3dDYWxsYmFjayIsImhpZGVDYWxsYmFjayIsIm9ic2VydmVyIiwiYXR0cmlidXRlcyIsImNhbGxiYWNrIiwiTXV0YXRpb25PYnNlcnZlciIsIm9ic2VydmUiLCJkaXNjb25uZWN0IiwicXVhbnRpdHkiLCJ2YXJpYXRpb25zIiwiU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIiLCJ1cGRhdGVDYXJ0Iiwic2hvd0J1dHRvbkNhbGxiYWNrIiwiaGlkZUJ1dHRvbkNhbGxiYWNrIiwiZm9ybUVsZW1lbnQiLCJoYXNWYXJpYXRpb25zIiwiZ2V0UHJvZHVjdHMiLCJpc0dyb3VwZWRQcm9kdWN0IiwicXR5IiwicXVlcnlTZWxlY3RvckFsbCIsImZvckVhY2giLCJlbGVtZW50TmFtZSIsImdldEF0dHJpYnV0ZSIsIm1hdGNoIiwicGFyc2VJbnQiLCJwdXNoIiwicHJvbWlzZSIsIm1hcCIsIlNpbmdsZVByb2R1Y3RCb290c3RhcCIsIm1lc3NhZ2VzIiwiaGlkZUJ1dHRvbnMiLCJjaGFuZ2VfY2FydCIsInNob3dCdXR0b25zIiwicHJpY2VUZXh0IiwiaW5uZXJUZXh0IiwiYW1vdW50IiwicmVuZGVyV2l0aEFtb3VudCIsIkNhcnRCb290c3RyYXAiLCJzcGlubmVyIiwiYmxvY2siLCJ1bmJsb2NrIiwiY29kZSIsImNsaWNrIiwiQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIiwiZm9ybVNlbGVjdG9yIiwiZm9ybVZhbHVlcyIsInNlcmlhbGl6ZSIsImNyZWF0ZWFjY291bnQiLCJpcyIsImZvcm0iLCJkb21QYXJzZXIiLCJET01QYXJzZXIiLCJwYXJzZUZyb21TdHJpbmciLCJpbnB1dCIsImN1c3RvbV9pZCIsImFwcGVuZCIsIm9uQ2FuY2VsIiwiZ2V0RWxlbWVudCIsInNlbGVjdG9yT3JFbGVtZW50IiwiaXNWaXNpYmxlIiwib2Zmc2V0V2lkdGgiLCJvZmZzZXRIZWlnaHQiLCJnZXRDbGllbnRSZWN0cyIsInNldFZpc2libGUiLCJzaG93IiwiaW1wb3J0YW50IiwiY3VycmVudFZhbHVlIiwic3R5bGUiLCJnZXRQcm9wZXJ0eVZhbHVlIiwic2V0UHJvcGVydHkiLCJyZW1vdmVQcm9wZXJ0eSIsImhpZGUiLCJDaGVja291dEJvb3RzdGFwIiwic3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yIiwiYnV0dG9uQ2hhbmdlT2JzZXJ2ZXIiLCJlbCIsInVwZGF0ZVVpIiwidmFsIiwiY2FuY2VsX3dyYXBwZXIiLCJjdXJyZW50UGF5bWVudE1ldGhvZCIsImlzUGF5cGFsIiwiaXNDYXJkIiwiaXNTYXZlZENhcmQiLCJpc1NhdmVkQ2FyZFNlbGVjdGVkIiwiaXNOb3RPdXJHYXRld2F5IiwiZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMiLCJlbmFibGVDcmVkaXRDYXJkRmllbGRzIiwiYWRkQ2xhc3MiLCJhdHRyIiwicmVtb3ZlQ2xhc3MiLCJzYXZlZENhcmRMaXN0IiwiUGF5Tm93Qm9vdHN0cmFwIiwidXJsUGFyYW1zIiwiVVJMU2VhcmNoUGFyYW1zIiwic2VhcmNoIiwiaGFzIiwiUmVuZGVyZXIiLCJjcmVkaXRDYXJkUmVuZGVyZXIiLCJkZWZhdWx0Q29uZmlnIiwib25TbWFydEJ1dHRvbkNsaWNrIiwiaG9zdGVkRmllbGRzV3JhcHBlciIsImNvbnRleHRDb25maWciLCJyZW5kZXJCdXR0b25zIiwiaXNBbHJlYWR5UmVuZGVyZWQiLCJwYXlwYWwiLCJCdXR0b25zIiwibWluaV9jYXJ0X3N0eWxlIiwib25DbGljayIsImhhc0NoaWxkTm9kZXMiLCJkb21FbGVtZW50IiwiZGlzcGxheSIsImRpc2FibGVGaWVsZHMiLCJlbmFibGVGaWVsZHMiLCJkY2NJbnB1dEZhY3RvcnkiLCJvcmlnaW5hbCIsInN0eWxlcyIsImdldENvbXB1dGVkU3R5bGUiLCJuZXdFbGVtZW50IiwiT2JqZWN0IiwidmFsdWVzIiwicHJvcCIsImlzTmFOIiwiQ3JlZGl0Q2FyZFJlbmRlcmVyIiwiY2FyZFZhbGlkIiwiZm9ybVZhbGlkIiwiY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlIiwiZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkIiwiSG9zdGVkRmllbGRzIiwiaXNFbGlnaWJsZSIsIndyYXBwZXJFbGVtZW50IiwicGFyZW50Tm9kZSIsInJlbW92ZUNoaWxkIiwidGVhcmRvd24iLCJnYXRlV2F5Qm94Iiwib2xkRGlzcGxheVN0eWxlIiwiaGlkZURjY0dhdGV3YXkiLCJjYXJkTnVtYmVyRmllbGQiLCJzdHlsZXNSYXciLCJjYXJkTnVtYmVyIiwicmVwbGFjZUNoaWxkIiwiY2FyZEV4cGlyeUZpZWxkIiwiY2FyZEV4cGlyeSIsImNhcmRDb2RlRmllbGQiLCJjYXJkQ29kZSIsImZvcm1XcmFwcGVyIiwiZW5mb3JjZV92YXVsdCIsImNoZWNrZWQiLCJmaWVsZHMiLCJudW1iZXIiLCJzZWxlY3RvciIsInBsYWNlaG9sZGVyIiwiY3JlZGl0X2NhcmRfbnVtYmVyIiwiY3Z2IiwiZXhwaXJhdGlvbkRhdGUiLCJtbV95eSIsImhvc3RlZEZpZWxkcyIsImRpc3BhdGNoRXZlbnQiLCJDdXN0b21FdmVudCIsIl9zdWJtaXQiLCJldmVudCIsImNhcmRzIiwidmFsaWRDYXJkcyIsInZhbGlkX2NhcmRzIiwiaW5kZXhPZiIsInR5cGUiLCJrZXlzIiwiZXZlcnkiLCJrZXkiLCJpc1ZhbGlkIiwiYWRkRXZlbnRMaXN0ZW5lciIsInByZXZlbnREZWZhdWx0IiwiZmllbGQiLCJhdHRyaWJ1dGUiLCJyZW1vdmVBdHRyaWJ1dGUiLCJzYXZlX2NhcmQiLCJ2YXVsdCIsImdldEVsZW1lbnRCeUlkIiwiY29udGluZ2VuY3kiLCJob3N0ZWRGaWVsZHNEYXRhIiwiY29udGluZ2VuY2llcyIsImNhcmRob2xkZXJOYW1lIiwiZmlyc3ROYW1lIiwibGFzdE5hbWUiLCJjYXJkaG9sZGVyX25hbWVfcmVxdWlyZWQiLCJzdWJtaXQiLCJwYXlsb2FkIiwib3JkZXJJZCIsImNhcmRfbm90X3N1cHBvcnRlZCIsImZpZWxkc19ub3RfdmFsaWQiLCJzdG9yYWdlS2V5IiwidmFsaWRhdGVUb2tlbiIsInRva2VuIiwidXNlciIsImN1cnJlbnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJpc0V4cGlyZWQiLCJleHBpcmF0aW9uIiwic3RvcmVkVG9rZW5Gb3JVc2VyIiwicGFyc2UiLCJzZXNzaW9uU3RvcmFnZSIsImdldEl0ZW0iLCJzdG9yZVRva2VuIiwic2V0SXRlbSIsImRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIiLCJzY3JpcHQiLCJNZXNzYWdlUmVuZGVyZXIiLCJNZXNzYWdlcyIsInBsYWNlbWVudCIsIm5ld1dyYXBwZXIiLCJzaWJsaW5nIiwibmV4dFNpYmxpbmciLCJwYXJlbnRFbGVtZW50IiwiaW5zZXJ0QmVmb3JlIiwiU3Bpbm5lciIsInRhcmdldCIsInNldFRhcmdldCIsIm92ZXJsYXlDU1MiLCJiYWNrZ3JvdW5kIiwib3BhY2l0eSIsImJvb3RzdHJhcCIsImZ1bmRpbmdTb3VyY2UiLCJtZXNzYWdlUmVuZGVyZXIiLCJtaW5pX2NhcnRfYnV0dG9uc19lbmFibGVkIiwibWluaUNhcnRCb290c3RyYXAiLCJzaW5nbGVfcHJvZHVjdF9idXR0b25zX2VuYWJsZWQiLCJzaW5nbGVQcm9kdWN0Qm9vdHN0cmFwIiwiY2FydEJvb3RzdHJhcCIsImNoZWNrb3V0Qm9vdHN0YXAiLCJwYXlOb3dCb290c3RyYXAiLCJ1cmwiLCJlbnRyaWVzIiwic2NyaXB0X2F0dHJpYnV0ZXMiLCJrZXlWYWx1ZSIsImRhdGFfY2xpZW50X2lkIiwic2V0X2F0dHJpYnV0ZSJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///964\n")}},__webpack_exports__={};__webpack_modules__[964]()})();
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 funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/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 funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\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, onSmartButtonClick) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n this.onSmartButtonClick = onSmartButtonClick;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig,\n onClick: this.onSmartButtonClick\n }).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\n const onSmartButtonClick = data => {\n window.ppcpFundingSource = data.fundingSource;\n };\n\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick);\n const messageRenderer = new Renderer_MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n\n if (context === 'mini-cart' || context === 'product') {\n if (PayPalCommerceGateway.mini_cart_buttons_enabled === '1') {\n const miniCartBootstrap = new ContextBootstrap_MiniCartBootstap(PayPalCommerceGateway, renderer);\n miniCartBootstrap.init();\n }\n }\n\n if (context === 'product' && PayPalCommerceGateway.single_product_buttons_enabled === '1') {\n const singleProductBootstrap = new ContextBootstrap_SingleProductBootstap(PayPalCommerceGateway, renderer, messageRenderer);\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstap(PayPalCommerceGateway, renderer);\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new ContextBootstrap_CheckoutBootstap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now') {\n const payNowBootstrap = new ContextBootstrap_PayNowBootstrap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (!typeof PayPalCommerceGateway) {\n console.error('PayPal button could not be configured.');\n return;\n }\n\n if (PayPalCommerceGateway.context !== 'checkout' && PayPalCommerceGateway.data_client_id.user === 0 && PayPalCommerceGateway.data_client_id.has_subscriptions) {\n return;\n }\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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LGFBQXpDLEVBQXdEO0FBQ3BEaEMsSUFBQUEsNEJBQTRCLENBQUNDLE1BQUQsRUFBU2xRLHFCQUFxQixDQUFDMlIsY0FBL0IsQ0FBNUI7QUFDQTtBQUNIOztBQUVEM1YsRUFBQUEsUUFBUSxDQUFDMkMsSUFBVCxDQUFjaUksTUFBZCxDQUFxQnNKLE1BQXJCO0FBQ0gsQ0FqQ0wiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRXJyb3JIYW5kbGVyLmpzP2U2NWEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanM/YzQ1NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1BheWVyRGF0YS5qcz8yYWYxIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyLmpzPzgyY2YiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcC5qcz9kNTUyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvVXBkYXRlQ2FydC5qcz9lNDIyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyLmpzP2UxOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0VudGl0eS9Qcm9kdWN0LmpzPzlmZmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIuanM/ZDliNyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAuanM/N2MxOSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAuanM/NWU5NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanM/OTMwNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXIuanM/ODUxNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0hpZGluZy5qcz8xZDM2Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAuanM/Yzg1NSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9QYXlOb3dCb290c3RyYXAuanM/ZDlmNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvUmVuZGVyZXIuanM/ZmE5MyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0RjY0lucHV0RmFjdG9yeS5qcz8yYTJmIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9DcmVkaXRDYXJkUmVuZGVyZXIuanM/Mzg3YSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlci5qcz9lZTBiIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXIuanM/Y2QwMiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1NwaW5uZXIuanM/MTcwOCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL2J1dHRvbi5qcz8wNjBmIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEVycm9ySGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3RvcihnZW5lcmljRXJyb3JUZXh0KVxuICAgIHtcbiAgICAgICAgdGhpcy5nZW5lcmljRXJyb3JUZXh0ID0gZ2VuZXJpY0Vycm9yVGV4dDtcbiAgICAgICAgdGhpcy53cmFwcGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLndvb2NvbW1lcmNlLW5vdGljZXMtd3JhcHBlcicpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3VsLndvb2NvbW1lcmNlLWVycm9yJyk7XG4gICAgfVxuXG4gICAgZ2VuZXJpY0Vycm9yKCkge1xuICAgICAgICBpZiAodGhpcy53cmFwcGVyLmNsYXNzTGlzdC5jb250YWlucygncHBjcC1wZXJzaXN0JykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMubWVzc2FnZSh0aGlzLmdlbmVyaWNFcnJvclRleHQpXG4gICAgfVxuXG4gICAgYXBwZW5kUHJlcGFyZWRFcnJvck1lc3NhZ2VFbGVtZW50KGVycm9yTWVzc2FnZUVsZW1lbnQpXG4gICAge1xuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlTWVzc2FnZXNMaXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5yZXBsYWNlV2l0aChlcnJvck1lc3NhZ2VFbGVtZW50KTtcbiAgICB9XG5cbiAgICBtZXNzYWdlKHRleHQsIHBlcnNpc3QgPSBmYWxzZSlcbiAgICB7XG4gICAgICAgIGlmKCEgdHlwZW9mIFN0cmluZyB8fCB0ZXh0Lmxlbmd0aCA9PT0gMCl7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgbmV3IG1lc3NhZ2UgdGV4dCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKXtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBlcnNpc3QpIHtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QuYWRkKCdwcGNwLXBlcnNpc3QnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QucmVtb3ZlKCdwcGNwLXBlcnNpc3QnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBtZXNzYWdlTm9kZSA9IHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0odGV4dCk7XG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LmFwcGVuZENoaWxkKG1lc3NhZ2VOb2RlKTtcblxuICAgICAgICBqUXVlcnkuc2Nyb2xsX3RvX25vdGljZXMoalF1ZXJ5KCcud29vY29tbWVyY2Utbm90aWNlcy13cmFwcGVyJykpXG4gICAgfVxuXG4gICAgcHJlcGFyZU1lc3NhZ2VzTGlzdCgpXG4gICAge1xuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCl7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3VsJyk7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3dvb2NvbW1lcmNlLWVycm9yJyk7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnYWxlcnQnKTtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlci5hcHBlbmRDaGlsZCh0aGlzLm1lc3NhZ2VzTGlzdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcmVwYXJlTWVzc2FnZXNMaXN0SXRlbShtZXNzYWdlKVxuICAgIHtcbiAgICAgICAgY29uc3QgbGkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpO1xuICAgICAgICBsaS5pbm5lckhUTUwgPSBtZXNzYWdlO1xuXG4gICAgICAgIHJldHVybiBsaTtcbiAgICB9XG5cbiAgICBzYW5pdGl6ZSh0ZXh0KVxuICAgIHtcbiAgICAgICAgY29uc3QgdGV4dGFyZWEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xuICAgICAgICB0ZXh0YXJlYS5pbm5lckhUTUwgPSB0ZXh0O1xuICAgICAgICByZXR1cm4gdGV4dGFyZWEudmFsdWUucmVwbGFjZSgnRXJyb3I6ICcsICcnKTtcbiAgICB9XG5cbiAgICBjbGVhcigpXG4gICAge1xuICAgICAgICBpZiAodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LmlubmVySFRNTCA9ICcnO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXJyb3JIYW5kbGVyO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICByZXR1cm4gZmV0Y2goY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICBub25jZTogY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgIG9yZGVyX2lkOmRhdGEub3JkZXJJRCxcbiAgICAgICAgICAgICAgICBmdW5kaW5nX3NvdXJjZTogd2luZG93LnBwY3BGdW5kaW5nU291cmNlLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgIH0pLnRoZW4oKGRhdGEpPT57XG4gICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5yZXN0YXJ0KCkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGNvbnRleHQuY29uZmlnLnJlZGlyZWN0O1xuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiZXhwb3J0IGNvbnN0IHBheWVyRGF0YSA9ICgpID0+IHtcbiAgICBjb25zdCBwYXllciA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5wYXllcjtcbiAgICBpZiAoISBwYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwaG9uZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpIHx8IHR5cGVvZiBwYXllci5waG9uZSAhPT0gJ3VuZGVmaW5lZCcpID9cbiAgICB7XG4gICAgICAgIHBob25lX3R5cGU6XCJIT01FXCIsXG4gICAgICAgICAgICBwaG9uZV9udW1iZXI6e1xuICAgICAgICAgICAgbmF0aW9uYWxfbnVtYmVyIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKS52YWx1ZSA6IHBheWVyLnBob25lLnBob25lX251bWJlci5uYXRpb25hbF9udW1iZXJcbiAgICAgICAgfVxuICAgIH0gOiBudWxsO1xuICAgIGNvbnN0IHBheWVyRGF0YSA9IHtcbiAgICAgICAgZW1haWxfYWRkcmVzczooZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpLnZhbHVlIDogcGF5ZXIuZW1haWxfYWRkcmVzcyxcbiAgICAgICAgbmFtZSA6IHtcbiAgICAgICAgICAgIHN1cm5hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuc3VybmFtZSxcbiAgICAgICAgICAgIGdpdmVuX25hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5naXZlbl9uYW1lXG4gICAgICAgIH0sXG4gICAgICAgIGFkZHJlc3MgOiB7XG4gICAgICAgICAgICBjb3VudHJ5X2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuY291bnRyeV9jb2RlLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8xLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8yLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8xLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMixcbiAgICAgICAgICAgIHBvc3RhbF9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MucG9zdGFsX2NvZGVcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAocGhvbmUpIHtcbiAgICAgICAgcGF5ZXJEYXRhLnBob25lID0gcGhvbmU7XG4gICAgfVxuICAgIHJldHVybiBwYXllckRhdGE7XG59XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENhcnRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOiBvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIpLFxuICAgICAgICAgICAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgTWluaUNhcnRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbignd2NfZnJhZ21lbnRzX2xvYWRlZCB3Y19mcmFnbWVudHNfcmVmcmVzaGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcikgIT09XG4gICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKVxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWluaUNhcnRCb290c3RhcDsiLCJpbXBvcnQgUHJvZHVjdCBmcm9tIFwiLi4vRW50aXR5L1Byb2R1Y3RcIjtcbmNsYXNzIFVwZGF0ZUNhcnQge1xuXG4gICAgY29uc3RydWN0b3IoZW5kcG9pbnQsIG5vbmNlKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludCA9IGVuZHBvaW50O1xuICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25SZXNvbHZlXG4gICAgICogQHBhcmFtIHtQcm9kdWN0W119IHByb2R1Y3RzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAgICovXG4gICAgdXBkYXRlKG9uUmVzb2x2ZSwgcHJvZHVjdHMpXG4gICAge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZmV0Y2goXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qc29uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gb25SZXNvbHZlKHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVcGRhdGVDYXJ0OyIsIi8qKlxuICogV2hlbiB5b3UgY2FuJ3QgYWRkIHNvbWV0aGluZyB0byB0aGUgY2FydCwgdGhlIFBheVBhbCBidXR0b25zIHNob3VsZCBub3Qgc2hvdy5cbiAqIFRoZXJlZm9yZSB3ZSBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiBhbmQgc2hvdy9oaWRlIHRoZSBidXR0b25zIGFjY29yZGluZ2x5LlxuICovXG5cbmNsYXNzIEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2hvd0NhbGxiYWNrLCBoaWRlQ2FsbGJhY2spXG4gICAge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnNob3dDYWxsYmFjayA9IHNob3dDYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2sgPSBoaWRlQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKVxuICAgIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0geyBhdHRyaWJ1dGVzIDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNob3dDYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgZGlzY29ubmVjdCgpXG4gICAge1xuICAgICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcjsiLCJjbGFzcyBQcm9kdWN0IHtcblxuICAgIGNvbnN0cnVjdG9yKGlkLCBxdWFudGl0eSwgdmFyaWF0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMucXVhbnRpdHkgPSBxdWFudGl0eTtcbiAgICAgICAgdGhpcy52YXJpYXRpb25zID0gdmFyaWF0aW9ucztcbiAgICB9XG5cbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6dGhpcy5pZCxcbiAgICAgICAgICAgIHF1YW50aXR5OnRoaXMucXVhbnRpdHksXG4gICAgICAgICAgICB2YXJpYXRpb25zOnRoaXMudmFyaWF0aW9uc1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0OyIsImltcG9ydCBCdXR0b25zVG9nZ2xlTGlzdGVuZXIgZnJvbSAnLi4vSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lcic7XG5pbXBvcnQgUHJvZHVjdCBmcm9tICcuLi9FbnRpdHkvUHJvZHVjdCc7XG5pbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHVwZGF0ZUNhcnQsXG4gICAgICAgIHNob3dCdXR0b25DYWxsYmFjayxcbiAgICAgICAgaGlkZUJ1dHRvbkNhbGxiYWNrLFxuICAgICAgICBmb3JtRWxlbWVudCxcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhcnQgPSB1cGRhdGVDYXJ0O1xuICAgICAgICB0aGlzLnNob3dCdXR0b25DYWxsYmFjayA9IHNob3dCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2sgPSBoaWRlQnV0dG9uQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnQgPSBmb3JtRWxlbWVudDtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpXG4gICAge1xuXG4gICAgICAgIGlmICggdGhpcy5oYXNWYXJpYXRpb25zKCkgKSB7XG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlX2FkZF90b19jYXJ0X2J1dHRvbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUJ1dHRvbkNhbGxiYWNrXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuaW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiB0aGlzLmNyZWF0ZU9yZGVyKCksXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU9yZGVyKClcbiAgICB7XG4gICAgICAgIHZhciBnZXRQcm9kdWN0cyA9IG51bGw7XG4gICAgICAgIGlmICghIHRoaXMuaXNHcm91cGVkUHJvZHVjdCgpICkge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cImFkZC10by1jYXJ0XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcXR5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25hbWU9XCJxdWFudGl0eVwiXScpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhdGlvbnMgPSB0aGlzLnZhcmlhdGlvbnMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBQcm9kdWN0KGlkLCBxdHksIHZhcmlhdGlvbnMpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFByb2R1Y3RzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwibnVtYmVyXCJdJykuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBlbGVtZW50LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpLm1hdGNoKC9xdWFudGl0eVxcWyhbXFxkXSopXFxdLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50TmFtZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHBhcnNlSW50KGVsZW1lbnROYW1lWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMucHVzaChuZXcgUHJvZHVjdChpZCwgcXVhbnRpdHksIG51bGwpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICBjb25zdCBvblJlc29sdmUgPSAocHVyY2hhc2VfdW5pdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnVwZGF0ZUNhcnQudXBkYXRlKG9uUmVzb2x2ZSwgZ2V0UHJvZHVjdHMoKSk7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU9yZGVyO1xuICAgIH1cblxuICAgIHZhcmlhdGlvbnMoKVxuICAgIHtcblxuICAgICAgICBpZiAoISB0aGlzLmhhc1ZhcmlhdGlvbnMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFsuLi50aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZV49J2F0dHJpYnV0ZV8nXVwiKV0ubWFwKFxuICAgICAgICAgICAgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOmVsZW1lbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ZWxlbWVudC5uYW1lXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICBoYXNWYXJpYXRpb25zKClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygndmFyaWF0aW9uc19mb3JtJyk7XG4gICAgfVxuXG4gICAgaXNHcm91cGVkUHJvZHVjdCgpXG4gICAge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyb3VwZWRfZm9ybScpO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhcnQgZnJvbSBcIi4uL0hlbHBlci9VcGRhdGVDYXJ0XCI7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIgZnJvbSBcIi4uL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXJcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXksXG4gICAgICAgICAgICBuZXcgVXBkYXRlQ2FydChcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5ub25jZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgbGV0IHByaWNlVGV4dCA9IFwiMFwiO1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlSW50KHByaWNlVGV4dC5yZXBsYWNlKC8oW15cXGQsXFwuXFxzXSopL2csICcnKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXJXaXRoQW1vdW50KGFtb3VudClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JyksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXA7IiwiaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuXG5jbGFzcyBDYXJ0Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscyB1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0Qm9vdHN0cmFwO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICBzcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIGVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklELFxuICAgICAgICAgICAgICAgIGZ1bmRpbmdfc291cmNlOiB3aW5kb3cucHBjcEZ1bmRpbmdTb3VyY2UsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmNvZGUgPT09IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbnMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhY3Rpb25zLnJlc3RhcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwbGFjZV9vcmRlcicpLmNsaWNrKClcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENoZWNrb3V0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMuc3Bpbm5lcjtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IHRoaXMuZXJyb3JIYW5kbGVyO1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtU2VsZWN0b3IgPSB0aGlzLmNvbmZpZy5jb250ZXh0ID09PSAnY2hlY2tvdXQnID8gJ2Zvcm0uY2hlY2tvdXQnIDogJ2Zvcm0jb3JkZXJfcmV2aWV3JztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSBqUXVlcnkoZm9ybVNlbGVjdG9yKS5zZXJpYWxpemUoKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlYWNjb3VudCA9IGpRdWVyeSgnI2NyZWF0ZWFjY291bnQnKS5pcyhcIjpjaGVja2VkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyX2lkOnRoaXMuY29uZmlnLm9yZGVyX2lkLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOmZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWFjY291bnQ6IGNyZWF0ZWFjY291bnRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vaGFuZGxlIGJvdGggbWVzc2FnZXMgc2VudCBmcm9tIFdvb2NvbW1lcmNlIChkYXRhLm1lc3NhZ2VzKSBhbmQgdGhpcyBwbHVnaW4gKGRhdGEuZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKGRhdGEubWVzc2FnZXMpICE9PSAndW5kZWZpbmVkJyApXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5hcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhkYXRhLm1lc3NhZ2VzLCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJ3VsJylcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3BwY3AtcmVzdW1lLW9yZGVyJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGRhdGEuZGF0YS5wdXJjaGFzZV91bml0c1swXS5jdXN0b21faWQpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVNlbGVjdG9yKS5hcHBlbmQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6b25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyLCB0aGlzLnNwaW5uZXIpLFxuICAgICAgICAgICAgb25DYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QWN0aW9uSGFuZGxlcjtcbiIsImNvbnN0IGdldEVsZW1lbnQgPSAoc2VsZWN0b3JPckVsZW1lbnQpID0+IHtcbiAgICBpZiAodHlwZW9mIHNlbGVjdG9yT3JFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvck9yRWxlbWVudCk7XG4gICAgfVxuICAgIHJldHVybiBzZWxlY3Rvck9yRWxlbWVudDtcbn1cblxuZXhwb3J0IGNvbnN0IGlzVmlzaWJsZSA9IChlbGVtZW50KSA9PiB7XG4gICAgcmV0dXJuICEhKGVsZW1lbnQub2Zmc2V0V2lkdGggfHwgZWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgZWxlbWVudC5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCk7XG59XG5cbmV4cG9ydCBjb25zdCBzZXRWaXNpYmxlID0gKHNlbGVjdG9yT3JFbGVtZW50LCBzaG93LCBpbXBvcnRhbnQgPSBmYWxzZSkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBnZXRFbGVtZW50KHNlbGVjdG9yT3JFbGVtZW50KTtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGVsZW1lbnQuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgnZGlzcGxheScpO1xuXG4gICAgaWYgKCFzaG93KSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPT09ICdub25lJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnZGlzcGxheScsICdub25lJywgaW1wb3J0YW50ID8gJ2ltcG9ydGFudCcgOiAnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA9PT0gJ25vbmUnKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnJlbW92ZVByb3BlcnR5KCdkaXNwbGF5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzdGlsbCBub3QgdmlzaWJsZSAoaWYgc29tZXRoaW5nIGVsc2UgYWRkZWQgZGlzcGxheTogbm9uZSBpbiBDU1MpXG4gICAgICAgIGlmICghaXNWaXNpYmxlKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCdkaXNwbGF5JywgJ2Jsb2NrJyk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5leHBvcnQgY29uc3QgaGlkZSA9IChzZWxlY3Rvck9yRWxlbWVudCwgaW1wb3J0YW50ID0gZmFsc2UpID0+IHtcbiAgICBzZXRWaXNpYmxlKHNlbGVjdG9yT3JFbGVtZW50LCBmYWxzZSwgaW1wb3J0YW50KTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaG93ID0gKHNlbGVjdG9yT3JFbGVtZW50KSA9PiB7XG4gICAgc2V0VmlzaWJsZShzZWxlY3Rvck9yRWxlbWVudCwgdHJ1ZSk7XG59O1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENoZWNrb3V0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NoZWNrb3V0QWN0aW9uSGFuZGxlcic7XG5pbXBvcnQgeyBzZXRWaXNpYmxlIH0gZnJvbSAnLi4vSGVscGVyL0hpZGluZyc7XG5cbmNsYXNzIENoZWNrb3V0Qm9vdHN0YXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcywgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlcztcbiAgICAgICAgdGhpcy5zcGlubmVyID0gc3Bpbm5lcjtcblxuICAgICAgICB0aGlzLnN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciA9ICcjcGxhY2Vfb3JkZXInO1xuXG4gICAgICAgIHRoaXMuYnV0dG9uQ2hhbmdlT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoZWwpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgICAgICAvLyBVbnNlbGVjdCBzYXZlZCBjYXJkLlxuICAgICAgICAvLyBXQyBzYXZlcyBmb3JtIHZhbHVlcywgc28gd2l0aCBvdXIgY3VycmVudCBVSSBpdCB3b3VsZCBiZSBhIGJpdCB3ZWlyZFxuICAgICAgICAvLyBpZiB0aGUgdXNlciBwYWlkIHdpdGggc2F2ZWQsIHRoZW4gYWZ0ZXIgc29tZSB0aW1lIHRyaWVzIHRvIHBheSBhZ2FpbixcbiAgICAgICAgLy8gYnV0IHdhbnRzIHRvIGVudGVyIGEgbmV3IGNhcmQsIGFuZCB0byBkbyB0aGF0IHRoZXkgaGF2ZSB0byBjaG9vc2Ug4oCcU2VsZWN0IHBheW1lbnTigJ0gaW4gdGhlIGxpc3QuXG4gICAgICAgIGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkJykudmFsKGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkIG9wdGlvbjpmaXJzdCcpLnZhbCgpKTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3VwZGF0ZWRfY2hlY2tvdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCBwYXltZW50X21ldGhvZF9zZWxlY3RlZCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50KS5vbignaG9zdGVkX2ZpZWxkc19sb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi5jYW5jZWxfd3JhcHBlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcikgIT09IG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKSAhPT0gbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIgKyAnPmRpdicpKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIgKyAnPmRpdicpLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYWN0aW9uSGFuZGxlciA9IG5ldyBDaGVja291dEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICAgICB0aGlzLnNwaW5uZXJcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsXG4gICAgICAgICAgICBhY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmJ1dHRvbkNoYW5nZU9ic2VydmVyLm9ic2VydmUoXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuc3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yKSxcbiAgICAgICAgICAgIHthdHRyaWJ1dGVzOiB0cnVlfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHVwZGF0ZVVpKCkge1xuICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IHRoaXMuY3VycmVudFBheW1lbnRNZXRob2QoKTtcbiAgICAgICAgY29uc3QgaXNQYXlwYWwgPSBjdXJyZW50UGF5bWVudE1ldGhvZCA9PT0gJ3BwY3AtZ2F0ZXdheSc7XG4gICAgICAgIGNvbnN0IGlzQ2FyZCA9IGN1cnJlbnRQYXltZW50TWV0aG9kID09PSAncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgY29uc3QgaXNTYXZlZENhcmQgPSBpc0NhcmQgJiYgdGhpcy5pc1NhdmVkQ2FyZFNlbGVjdGVkKCk7XG4gICAgICAgIGNvbnN0IGlzTm90T3VyR2F0ZXdheSA9ICFpc1BheXBhbCAmJiAhaXNDYXJkO1xuXG4gICAgICAgIHNldFZpc2libGUodGhpcy5zdGFuZGFyZE9yZGVyQnV0dG9uU2VsZWN0b3IsIGlzTm90T3VyR2F0ZXdheSB8fCBpc1NhdmVkQ2FyZCwgdHJ1ZSk7XG4gICAgICAgIHNldFZpc2libGUodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLCBpc1BheXBhbCk7XG4gICAgICAgIHNldFZpc2libGUodGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIsIGlzUGF5cGFsKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLCBpc0NhcmQgJiYgIWlzU2F2ZWRDYXJkKTtcblxuICAgICAgICBpZiAoaXNQYXlwYWwpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNDYXJkKSB7XG4gICAgICAgICAgICBpZiAoaXNTYXZlZENhcmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgZmFsc2UpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxuXG4gICAgY3VycmVudFBheW1lbnRNZXRob2QoKSB7XG4gICAgICAgIHJldHVybiBqUXVlcnkoJ2lucHV0W25hbWU9XCJwYXltZW50X21ldGhvZFwiXTpjaGVja2VkJykudmFsKCk7XG4gICAgfVxuXG4gICAgaXNTYXZlZENhcmRTZWxlY3RlZCgpIHtcbiAgICAgICAgY29uc3Qgc2F2ZWRDYXJkTGlzdCA9IGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkJyk7XG4gICAgICAgIHJldHVybiBzYXZlZENhcmRMaXN0Lmxlbmd0aCAmJiBzYXZlZENhcmRMaXN0LnZhbCgpICE9PSAnJztcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0Qm9vdHN0YXBcbiIsImltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vQ2hlY2tvdXRCb290c3RhcCdcblxuY2xhc3MgUGF5Tm93Qm9vdHN0cmFwIGV4dGVuZHMgQ2hlY2tvdXRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIsIG1lc3NhZ2VzLCBzcGlubmVyKSB7XG4gICAgICAgIHN1cGVyKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcywgc3Bpbm5lcilcbiAgICB9XG5cbiAgICB1cGRhdGVVaSgpIHtcbiAgICAgICAgY29uc3QgdXJsUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKVxuICAgICAgICBpZiAodXJsUGFyYW1zLmhhcygnY2hhbmdlX3BheW1lbnRfbWV0aG9kJykpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgc3VwZXIudXBkYXRlVWkoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBheU5vd0Jvb3RzdHJhcDtcbiIsImNsYXNzIFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihjcmVkaXRDYXJkUmVuZGVyZXIsIGRlZmF1bHRDb25maWcsIG9uU21hcnRCdXR0b25DbGljaykge1xuICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcgPSBkZWZhdWx0Q29uZmlnO1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlciA9IGNyZWRpdENhcmRSZW5kZXJlcjtcbiAgICAgICAgdGhpcy5vblNtYXJ0QnV0dG9uQ2xpY2sgPSBvblNtYXJ0QnV0dG9uQ2xpY2s7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICB0aGlzLnJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLnJlbmRlcihob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICB9XG5cbiAgICByZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSB8fCB0aGlzLmlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHx8ICd1bmRlZmluZWQnID09PSB0eXBlb2YgcGF5cGFsLkJ1dHRvbnMgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdHlsZSA9IHdyYXBwZXIgPT09IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ud3JhcHBlciA/IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24uc3R5bGUgOiB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLm1pbmlfY2FydF9zdHlsZTtcbiAgICAgICAgcGF5cGFsLkJ1dHRvbnMoe1xuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAuLi5jb250ZXh0Q29uZmlnLFxuICAgICAgICAgICAgb25DbGljazogdGhpcy5vblNtYXJ0QnV0dG9uQ2xpY2ssXG4gICAgICAgIH0pLnJlbmRlcih3cmFwcGVyKTtcbiAgICB9XG5cbiAgICBpc0FscmVhZHlSZW5kZXJlZCh3cmFwcGVyKSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpLmhhc0NoaWxkTm9kZXMoKTtcbiAgICB9XG5cbiAgICBoaWRlQnV0dG9ucyhlbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGRvbUVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsZW1lbnQpO1xuICAgICAgICBpZiAoISBkb21FbGVtZW50ICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGRvbUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgc2hvd0J1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBkaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcygpIHtcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIuZGlzYWJsZUZpZWxkcygpO1xuICAgIH1cblxuICAgIGVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmVuYWJsZUZpZWxkcygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmVuZGVyZXI7XG4iLCJjb25zdCBkY2NJbnB1dEZhY3RvcnkgPSAob3JpZ2luYWwpID0+IHtcbiAgICBjb25zdCBzdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShvcmlnaW5hbCk7XG4gICAgY29uc3QgbmV3RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBuZXdFbGVtZW50LnNldEF0dHJpYnV0ZSgnaWQnLCBvcmlnaW5hbC5pZCk7XG4gICAgT2JqZWN0LnZhbHVlcyhzdHlsZXMpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgIGlmICghIHN0eWxlc1twcm9wXSB8fCAhIGlzTmFOKHByb3ApICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIG5ld0VsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkocHJvcCwnJyArIHN0eWxlc1twcm9wXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ld0VsZW1lbnQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRjY0lucHV0RmFjdG9yeTsiLCJpbXBvcnQgZGNjSW5wdXRGYWN0b3J5IGZyb20gXCIuLi9IZWxwZXIvRGNjSW5wdXRGYWN0b3J5XCI7XG5cbmNsYXNzIENyZWRpdENhcmRSZW5kZXJlciB7XG5cbiAgICBjb25zdHJ1Y3RvcihkZWZhdWx0Q29uZmlnLCBlcnJvckhhbmRsZXIsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgICAgIHRoaXMuY2FyZFZhbGlkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZm9ybVZhbGlkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlID0gbnVsbDtcbiAgICAgICAgdGhpcy5mb3JtU3VibWlzc2lvblN1YnNjcmliZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICByZW5kZXIod3JhcHBlciwgY29udGV4dENvbmZpZykge1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcuY29udGV4dCAhPT0gJ2NoZWNrb3V0J1xuICAgICAgICAgICAgICAgICYmIHRoaXMuZGVmYXVsdENvbmZpZy5jb250ZXh0ICE9PSAncGF5LW5vdydcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIHx8IHdyYXBwZXIgPT09IG51bGxcbiAgICAgICAgICAgIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikgPT09IG51bGxcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdHlwZW9mIHBheXBhbC5Ib3N0ZWRGaWVsZHMgPT09ICd1bmRlZmluZWQnXG4gICAgICAgICAgICB8fCAhIHBheXBhbC5Ib3N0ZWRGaWVsZHMuaXNFbGlnaWJsZSgpXG4gICAgICAgICkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlckVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpO1xuICAgICAgICAgICAgd3JhcHBlckVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh3cmFwcGVyRWxlbWVudCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnRlYXJkb3duKClcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoYEhvc3RlZCBmaWVsZHMgdGVhcmRvd24gZXJyb3I6ICR7ZXJyfWApKTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGdhdGVXYXlCb3ggPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGF5bWVudF9ib3gucGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5Jyk7XG4gICAgICAgIGNvbnN0IG9sZERpc3BsYXlTdHlsZSA9IGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheTtcbiAgICAgICAgZ2F0ZVdheUJveC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblxuICAgICAgICBjb25zdCBoaWRlRGNjR2F0ZXdheSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWhpZGUtZGNjJyk7XG4gICAgICAgIGlmIChoaWRlRGNjR2F0ZXdheSkge1xuICAgICAgICAgICAgaGlkZURjY0dhdGV3YXkucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChoaWRlRGNjR2F0ZXdheSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjYXJkTnVtYmVyRmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJyk7XG5cbiAgICAgICAgY29uc3Qgc3R5bGVzUmF3ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoY2FyZE51bWJlckZpZWxkKTtcbiAgICAgICAgbGV0IHN0eWxlcyA9IHt9O1xuICAgICAgICBPYmplY3QudmFsdWVzKHN0eWxlc1JhdykuZm9yRWFjaCggKHByb3ApID0+IHtcbiAgICAgICAgICAgIGlmICghIHN0eWxlc1Jhd1twcm9wXSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0eWxlc1twcm9wXSA9ICcnICsgc3R5bGVzUmF3W3Byb3BdO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBjYXJkTnVtYmVyID0gZGNjSW5wdXRGYWN0b3J5KGNhcmROdW1iZXJGaWVsZCk7XG4gICAgICAgIGNhcmROdW1iZXJGaWVsZC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjYXJkTnVtYmVyLCBjYXJkTnVtYmVyRmllbGQpO1xuXG4gICAgICAgIGNvbnN0IGNhcmRFeHBpcnlGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKTtcbiAgICAgICAgY29uc3QgY2FyZEV4cGlyeSA9IGRjY0lucHV0RmFjdG9yeShjYXJkRXhwaXJ5RmllbGQpO1xuICAgICAgICBjYXJkRXhwaXJ5RmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZEV4cGlyeSwgY2FyZEV4cGlyeUZpZWxkKTtcblxuICAgICAgICBjb25zdCBjYXJkQ29kZUZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpO1xuICAgICAgICBjb25zdCBjYXJkQ29kZSA9IGRjY0lucHV0RmFjdG9yeShjYXJkQ29kZUZpZWxkKTtcbiAgICAgICAgY2FyZENvZGVGaWVsZC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjYXJkQ29kZSwgY2FyZENvZGVGaWVsZCk7XG5cbiAgICAgICAgZ2F0ZVdheUJveC5zdHlsZS5kaXNwbGF5ID0gb2xkRGlzcGxheVN0eWxlO1xuXG4gICAgICAgIGNvbnN0IGZvcm1XcmFwcGVyID0gJy5wYXltZW50X2JveCBwYXltZW50X21ldGhvZF9wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcuZW5mb3JjZV92YXVsdFxuICAgICAgICAgICAgJiYgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuY2hlY2tlZCA9IHRydWU7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBwYXlwYWwuSG9zdGVkRmllbGRzLnJlbmRlcih7XG4gICAgICAgICAgICBjcmVhdGVPcmRlcjogY29udGV4dENvbmZpZy5jcmVhdGVPcmRlcixcbiAgICAgICAgICAgIHN0eWxlczoge1xuICAgICAgICAgICAgICAgICdpbnB1dCc6IHN0eWxlc1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZpZWxkczoge1xuICAgICAgICAgICAgICAgIG51bWJlcjoge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXInLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNyZWRpdF9jYXJkX251bWJlcixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGN2djoge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmN2dixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGV4cGlyYXRpb25EYXRlOiB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yOiAnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeScsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMubW1feXksXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KS50aGVuKGhvc3RlZEZpZWxkcyA9PiB7XG4gICAgICAgICAgICBkb2N1bWVudC5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChcImhvc3RlZF9maWVsZHNfbG9hZGVkXCIpKTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlID0gaG9zdGVkRmllbGRzO1xuXG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ2lucHV0U3VibWl0UmVxdWVzdCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWJtaXQoY29udGV4dENvbmZpZyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbignY2FyZFR5cGVDaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoICEgZXZlbnQuY2FyZHMubGVuZ3RoICkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbGlkQ2FyZHMgPSB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy52YWxpZF9jYXJkcztcbiAgICAgICAgICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IHZhbGlkQ2FyZHMuaW5kZXhPZihldmVudC5jYXJkc1swXS50eXBlKSAhPT0gLTE7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCd2YWxpZGl0eUNoYW5nZScsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1WYWxpZCA9IE9iamVjdC5rZXlzKGV2ZW50LmZpZWxkcykuZXZlcnkoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQuZmllbGRzW2tleV0uaXNWYWxpZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgIHRoaXMuZm9ybVZhbGlkID0gZm9ybVZhbGlkO1xuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmZvcm1TdWJtaXNzaW9uU3Vic2NyaWJlZCkge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlciArICcgYnV0dG9uJykuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICAgICAgJ2NsaWNrJyxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N1Ym1pdChjb250ZXh0Q29uZmlnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtU3VibWlzc2lvblN1YnNjcmliZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JykuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbGFiZWxbZm9yPXBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcl0nKS5jbGljaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICApXG4gICAgfVxuXG4gICAgZGlzYWJsZUZpZWxkcygpIHtcbiAgICAgICAgaWYoIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zZXRBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnbnVtYmVyJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zZXRBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnY3Z2JyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zZXRBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnZXhwaXJhdGlvbkRhdGUnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGVuYWJsZUZpZWxkcygpIHtcbiAgICAgICAgaWYoIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5yZW1vdmVBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnbnVtYmVyJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5yZW1vdmVBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnY3Z2JyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5yZW1vdmVBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnZXhwaXJhdGlvbkRhdGUnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9zdWJtaXQoY29udGV4dENvbmZpZykge1xuICAgICAgICB0aGlzLnNwaW5uZXIuYmxvY2soKTtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuY2xlYXIoKTtcblxuICAgICAgICBpZiAodGhpcy5mb3JtVmFsaWQgJiYgdGhpcy5jYXJkVmFsaWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHNhdmVfY2FyZCA9IHRoaXMuZGVmYXVsdENvbmZpZy5zYXZlX2NhcmQgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgICAgICBsZXQgdmF1bHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpID9cbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgOiBzYXZlX2NhcmQ7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHQpIHtcbiAgICAgICAgICAgICAgICB2YXVsdCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb250aW5nZW5jeSA9IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmNvbnRpbmdlbmN5O1xuICAgICAgICAgICAgY29uc3QgaG9zdGVkRmllbGRzRGF0YSA9IHtcbiAgICAgICAgICAgICAgICB2YXVsdDogdmF1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoY29udGluZ2VuY3kgIT09ICdOT18zRF9TRUNVUkUnKSB7XG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jb250aW5nZW5jaWVzID0gW2NvbnRpbmdlbmN5XTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbmZpZy5wYXllcikge1xuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY2FyZGhvbGRlck5hbWUgPSB0aGlzLmRlZmF1bHRDb25maWcucGF5ZXIubmFtZS5naXZlbl9uYW1lICsgJyAnICsgdGhpcy5kZWZhdWx0Q29uZmlnLnBheWVyLm5hbWUuc3VybmFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaG9zdGVkRmllbGRzRGF0YS5jYXJkaG9sZGVyTmFtZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0TmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2ZpcnN0X25hbWUnKSA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2ZpcnN0X25hbWUnKS52YWx1ZSA6ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhc3ROYW1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JpbGxpbmdfbGFzdF9uYW1lJykgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6ICcnO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFmaXJzdE5hbWUgfHwgIWxhc3ROYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UodGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNhcmRob2xkZXJfbmFtZV9yZXF1aXJlZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBob3N0ZWRGaWVsZHNEYXRhLmNhcmRob2xkZXJOYW1lID0gZmlyc3ROYW1lICsgJyAnICsgbGFzdE5hbWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnN1Ym1pdChob3N0ZWRGaWVsZHNEYXRhKS50aGVuKChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgcGF5bG9hZC5vcmRlcklEID0gcGF5bG9hZC5vcmRlcklkO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRDb25maWcub25BcHByb3ZlKHBheWxvYWQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSAhIHRoaXMuY2FyZFZhbGlkID8gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNhcmRfbm90X3N1cHBvcnRlZCA6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5maWVsZHNfbm90X3ZhbGlkO1xuICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IENyZWRpdENhcmRSZW5kZXJlcjtcbiIsImNvbnN0IHN0b3JhZ2VLZXkgPSAncHBjcC1kYXRhLWNsaWVudC1pZCc7XG5cbmNvbnN0IHZhbGlkYXRlVG9rZW4gPSAodG9rZW4sIHVzZXIpID0+IHtcbiAgICBpZiAoISB0b2tlbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0b2tlbi51c2VyICE9PSB1c2VyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBpc0V4cGlyZWQgPSBjdXJyZW50VGltZSA+PSB0b2tlbi5leHBpcmF0aW9uICogMTAwMDtcbiAgICByZXR1cm4gISBpc0V4cGlyZWQ7XG59XG5cbmNvbnN0IHN0b3JlZFRva2VuRm9yVXNlciA9ICh1c2VyKSA9PiB7XG4gICAgY29uc3QgdG9rZW4gPSBKU09OLnBhcnNlKHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oc3RvcmFnZUtleSkpO1xuICAgIGlmICh2YWxpZGF0ZVRva2VuKHRva2VuLCB1c2VyKSkge1xuICAgICAgICByZXR1cm4gdG9rZW4udG9rZW47XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBzdG9yZVRva2VuID0gKHRva2VuKSA9PiB7XG4gICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeSh0b2tlbikpO1xufVxuXG5jb25zdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyID0gKHNjcmlwdCwgY29uZmlnKSA9PiB7XG4gICAgZmV0Y2goY29uZmlnLmVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBub25jZTogY29uZmlnLm5vbmNlXG4gICAgICAgIH0pXG4gICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICB9KS50aGVuKChkYXRhKT0+e1xuICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdGVUb2tlbihkYXRhLCBjb25maWcudXNlcik7XG4gICAgICAgIGlmICghaXNWYWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0b3JlVG9rZW4oZGF0YSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtY2xpZW50LXRva2VuJywgZGF0YS50b2tlbik7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKHNjcmlwdCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXI7XG4iLCJjbGFzcyBNZXNzYWdlUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGF5cGFsLk1lc3NhZ2VzKHtcbiAgICAgICAgICAgIGFtb3VudDogdGhpcy5jb25maWcuYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHJlbmRlcldpdGhBbW91bnQoYW1vdW50KSB7XG5cbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3V3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBuZXdXcmFwcGVyLnNldEF0dHJpYnV0ZSgnaWQnLCB0aGlzLmNvbmZpZy53cmFwcGVyLnJlcGxhY2UoJyMnLCAnJykpO1xuXG4gICAgICAgIGNvbnN0IHNpYmxpbmcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLm5leHRTaWJsaW5nO1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSk7XG4gICAgICAgIHNpYmxpbmcucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUobmV3V3JhcHBlciwgc2libGluZyk7XG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgICBwbGFjZW1lbnQ6IHRoaXMuY29uZmlnLnBsYWNlbWVudCxcbiAgICAgICAgICAgIHN0eWxlOiB0aGlzLmNvbmZpZy5zdHlsZVxuICAgICAgICB9KS5yZW5kZXIodGhpcy5jb25maWcud3JhcHBlcik7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuXG4gICAgICAgIGlmICh0eXBlb2YgcGF5cGFsLk1lc3NhZ2VzID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgdGhpcy5jb25maWcud3JhcHBlciA9PT0gJ3VuZGVmaW5lZCcgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IE1lc3NhZ2VSZW5kZXJlcjsiLCJjbGFzcyBTcGlubmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnRhcmdldCA9ICdmb3JtLndvb2NvbW1lcmNlLWNoZWNrb3V0JztcbiAgICB9XG5cbiAgICBzZXRUYXJnZXQodGFyZ2V0KSB7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIH1cblxuICAgIGJsb2NrKCkge1xuXG4gICAgICAgIGpRdWVyeSggdGhpcy50YXJnZXQgKS5ibG9jayh7XG4gICAgICAgICAgICBtZXNzYWdlOiBudWxsLFxuICAgICAgICAgICAgb3ZlcmxheUNTUzoge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjZcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdW5ibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkudW5ibG9jaygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgU3Bpbm5lcjtcbiIsImltcG9ydCBNaW5pQ2FydEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL01pbmlDYXJ0Qm9vdHN0YXAnO1xuaW1wb3J0IFNpbmdsZVByb2R1Y3RCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAnO1xuaW1wb3J0IENhcnRCb290c3RyYXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2FydEJvb3RzdGFwJztcbmltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAnO1xuaW1wb3J0IFBheU5vd0Jvb3RzdHJhcCBmcm9tIFwiLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwXCI7XG5pbXBvcnQgUmVuZGVyZXIgZnJvbSAnLi9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyJztcbmltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi9tb2R1bGVzL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ3JlZGl0Q2FyZFJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyXCI7XG5pbXBvcnQgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciBmcm9tIFwiLi9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXJcIjtcbmltcG9ydCBNZXNzYWdlUmVuZGVyZXIgZnJvbSBcIi4vbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXJcIjtcbmltcG9ydCBTcGlubmVyIGZyb20gXCIuL21vZHVsZXMvSGVscGVyL1NwaW5uZXJcIjtcblxuY29uc3QgYm9vdHN0cmFwID0gKCkgPT4ge1xuICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IG5ldyBFcnJvckhhbmRsZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKTtcbiAgICBjb25zdCBzcGlubmVyID0gbmV3IFNwaW5uZXIoKTtcbiAgICBjb25zdCBjcmVkaXRDYXJkUmVuZGVyZXIgPSBuZXcgQ3JlZGl0Q2FyZFJlbmRlcmVyKFBheVBhbENvbW1lcmNlR2F0ZXdheSwgZXJyb3JIYW5kbGVyLCBzcGlubmVyKTtcbiAgICBjb25zdCBvblNtYXJ0QnV0dG9uQ2xpY2sgPSBkYXRhID0+IHtcbiAgICAgICAgd2luZG93LnBwY3BGdW5kaW5nU291cmNlID0gZGF0YS5mdW5kaW5nU291cmNlO1xuICAgIH07XG4gICAgY29uc3QgcmVuZGVyZXIgPSBuZXcgUmVuZGVyZXIoY3JlZGl0Q2FyZFJlbmRlcmVyLCBQYXlQYWxDb21tZXJjZUdhdGV3YXksIG9uU21hcnRCdXR0b25DbGljayk7XG4gICAgY29uc3QgbWVzc2FnZVJlbmRlcmVyID0gbmV3IE1lc3NhZ2VSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXkubWVzc2FnZXMpO1xuICAgIGNvbnN0IGNvbnRleHQgPSBQYXlQYWxDb21tZXJjZUdhdGV3YXkuY29udGV4dDtcbiAgICBpZiAoY29udGV4dCA9PT0gJ21pbmktY2FydCcgfHwgY29udGV4dCA9PT0gJ3Byb2R1Y3QnKSB7XG4gICAgICAgIGlmIChQYXlQYWxDb21tZXJjZUdhdGV3YXkubWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgICAgICBjb25zdCBtaW5pQ2FydEJvb3RzdHJhcCA9IG5ldyBNaW5pQ2FydEJvb3RzdGFwKFxuICAgICAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgICAgICByZW5kZXJlclxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgbWluaUNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdwcm9kdWN0JyAmJiBQYXlQYWxDb21tZXJjZUdhdGV3YXkuc2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkID09PSAnMScpIHtcbiAgICAgICAgY29uc3Qgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcCA9IG5ldyBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBzaW5nbGVQcm9kdWN0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NhcnQnKSB7XG4gICAgICAgIGNvbnN0IGNhcnRCb290c3RyYXAgPSBuZXcgQ2FydEJvb3RzdHJhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICApO1xuXG4gICAgICAgIGNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAnY2hlY2tvdXQnKSB7XG4gICAgICAgIGNvbnN0IGNoZWNrb3V0Qm9vdHN0YXAgPSBuZXcgQ2hlY2tvdXRCb290c3RhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICAgICAgbWVzc2FnZVJlbmRlcmVyLFxuICAgICAgICAgICAgc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIGNoZWNrb3V0Qm9vdHN0YXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncGF5LW5vdycgKSB7XG4gICAgICAgIGNvbnN0IHBheU5vd0Jvb3RzdHJhcCA9IG5ldyBQYXlOb3dCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcbiAgICAgICAgcGF5Tm93Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCAhPT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBtZXNzYWdlUmVuZGVyZXIucmVuZGVyKCk7XG4gICAgfVxufTtcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgJ0RPTUNvbnRlbnRMb2FkZWQnLFxuICAgICgpID0+IHtcbiAgICAgICAgaWYgKCF0eXBlb2YgKFBheVBhbENvbW1lcmNlR2F0ZXdheSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1BheVBhbCBidXR0b24gY291bGQgbm90IGJlIGNvbmZpZ3VyZWQuJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXkuY29udGV4dCAhPT0gJ2NoZWNrb3V0J1xuICAgICAgICAgICAgJiYgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkLnVzZXIgPT09IDBcbiAgICAgICAgICAgICYmIFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZC5oYXNfc3Vic2NyaXB0aW9uc1xuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICBzY3JpcHQuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgYm9vdHN0cmFwKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdzcmMnLCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuYnV0dG9uLnVybCk7XG4gICAgICAgIE9iamVjdC5lbnRyaWVzKFBheVBhbENvbW1lcmNlR2F0ZXdheS5zY3JpcHRfYXR0cmlidXRlcykuZm9yRWFjaChcbiAgICAgICAgICAgIChrZXlWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoa2V5VmFsdWVbMF0sIGtleVZhbHVlWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkLnNldF9hdHRyaWJ1dGUpIHtcbiAgICAgICAgICAgIGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIoc2NyaXB0LCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoc2NyaXB0KTtcbiAgICB9LFxuKTtcbiJdLCJuYW1lcyI6WyJFcnJvckhhbmRsZXIiLCJjb25zdHJ1Y3RvciIsImdlbmVyaWNFcnJvclRleHQiLCJ3cmFwcGVyIiwiZG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwibWVzc2FnZXNMaXN0IiwiZ2VuZXJpY0Vycm9yIiwiY2xhc3NMaXN0IiwiY29udGFpbnMiLCJjbGVhciIsIm1lc3NhZ2UiLCJhcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQiLCJlcnJvck1lc3NhZ2VFbGVtZW50IiwicHJlcGFyZU1lc3NhZ2VzTGlzdCIsInJlcGxhY2VXaXRoIiwidGV4dCIsInBlcnNpc3QiLCJTdHJpbmciLCJsZW5ndGgiLCJFcnJvciIsImFkZCIsInJlbW92ZSIsIm1lc3NhZ2VOb2RlIiwicHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0iLCJhcHBlbmRDaGlsZCIsImpRdWVyeSIsInNjcm9sbF90b19ub3RpY2VzIiwiY3JlYXRlRWxlbWVudCIsInNldEF0dHJpYnV0ZSIsImxpIiwiaW5uZXJIVE1MIiwic2FuaXRpemUiLCJ0ZXh0YXJlYSIsInZhbHVlIiwicmVwbGFjZSIsIm9uQXBwcm92ZSIsImNvbnRleHQiLCJlcnJvckhhbmRsZXIiLCJkYXRhIiwiYWN0aW9ucyIsImZldGNoIiwiY29uZmlnIiwiYWpheCIsImFwcHJvdmVfb3JkZXIiLCJlbmRwb2ludCIsIm1ldGhvZCIsImJvZHkiLCJKU09OIiwic3RyaW5naWZ5Iiwibm9uY2UiLCJvcmRlcl9pZCIsIm9yZGVySUQiLCJmdW5kaW5nX3NvdXJjZSIsIndpbmRvdyIsInBwY3BGdW5kaW5nU291cmNlIiwidGhlbiIsInJlcyIsImpzb24iLCJzdWNjZXNzIiwicmVzdGFydCIsImNhdGNoIiwiZXJyIiwibG9jYXRpb24iLCJocmVmIiwicmVkaXJlY3QiLCJwYXllckRhdGEiLCJwYXllciIsIlBheVBhbENvbW1lcmNlR2F0ZXdheSIsInBob25lIiwicGhvbmVfdHlwZSIsInBob25lX251bWJlciIsIm5hdGlvbmFsX251bWJlciIsImVtYWlsX2FkZHJlc3MiLCJuYW1lIiwic3VybmFtZSIsImdpdmVuX25hbWUiLCJhZGRyZXNzIiwiY291bnRyeV9jb2RlIiwiYWRkcmVzc19saW5lXzEiLCJhZGRyZXNzX2xpbmVfMiIsImFkbWluX2FyZWFfMSIsImFkbWluX2FyZWFfMiIsInBvc3RhbF9jb2RlIiwiQ2FydEFjdGlvbkhhbmRsZXIiLCJjb25maWd1cmF0aW9uIiwiY3JlYXRlT3JkZXIiLCJibkNvZGUiLCJibl9jb2RlcyIsImNyZWF0ZV9vcmRlciIsInB1cmNoYXNlX3VuaXRzIiwiYm5fY29kZSIsImNvbnNvbGUiLCJlcnJvciIsImlkIiwib25FcnJvciIsIk1pbmlDYXJ0Qm9vdHN0YXAiLCJnYXRld2F5IiwicmVuZGVyZXIiLCJhY3Rpb25IYW5kbGVyIiwiaW5pdCIsImxhYmVscyIsImdlbmVyaWMiLCJyZW5kZXIiLCJvbiIsInNob3VsZFJlbmRlciIsImJ1dHRvbiIsIm1pbmlfY2FydF93cmFwcGVyIiwiaG9zdGVkX2ZpZWxkcyIsIlByb2R1Y3QiLCJVcGRhdGVDYXJ0IiwidXBkYXRlIiwib25SZXNvbHZlIiwicHJvZHVjdHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlc3VsdCIsInJlc29sdmVkIiwiQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIiwiZWxlbWVudCIsInNob3dDYWxsYmFjayIsImhpZGVDYWxsYmFjayIsIm9ic2VydmVyIiwiYXR0cmlidXRlcyIsImNhbGxiYWNrIiwiTXV0YXRpb25PYnNlcnZlciIsIm9ic2VydmUiLCJkaXNjb25uZWN0IiwicXVhbnRpdHkiLCJ2YXJpYXRpb25zIiwiU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIiLCJ1cGRhdGVDYXJ0Iiwic2hvd0J1dHRvbkNhbGxiYWNrIiwiaGlkZUJ1dHRvbkNhbGxiYWNrIiwiZm9ybUVsZW1lbnQiLCJoYXNWYXJpYXRpb25zIiwiZ2V0UHJvZHVjdHMiLCJpc0dyb3VwZWRQcm9kdWN0IiwicXR5IiwicXVlcnlTZWxlY3RvckFsbCIsImZvckVhY2giLCJlbGVtZW50TmFtZSIsImdldEF0dHJpYnV0ZSIsIm1hdGNoIiwicGFyc2VJbnQiLCJwdXNoIiwicHJvbWlzZSIsIm1hcCIsIlNpbmdsZVByb2R1Y3RCb290c3RhcCIsIm1lc3NhZ2VzIiwiaGlkZUJ1dHRvbnMiLCJjaGFuZ2VfY2FydCIsInNob3dCdXR0b25zIiwicHJpY2VUZXh0IiwiaW5uZXJUZXh0IiwiYW1vdW50IiwicmVuZGVyV2l0aEFtb3VudCIsIkNhcnRCb290c3RyYXAiLCJzcGlubmVyIiwiYmxvY2siLCJ1bmJsb2NrIiwiY29kZSIsImNsaWNrIiwiQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIiwiZm9ybVNlbGVjdG9yIiwiZm9ybVZhbHVlcyIsInNlcmlhbGl6ZSIsImNyZWF0ZWFjY291bnQiLCJpcyIsImZvcm0iLCJkb21QYXJzZXIiLCJET01QYXJzZXIiLCJwYXJzZUZyb21TdHJpbmciLCJpbnB1dCIsImN1c3RvbV9pZCIsImFwcGVuZCIsIm9uQ2FuY2VsIiwiZ2V0RWxlbWVudCIsInNlbGVjdG9yT3JFbGVtZW50IiwiaXNWaXNpYmxlIiwib2Zmc2V0V2lkdGgiLCJvZmZzZXRIZWlnaHQiLCJnZXRDbGllbnRSZWN0cyIsInNldFZpc2libGUiLCJzaG93IiwiaW1wb3J0YW50IiwiY3VycmVudFZhbHVlIiwic3R5bGUiLCJnZXRQcm9wZXJ0eVZhbHVlIiwic2V0UHJvcGVydHkiLCJyZW1vdmVQcm9wZXJ0eSIsImhpZGUiLCJDaGVja291dEJvb3RzdGFwIiwic3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yIiwiYnV0dG9uQ2hhbmdlT2JzZXJ2ZXIiLCJlbCIsInVwZGF0ZVVpIiwidmFsIiwiY2FuY2VsX3dyYXBwZXIiLCJjdXJyZW50UGF5bWVudE1ldGhvZCIsImlzUGF5cGFsIiwiaXNDYXJkIiwiaXNTYXZlZENhcmQiLCJpc1NhdmVkQ2FyZFNlbGVjdGVkIiwiaXNOb3RPdXJHYXRld2F5IiwiZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMiLCJlbmFibGVDcmVkaXRDYXJkRmllbGRzIiwiYWRkQ2xhc3MiLCJhdHRyIiwicmVtb3ZlQ2xhc3MiLCJzYXZlZENhcmRMaXN0IiwiUGF5Tm93Qm9vdHN0cmFwIiwidXJsUGFyYW1zIiwiVVJMU2VhcmNoUGFyYW1zIiwic2VhcmNoIiwiaGFzIiwiUmVuZGVyZXIiLCJjcmVkaXRDYXJkUmVuZGVyZXIiLCJkZWZhdWx0Q29uZmlnIiwib25TbWFydEJ1dHRvbkNsaWNrIiwiaG9zdGVkRmllbGRzV3JhcHBlciIsImNvbnRleHRDb25maWciLCJyZW5kZXJCdXR0b25zIiwiaXNBbHJlYWR5UmVuZGVyZWQiLCJwYXlwYWwiLCJCdXR0b25zIiwibWluaV9jYXJ0X3N0eWxlIiwib25DbGljayIsImhhc0NoaWxkTm9kZXMiLCJkb21FbGVtZW50IiwiZGlzcGxheSIsImRpc2FibGVGaWVsZHMiLCJlbmFibGVGaWVsZHMiLCJkY2NJbnB1dEZhY3RvcnkiLCJvcmlnaW5hbCIsInN0eWxlcyIsImdldENvbXB1dGVkU3R5bGUiLCJuZXdFbGVtZW50IiwiT2JqZWN0IiwidmFsdWVzIiwicHJvcCIsImlzTmFOIiwiQ3JlZGl0Q2FyZFJlbmRlcmVyIiwiY2FyZFZhbGlkIiwiZm9ybVZhbGlkIiwiY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlIiwiZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkIiwiSG9zdGVkRmllbGRzIiwiaXNFbGlnaWJsZSIsIndyYXBwZXJFbGVtZW50IiwicGFyZW50Tm9kZSIsInJlbW92ZUNoaWxkIiwidGVhcmRvd24iLCJnYXRlV2F5Qm94Iiwib2xkRGlzcGxheVN0eWxlIiwiaGlkZURjY0dhdGV3YXkiLCJjYXJkTnVtYmVyRmllbGQiLCJzdHlsZXNSYXciLCJjYXJkTnVtYmVyIiwicmVwbGFjZUNoaWxkIiwiY2FyZEV4cGlyeUZpZWxkIiwiY2FyZEV4cGlyeSIsImNhcmRDb2RlRmllbGQiLCJjYXJkQ29kZSIsImZvcm1XcmFwcGVyIiwiZW5mb3JjZV92YXVsdCIsImNoZWNrZWQiLCJmaWVsZHMiLCJudW1iZXIiLCJzZWxlY3RvciIsInBsYWNlaG9sZGVyIiwiY3JlZGl0X2NhcmRfbnVtYmVyIiwiY3Z2IiwiZXhwaXJhdGlvbkRhdGUiLCJtbV95eSIsImhvc3RlZEZpZWxkcyIsImRpc3BhdGNoRXZlbnQiLCJDdXN0b21FdmVudCIsIl9zdWJtaXQiLCJldmVudCIsImNhcmRzIiwidmFsaWRDYXJkcyIsInZhbGlkX2NhcmRzIiwiaW5kZXhPZiIsInR5cGUiLCJrZXlzIiwiZXZlcnkiLCJrZXkiLCJpc1ZhbGlkIiwiYWRkRXZlbnRMaXN0ZW5lciIsInByZXZlbnREZWZhdWx0IiwiZmllbGQiLCJhdHRyaWJ1dGUiLCJyZW1vdmVBdHRyaWJ1dGUiLCJzYXZlX2NhcmQiLCJ2YXVsdCIsImdldEVsZW1lbnRCeUlkIiwiY29udGluZ2VuY3kiLCJob3N0ZWRGaWVsZHNEYXRhIiwiY29udGluZ2VuY2llcyIsImNhcmRob2xkZXJOYW1lIiwiZmlyc3ROYW1lIiwibGFzdE5hbWUiLCJjYXJkaG9sZGVyX25hbWVfcmVxdWlyZWQiLCJzdWJtaXQiLCJwYXlsb2FkIiwib3JkZXJJZCIsImNhcmRfbm90X3N1cHBvcnRlZCIsImZpZWxkc19ub3RfdmFsaWQiLCJzdG9yYWdlS2V5IiwidmFsaWRhdGVUb2tlbiIsInRva2VuIiwidXNlciIsImN1cnJlbnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJpc0V4cGlyZWQiLCJleHBpcmF0aW9uIiwic3RvcmVkVG9rZW5Gb3JVc2VyIiwicGFyc2UiLCJzZXNzaW9uU3RvcmFnZSIsImdldEl0ZW0iLCJzdG9yZVRva2VuIiwic2V0SXRlbSIsImRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIiLCJzY3JpcHQiLCJNZXNzYWdlUmVuZGVyZXIiLCJNZXNzYWdlcyIsInBsYWNlbWVudCIsIm5ld1dyYXBwZXIiLCJzaWJsaW5nIiwibmV4dFNpYmxpbmciLCJwYXJlbnRFbGVtZW50IiwiaW5zZXJ0QmVmb3JlIiwiU3Bpbm5lciIsInRhcmdldCIsInNldFRhcmdldCIsIm92ZXJsYXlDU1MiLCJiYWNrZ3JvdW5kIiwib3BhY2l0eSIsImJvb3RzdHJhcCIsImZ1bmRpbmdTb3VyY2UiLCJtZXNzYWdlUmVuZGVyZXIiLCJtaW5pX2NhcnRfYnV0dG9uc19lbmFibGVkIiwibWluaUNhcnRCb290c3RyYXAiLCJzaW5nbGVfcHJvZHVjdF9idXR0b25zX2VuYWJsZWQiLCJzaW5nbGVQcm9kdWN0Qm9vdHN0cmFwIiwiY2FydEJvb3RzdHJhcCIsImNoZWNrb3V0Qm9vdHN0YXAiLCJwYXlOb3dCb290c3RyYXAiLCJkYXRhX2NsaWVudF9pZCIsImhhc19zdWJzY3JpcHRpb25zIiwidXJsIiwiZW50cmllcyIsInNjcmlwdF9hdHRyaWJ1dGVzIiwia2V5VmFsdWUiLCJzZXRfYXR0cmlidXRlIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///964\n")}},__webpack_exports__={};__webpack_modules__[964]()})();
modules/ppcp-button/resources/js/button.js CHANGED
@@ -82,8 +82,16 @@ document.addEventListener(
82
  console.error('PayPal button could not be configured.');
83
  return;
84
  }
85
- const script = document.createElement('script');
86
 
 
 
 
 
 
 
 
 
 
87
  script.addEventListener('load', (event) => {
88
  bootstrap();
89
  });
82
  console.error('PayPal button could not be configured.');
83
  return;
84
  }
 
85
 
86
+ if (
87
+ PayPalCommerceGateway.context !== 'checkout'
88
+ && PayPalCommerceGateway.data_client_id.user === 0
89
+ && PayPalCommerceGateway.data_client_id.has_subscriptions
90
+ ) {
91
+ return;
92
+ }
93
+
94
+ const script = document.createElement('script');
95
  script.addEventListener('load', (event) => {
96
  bootstrap();
97
  });
modules/ppcp-button/services.php CHANGED
@@ -90,7 +90,7 @@ return array(
90
  'button.url' => static function ( ContainerInterface $container ): string {
91
  return plugins_url(
92
  '/modules/ppcp-button/',
93
- dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
94
  );
95
  },
96
  'button.request-data' => static function ( ContainerInterface $container ): RequestData {
90
  'button.url' => static function ( ContainerInterface $container ): string {
91
  return plugins_url(
92
  '/modules/ppcp-button/',
93
+ dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
94
  );
95
  },
96
  'button.request-data' => static function ( ContainerInterface $container ): RequestData {
modules/ppcp-button/src/Assets/SmartButton.php CHANGED
@@ -215,11 +215,12 @@ class SmartButton implements SmartButtonInterface {
215
  function ( array $default_fields, $id ) use ( $subscription_helper ) : array {
216
  if ( is_user_logged_in() && $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) && CreditCardGateway::ID === $id ) {
217
 
218
- if ( ! $subscription_helper->cart_contains_subscription() ) {
219
- $default_fields['card-vault'] = sprintf(
220
- '<p class="form-row form-row-wide"><label for="vault"><input class="ppcp-credit-card-vault" type="checkbox" id="ppcp-credit-card-vault" name="vault">%s</label></p>',
221
- esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' )
222
- );
 
223
  }
224
 
225
  $tokens = $this->payment_token_repository->all_for_user_id( get_current_user_id() );
@@ -391,9 +392,6 @@ class SmartButton implements SmartButtonInterface {
391
  if ( ! is_checkout() && ! $buttons_enabled ) {
392
  return false;
393
  }
394
- if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
395
- return false;
396
- }
397
 
398
  $load_script = false;
399
  if ( is_checkout() && $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
@@ -406,7 +404,7 @@ class SmartButton implements SmartButtonInterface {
406
  if ( in_array( $this->context(), array( 'pay-now', 'checkout' ), true ) && $this->can_render_dcc() ) {
407
  wp_enqueue_style(
408
  'ppcp-hosted-fields',
409
- $this->module_url . '/assets/css/hosted-fields.css',
410
  array(),
411
  1
412
  );
@@ -414,7 +412,7 @@ class SmartButton implements SmartButtonInterface {
414
  if ( $load_script ) {
415
  wp_enqueue_script(
416
  'ppcp-smart-button',
417
- $this->module_url . '/assets/js/button.js',
418
  array( 'jquery' ),
419
  '1.3.2',
420
  true
@@ -570,7 +568,8 @@ class SmartButton implements SmartButtonInterface {
570
  return;
571
  }
572
 
573
- $label = 'checkout' === $this->context() ? __( 'Place order', 'woocommerce-paypal-payments' ) : __( 'Pay for order', 'woocommerce-paypal-payments' );
 
574
 
575
  printf(
576
  '<div id="%1$s" style="display:none;">
@@ -597,7 +596,7 @@ class SmartButton implements SmartButtonInterface {
597
  return false;
598
  }
599
 
600
- return is_user_logged_in();
601
  }
602
 
603
  /**
@@ -612,6 +611,10 @@ class SmartButton implements SmartButtonInterface {
612
  if ( is_product() ) {
613
  return $this->subscription_helper->current_product_is_subscription();
614
  }
 
 
 
 
615
  return $this->subscription_helper->cart_contains_subscription();
616
  }
617
 
@@ -644,10 +647,11 @@ class SmartButton implements SmartButtonInterface {
644
  $localize = array(
645
  'script_attributes' => $this->attributes(),
646
  'data_client_id' => array(
647
- 'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() ) || $this->can_save_vault_token(),
648
- 'endpoint' => home_url( \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ) ),
649
- 'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ),
650
- 'user' => get_current_user_id(),
 
651
  ),
652
  'redirect' => wc_get_checkout_url(),
653
  'context' => $this->context(),
215
  function ( array $default_fields, $id ) use ( $subscription_helper ) : array {
216
  if ( is_user_logged_in() && $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) && CreditCardGateway::ID === $id ) {
217
 
218
+ $default_fields['card-vault'] = sprintf(
219
+ '<p class="form-row form-row-wide"><label for="ppcp-credit-card-vault"><input class="ppcp-credit-card-vault" type="checkbox" id="ppcp-credit-card-vault" name="vault">%s</label></p>',
220
+ esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' )
221
+ );
222
+ if ( $subscription_helper->cart_contains_subscription() || $subscription_helper->order_pay_contains_subscription() ) {
223
+ $default_fields['card-vault'] = '';
224
  }
225
 
226
  $tokens = $this->payment_token_repository->all_for_user_id( get_current_user_id() );
392
  if ( ! is_checkout() && ! $buttons_enabled ) {
393
  return false;
394
  }
 
 
 
395
 
396
  $load_script = false;
397
  if ( is_checkout() && $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
404
  if ( in_array( $this->context(), array( 'pay-now', 'checkout' ), true ) && $this->can_render_dcc() ) {
405
  wp_enqueue_style(
406
  'ppcp-hosted-fields',
407
+ untrailingslashit( $this->module_url ) . '/assets/css/hosted-fields.css',
408
  array(),
409
  1
410
  );
412
  if ( $load_script ) {
413
  wp_enqueue_script(
414
  'ppcp-smart-button',
415
+ untrailingslashit( $this->module_url ) . '/assets/js/button.js',
416
  array( 'jquery' ),
417
  '1.3.2',
418
  true
568
  return;
569
  }
570
 
571
+ // phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
572
+ $label = 'checkout' === $this->context() ? apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ) : __( 'Pay for order', 'woocommerce' );
573
 
574
  printf(
575
  '<div id="%1$s" style="display:none;">
596
  return false;
597
  }
598
 
599
+ return true;
600
  }
601
 
602
  /**
611
  if ( is_product() ) {
612
  return $this->subscription_helper->current_product_is_subscription();
613
  }
614
+ if ( is_wc_endpoint_url( 'order-pay' ) ) {
615
+ return $this->subscription_helper->order_pay_contains_subscription();
616
+ }
617
+
618
  return $this->subscription_helper->cart_contains_subscription();
619
  }
620
 
647
  $localize = array(
648
  'script_attributes' => $this->attributes(),
649
  'data_client_id' => array(
650
+ 'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() ) || $this->can_save_vault_token(),
651
+ 'endpoint' => home_url( \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ) ),
652
+ 'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ),
653
+ 'user' => get_current_user_id(),
654
+ 'has_subscriptions' => $this->has_subscriptions(),
655
  ),
656
  'redirect' => wc_get_checkout_url(),
657
  'context' => $this->context(),
modules/ppcp-button/src/Endpoint/DataClientIdEndpoint.php CHANGED
@@ -80,7 +80,7 @@ class DataClientIdEndpoint implements EndpointInterface {
80
  try {
81
  $this->request_data->read_request( $this->nonce() );
82
  $user_id = get_current_user_id();
83
- $token = $this->identity_token->generate_for_customer( $user_id );
84
  wp_send_json(
85
  array(
86
  'token' => $token->token(),
80
  try {
81
  $this->request_data->read_request( $this->nonce() );
82
  $user_id = get_current_user_id();
83
+ $token = $this->identity_token->generate_for_user( $user_id );
84
  wp_send_json(
85
  array(
86
  'token' => $token->token(),
modules/ppcp-onboarding/services.php CHANGED
@@ -139,7 +139,7 @@ return array(
139
  'onboarding.url' => static function ( ContainerInterface $container ): string {
140
  return plugins_url(
141
  '/modules/ppcp-onboarding/',
142
- dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
143
  );
144
  },
145
 
139
  'onboarding.url' => static function ( ContainerInterface $container ): string {
140
  return plugins_url(
141
  '/modules/ppcp-onboarding/',
142
+ dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
143
  );
144
  },
145
 
modules/ppcp-onboarding/src/Assets/OnboardingAssets.php CHANGED
@@ -63,14 +63,14 @@ class OnboardingAssets {
63
  */
64
  public function register(): bool {
65
 
66
- $url = $this->module_url . '/assets/css/onboarding.css';
67
  wp_register_style(
68
  'ppcp-onboarding',
69
  $url,
70
  array(),
71
  1
72
  );
73
- $url = $this->module_url . '/assets/js/settings.js';
74
  wp_register_script(
75
  'ppcp-settings',
76
  $url,
@@ -79,7 +79,7 @@ class OnboardingAssets {
79
  true
80
  );
81
 
82
- $url = $this->module_url . '/assets/js/onboarding.js';
83
  wp_register_script(
84
  'ppcp-onboarding',
85
  $url,
63
  */
64
  public function register(): bool {
65
 
66
+ $url = untrailingslashit( $this->module_url ) . '/assets/css/onboarding.css';
67
  wp_register_style(
68
  'ppcp-onboarding',
69
  $url,
70
  array(),
71
  1
72
  );
73
+ $url = untrailingslashit( $this->module_url ) . '/assets/js/settings.js';
74
  wp_register_script(
75
  'ppcp-settings',
76
  $url,
79
  true
80
  );
81
 
82
+ $url = untrailingslashit( $this->module_url ) . '/assets/js/onboarding.js';
83
  wp_register_script(
84
  'ppcp-onboarding',
85
  $url,
modules/ppcp-subscription/services.php CHANGED
@@ -23,12 +23,14 @@ return array(
23
  $endpoint = $container->get( 'api.endpoint.order' );
24
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
25
  $payer_factory = $container->get( 'api.factory.payer' );
 
26
  return new RenewalHandler(
27
  $logger,
28
  $repository,
29
  $endpoint,
30
  $purchase_unit_factory,
31
- $payer_factory
 
32
  );
33
  },
34
  'subscription.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository {
23
  $endpoint = $container->get( 'api.endpoint.order' );
24
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
25
  $payer_factory = $container->get( 'api.factory.payer' );
26
+ $environment = $container->get( 'onboarding.environment' );
27
  return new RenewalHandler(
28
  $logger,
29
  $repository,
30
  $endpoint,
31
  $purchase_unit_factory,
32
+ $payer_factory,
33
+ $environment
34
  );
35
  },
36
  'subscription.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository {
modules/ppcp-subscription/src/Helper/SubscriptionHelper.php CHANGED
@@ -55,6 +55,42 @@ class SubscriptionHelper {
55
  return false;
56
  }
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  /**
59
  * Whether only automatic payment gateways are accepted.
60
  *
55
  return false;
56
  }
57
 
58
+ /**
59
+ * Whether pay for order contains subscriptions.
60
+ *
61
+ * @return bool
62
+ */
63
+ public function order_pay_contains_subscription(): bool {
64
+ if ( ! $this->plugin_is_active() || ! is_wc_endpoint_url( 'order-pay' ) ) {
65
+ return false;
66
+ }
67
+
68
+ global $wp;
69
+ $order_id = (int) $wp->query_vars['order-pay'];
70
+ if ( 0 === $order_id ) {
71
+ return false;
72
+ }
73
+
74
+ $order = wc_get_order( $order_id );
75
+ if ( is_a( $order, \WC_Order::class ) ) {
76
+ foreach ( $order->get_items() as $item ) {
77
+ if ( is_a( $item, \WC_Order_Item_Product::class ) ) {
78
+ $product = wc_get_product( $item->get_product_id() );
79
+ /**
80
+ * Class already exist in subscriptions plugin.
81
+ *
82
+ * @psalm-suppress UndefinedClass
83
+ */
84
+ if ( is_a( $product, \WC_Product_Subscription::class ) ) {
85
+ return true;
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ return false;
92
+ }
93
+
94
  /**
95
  * Whether only automatic payment gateways are accepted.
96
  *
modules/ppcp-subscription/src/RenewalHandler.php CHANGED
@@ -10,21 +10,26 @@ declare(strict_types=1);
10
  namespace WooCommerce\PayPalCommerce\Subscription;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
13
- use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
14
- use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
16
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
17
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
 
18
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
19
- use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
20
  use Psr\Log\LoggerInterface;
21
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
 
 
 
22
 
23
  /**
24
  * Class RenewalHandler
25
  */
26
  class RenewalHandler {
27
 
 
 
 
 
28
  /**
29
  * The logger.
30
  *
@@ -60,6 +65,13 @@ class RenewalHandler {
60
  */
61
  private $payer_factory;
62
 
 
 
 
 
 
 
 
63
  /**
64
  * RenewalHandler constructor.
65
  *
@@ -68,13 +80,15 @@ class RenewalHandler {
68
  * @param OrderEndpoint $order_endpoint The order endpoint.
69
  * @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
70
  * @param PayerFactory $payer_factory The payer factory.
 
71
  */
72
  public function __construct(
73
  LoggerInterface $logger,
74
  PaymentTokenRepository $repository,
75
  OrderEndpoint $order_endpoint,
76
  PurchaseUnitFactory $purchase_unit_factory,
77
- PayerFactory $payer_factory
 
78
  ) {
79
 
80
  $this->logger = $logger;
@@ -82,6 +96,7 @@ class RenewalHandler {
82
  $this->order_endpoint = $order_endpoint;
83
  $this->purchase_unit_factory = $purchase_unit_factory;
84
  $this->payer_factory = $payer_factory;
 
85
  }
86
 
87
  /**
@@ -90,52 +105,23 @@ class RenewalHandler {
90
  * @param \WC_Order $wc_order The WooCommerce order.
91
  */
92
  public function renew( \WC_Order $wc_order ) {
93
-
94
- $this->logger->log(
95
- 'info',
96
- sprintf(
97
- // translators: %d is the id of the order.
98
- __( 'Start moneytransfer for order %d', 'woocommerce-paypal-payments' ),
99
- (int) $wc_order->get_id()
100
- ),
101
- array(
102
- 'order' => $wc_order,
103
- )
104
- );
105
-
106
  try {
107
  $this->process_order( $wc_order );
108
  } catch ( \Exception $error ) {
109
- $this->logger->log(
110
- 'error',
111
  sprintf(
112
- // translators: %1$d is the order number, %2$s the error message.
113
- __(
114
- 'An error occured while trying to renew the subscription for order %1$d: %2$s',
115
- 'woocommerce-paypal-payments'
116
- ),
117
- (int) $wc_order->get_id(),
118
  $error->getMessage()
119
- ),
120
- array(
121
- 'order' => $wc_order,
122
  )
123
  );
124
 
125
  return;
126
  }
127
- $this->logger->log(
128
- 'info',
129
  sprintf(
130
- // translators: %d is the order number.
131
- __(
132
- 'Moneytransfer for order %d is completed.',
133
- 'woocommerce-paypal-payments'
134
- ),
135
- (int) $wc_order->get_id()
136
- ),
137
- array(
138
- 'order' => $wc_order,
139
  )
140
  );
141
  }
@@ -164,7 +150,19 @@ class RenewalHandler {
164
  $token
165
  );
166
 
167
- $this->capture_order( $order, $wc_order );
 
 
 
 
 
 
 
 
 
 
 
 
168
  }
169
 
170
  /**
@@ -185,12 +183,8 @@ class RenewalHandler {
185
  if ( ! $tokens ) {
186
 
187
  $error_message = sprintf(
188
- // translators: %d is the customer id.
189
- __(
190
- 'Payment failed. No payment tokens found for customer %d.',
191
- 'woocommerce-paypal-payments'
192
- ),
193
- (int) $customer->get_id()
194
  );
195
 
196
  $wc_order->update_status(
@@ -198,14 +192,7 @@ class RenewalHandler {
198
  $error_message
199
  );
200
 
201
- $this->logger->log(
202
- 'error',
203
- $error_message,
204
- array(
205
- 'customer' => $customer,
206
- 'order' => $wc_order,
207
- )
208
- );
209
  }
210
 
211
  $subscription = function_exists( 'wcs_get_subscription' ) ? wcs_get_subscription( $wc_order->get_meta( '_subscription_renewal' ) ) : null;
@@ -223,25 +210,4 @@ class RenewalHandler {
223
 
224
  return current( $tokens );
225
  }
226
-
227
- /**
228
- * If the PayPal order is captured/authorized the WooCommerce order gets updated accordingly.
229
- *
230
- * @param Order $order The PayPal order.
231
- * @param \WC_Order $wc_order The related WooCommerce order.
232
- */
233
- private function capture_order( Order $order, \WC_Order $wc_order ) {
234
-
235
- if ( $order->intent() === 'CAPTURE' && $order->status()->is( OrderStatus::COMPLETED ) ) {
236
- $wc_order->update_status(
237
- 'processing',
238
- __( 'Payment received.', 'woocommerce-paypal-payments' )
239
- );
240
- }
241
-
242
- if ( $order->intent() === 'AUTHORIZE' ) {
243
- $this->order_endpoint->authorize( $order );
244
- $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
245
- }
246
- }
247
  }
10
  namespace WooCommerce\PayPalCommerce\Subscription;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
 
 
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
14
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
15
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
16
+ use WooCommerce\PayPalCommerce\Onboarding\Environment;
17
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
 
18
  use Psr\Log\LoggerInterface;
19
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
20
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait;
21
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
22
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
23
 
24
  /**
25
  * Class RenewalHandler
26
  */
27
  class RenewalHandler {
28
 
29
+ use OrderMetaTrait;
30
+ use TransactionIdHandlingTrait;
31
+ use PaymentsStatusHandlingTrait;
32
+
33
  /**
34
  * The logger.
35
  *
65
  */
66
  private $payer_factory;
67
 
68
+ /**
69
+ * The environment.
70
+ *
71
+ * @var Environment
72
+ */
73
+ protected $environment;
74
+
75
  /**
76
  * RenewalHandler constructor.
77
  *
80
  * @param OrderEndpoint $order_endpoint The order endpoint.
81
  * @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
82
  * @param PayerFactory $payer_factory The payer factory.
83
+ * @param Environment $environment The environment.
84
  */
85
  public function __construct(
86
  LoggerInterface $logger,
87
  PaymentTokenRepository $repository,
88
  OrderEndpoint $order_endpoint,
89
  PurchaseUnitFactory $purchase_unit_factory,
90
+ PayerFactory $payer_factory,
91
+ Environment $environment
92
  ) {
93
 
94
  $this->logger = $logger;
96
  $this->order_endpoint = $order_endpoint;
97
  $this->purchase_unit_factory = $purchase_unit_factory;
98
  $this->payer_factory = $payer_factory;
99
+ $this->environment = $environment;
100
  }
101
 
102
  /**
105
  * @param \WC_Order $wc_order The WooCommerce order.
106
  */
107
  public function renew( \WC_Order $wc_order ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  try {
109
  $this->process_order( $wc_order );
110
  } catch ( \Exception $error ) {
111
+ $this->logger->error(
 
112
  sprintf(
113
+ 'An error occurred while trying to renew the subscription for order %1$d: %2$s',
114
+ $wc_order->get_id(),
 
 
 
 
115
  $error->getMessage()
 
 
 
116
  )
117
  );
118
 
119
  return;
120
  }
121
+ $this->logger->info(
 
122
  sprintf(
123
+ 'Renewal for order %d is completed.',
124
+ $wc_order->get_id()
 
 
 
 
 
 
 
125
  )
126
  );
127
  }
150
  $token
151
  );
152
 
153
+ $this->add_paypal_meta( $wc_order, $order, $this->environment );
154
+
155
+ if ( $order->intent() === 'AUTHORIZE' ) {
156
+ $order = $this->order_endpoint->authorize( $order );
157
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
158
+ }
159
+
160
+ $transaction_id = $this->get_paypal_order_transaction_id( $order );
161
+ if ( $transaction_id ) {
162
+ $this->update_transaction_id( $transaction_id, $wc_order );
163
+ }
164
+
165
+ $this->handle_new_order_status( $order, $wc_order );
166
  }
167
 
168
  /**
183
  if ( ! $tokens ) {
184
 
185
  $error_message = sprintf(
186
+ 'Payment failed. No payment tokens found for customer %d.',
187
+ $customer->get_id()
 
 
 
 
188
  );
189
 
190
  $wc_order->update_status(
192
  $error_message
193
  );
194
 
195
+ $this->logger->error( $error_message );
 
 
 
 
 
 
 
196
  }
197
 
198
  $subscription = function_exists( 'wcs_get_subscription' ) ? wcs_get_subscription( $wc_order->get_meta( '_subscription_renewal' ) ) : null;
210
 
211
  return current( $tokens );
212
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  }
modules/ppcp-vaulting/services.php CHANGED
@@ -17,7 +17,7 @@ return array(
17
  'vaulting.module-url' => static function ( ContainerInterface $container ): string {
18
  return plugins_url(
19
  '/modules/ppcp-vaulting/',
20
- dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
21
  );
22
  },
23
  'vaulting.assets.myaccount-payments' => function( ContainerInterface $container ) : MyAccountPaymentsAssets {
17
  'vaulting.module-url' => static function ( ContainerInterface $container ): string {
18
  return plugins_url(
19
  '/modules/ppcp-vaulting/',
20
+ dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
21
  );
22
  },
23
  'vaulting.assets.myaccount-payments' => function( ContainerInterface $container ) : MyAccountPaymentsAssets {
modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php CHANGED
@@ -42,7 +42,7 @@ class MyAccountPaymentsAssets {
42
  public function enqueue(): void {
43
  wp_enqueue_script(
44
  'ppcp-vaulting-myaccount-payments',
45
- $this->module_url . '/assets/js/myaccount-payments.js',
46
  array( 'jquery' ),
47
  '1',
48
  true
42
  public function enqueue(): void {
43
  wp_enqueue_script(
44
  'ppcp-vaulting-myaccount-payments',
45
+ untrailingslashit( $this->module_url ) . '/assets/js/myaccount-payments.js',
46
  array( 'jquery' ),
47
  '1',
48
  true
modules/ppcp-vaulting/src/VaultingModule.php CHANGED
@@ -98,6 +98,17 @@ class VaultingModule implements ModuleInterface {
98
  }
99
  );
100
 
 
 
 
 
 
 
 
 
 
 
 
101
  $asset_loader = $container->get( 'vaulting.assets.myaccount-payments' );
102
  add_action(
103
  'wp_enqueue_scripts',
98
  }
99
  );
100
 
101
+ $subscription_helper = $container->get( 'subscription.helper' );
102
+ add_action(
103
+ 'woocommerce_created_customer',
104
+ function( int $customer_id ) use ( $subscription_helper ) {
105
+ $guest_customer_id = WC()->session->get( 'ppcp_guest_customer_id' );
106
+ if ( $guest_customer_id && $subscription_helper->cart_contains_subscription() ) {
107
+ update_user_meta( $customer_id, 'ppcp_guest_customer_id', $guest_customer_id );
108
+ }
109
+ }
110
+ );
111
+
112
  $asset_loader = $container->get( 'vaulting.assets.myaccount-payments' );
113
  add_action(
114
  'wp_enqueue_scripts',
modules/ppcp-wc-gateway/services.php CHANGED
@@ -120,8 +120,7 @@ return array(
120
  'wcgateway.disabler' => static function ( ContainerInterface $container ): DisableGateways {
121
  $session_handler = $container->get( 'session.handler' );
122
  $settings = $container->get( 'wcgateway.settings' );
123
- $subscription_helper = $container->get( 'subscription.helper' );
124
- return new DisableGateways( $session_handler, $settings, $subscription_helper );
125
  },
126
  'wcgateway.is-wc-payments-page' => static function ( ContainerInterface $container ): bool {
127
  $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
@@ -729,7 +728,8 @@ return array(
729
  'title' => __( 'Logging', 'woocommerce-paypal-payments' ),
730
  'type' => 'checkbox',
731
  'desc_tip' => true,
732
- 'label' => __( 'Enable logging', 'woocommerce-paypal-payments' ),
 
733
  'description' => __( 'Enable logging of unexpected behavior. This can also log private data and should only be enabled in a development or stage environment.', 'woocommerce-paypal-payments' ),
734
  'default' => false,
735
  'screens' => array(
@@ -1987,7 +1987,7 @@ return array(
1987
  'wcgateway.url' => static function ( ContainerInterface $container ): string {
1988
  return plugins_url(
1989
  $container->get( 'wcgateway.relative-path' ),
1990
- dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1991
  );
1992
  },
1993
  'wcgateway.relative-path' => static function( ContainerInterface $container ): string {
@@ -1995,7 +1995,7 @@ return array(
1995
  },
1996
  'wcgateway.absolute-path' => static function( ContainerInterface $container ): string {
1997
  return plugin_dir_path(
1998
- dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1999
  ) .
2000
  $container->get( 'wcgateway.relative-path' );
2001
  },
120
  'wcgateway.disabler' => static function ( ContainerInterface $container ): DisableGateways {
121
  $session_handler = $container->get( 'session.handler' );
122
  $settings = $container->get( 'wcgateway.settings' );
123
+ return new DisableGateways( $session_handler, $settings );
 
124
  },
125
  'wcgateway.is-wc-payments-page' => static function ( ContainerInterface $container ): bool {
126
  $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
728
  'title' => __( 'Logging', 'woocommerce-paypal-payments' ),
729
  'type' => 'checkbox',
730
  'desc_tip' => true,
731
+ 'label' => __( 'Enable logging. ', 'woocommerce-paypal-payments' ) .
732
+ ' <a href="' . admin_url( 'admin.php?page=wc-status&tab=logs' ) . '">' . __( 'View logs', 'woocommerce-paypal-payments' ) . '</a>',
733
  'description' => __( 'Enable logging of unexpected behavior. This can also log private data and should only be enabled in a development or stage environment.', 'woocommerce-paypal-payments' ),
734
  'default' => false,
735
  'screens' => array(
1987
  'wcgateway.url' => static function ( ContainerInterface $container ): string {
1988
  return plugins_url(
1989
  $container->get( 'wcgateway.relative-path' ),
1990
+ dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
1991
  );
1992
  },
1993
  'wcgateway.relative-path' => static function( ContainerInterface $container ): string {
1995
  },
1996
  'wcgateway.absolute-path' => static function( ContainerInterface $container ): string {
1997
  return plugin_dir_path(
1998
+ dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
1999
  ) .
2000
  $container->get( 'wcgateway.relative-path' );
2001
  },
modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php CHANGED
@@ -59,7 +59,7 @@ class SettingsPageAssets {
59
  add_action(
60
  'admin_enqueue_scripts',
61
  function() use ( $bearer ) {
62
- if ( ! is_admin() || is_ajax() ) {
63
  return;
64
  }
65
 
59
  add_action(
60
  'admin_enqueue_scripts',
61
  function() use ( $bearer ) {
62
+ if ( ! is_admin() || wp_doing_ajax() ) {
63
  return;
64
  }
65
 
modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php CHANGED
@@ -10,7 +10,6 @@ declare(strict_types=1);
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Checkout;
11
 
12
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
13
- use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
14
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
15
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
16
  use Psr\Container\ContainerInterface;
@@ -34,29 +33,19 @@ class DisableGateways {
34
  */
35
  private $settings;
36
 
37
- /**
38
- * The subscription helper
39
- *
40
- * @var SubscriptionHelper
41
- */
42
- private $subscription_helper;
43
-
44
  /**
45
  * DisableGateways constructor.
46
  *
47
  * @param SessionHandler $session_handler The Session Handler.
48
  * @param ContainerInterface $settings The Settings.
49
- * @param SubscriptionHelper $subscription_helper The subscription helper.
50
  */
51
  public function __construct(
52
  SessionHandler $session_handler,
53
- ContainerInterface $settings,
54
- SubscriptionHelper $subscription_helper
55
  ) {
56
 
57
- $this->session_handler = $session_handler;
58
- $this->settings = $settings;
59
- $this->subscription_helper = $subscription_helper;
60
  }
61
 
62
  /**
@@ -110,10 +99,6 @@ class DisableGateways {
110
  return true;
111
  }
112
 
113
- if ( $this->subscription_helper->cart_contains_subscription() && ! is_user_logged_in() ) {
114
- return true;
115
- }
116
-
117
  return false;
118
  }
119
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Checkout;
11
 
12
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
 
13
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
14
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
15
  use Psr\Container\ContainerInterface;
33
  */
34
  private $settings;
35
 
 
 
 
 
 
 
 
36
  /**
37
  * DisableGateways constructor.
38
  *
39
  * @param SessionHandler $session_handler The Session Handler.
40
  * @param ContainerInterface $settings The Settings.
 
41
  */
42
  public function __construct(
43
  SessionHandler $session_handler,
44
+ ContainerInterface $settings
 
45
  ) {
46
 
47
+ $this->session_handler = $session_handler;
48
+ $this->settings = $settings;
 
49
  }
50
 
51
  /**
99
  return true;
100
  }
101
 
 
 
 
 
102
  return false;
103
  }
104
 
modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php CHANGED
@@ -538,6 +538,14 @@ $data_rows_html
538
  'woocommerce-paypal-payments'
539
  );
540
  ?>
 
 
 
 
 
 
 
 
541
  </p>
542
  </td>
543
  </tr>
538
  'woocommerce-paypal-payments'
539
  );
540
  ?>
541
+ <a href="https://developer.paypal.com/docs/checkout/advanced/currency-availability-advanced-cards/">
542
+ <?php
543
+ esc_html_e(
544
+ 'Advanced credit and debit country and currency availability.',
545
+ 'woocommerce-paypal-payments'
546
+ );
547
+ ?>
548
+ </a>
549
  </p>
550
  </td>
551
  </tr>
modules/ppcp-webhooks/services.php CHANGED
@@ -197,7 +197,7 @@ return array(
197
  'webhook.module-url' => static function ( ContainerInterface $container ): string {
198
  return plugins_url(
199
  '/modules/ppcp-webhooks/',
200
- dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
201
  );
202
  },
203
  );
197
  'webhook.module-url' => static function ( ContainerInterface $container ): string {
198
  return plugins_url(
199
  '/modules/ppcp-webhooks/',
200
+ dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
201
  );
202
  },
203
  );
modules/ppcp-webhooks/src/Status/Assets/WebhooksStatusPageAssets.php CHANGED
@@ -45,14 +45,14 @@ class WebhooksStatusPageAssets {
45
  public function register(): void {
46
  wp_register_style(
47
  'ppcp-webhooks-status-page-style',
48
- $this->module_url . '/assets/css/status-page.css',
49
  array(),
50
  '1'
51
  );
52
 
53
  wp_register_script(
54
  'ppcp-webhooks-status-page',
55
- $this->module_url . '/assets/js/status-page.js',
56
  array(),
57
  '1',
58
  true
45
  public function register(): void {
46
  wp_register_style(
47
  'ppcp-webhooks-status-page-style',
48
+ untrailingslashit( $this->module_url ) . '/assets/css/status-page.css',
49
  array(),
50
  '1'
51
  );
52
 
53
  wp_register_script(
54
  'ppcp-webhooks-status-page',
55
+ untrailingslashit( $this->module_url ) . '/assets/js/status-page.js',
56
  array(),
57
  '1',
58
  true
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.4
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -81,6 +81,20 @@ Follow the steps below to connect the plugin to your PayPal account:
81
 
82
  == Changelog ==
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  = 1.6.4 =
85
  * Fix - Non admin user cannot save changes to the plugin settings #278
86
  * Fix - Empty space in invoice prefix causes smart buttons to not load #390
4
  Requires at least: 5.3
5
  Tested up to: 5.8
6
  Requires PHP: 7.1
7
+ Stable tag: 1.6.5
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
81
 
82
  == Changelog ==
83
 
84
+ = 1.6.5 =
85
+ * Fix - Allow guest users to purchase subscription products #422
86
+ * Fix - Transaction ID missing for renewal order #424
87
+ * Fix - Save your credit card checkbox should be removed in pay for order for subscriptions #420
88
+ * Fix - Null currency error when the Aelia currency switcher plugin is active #426
89
+ * Fix - Hide Reference Transactions check from logs #428
90
+ * Fix - Doubled plugin module URL path causing failure #438
91
+ * Fix - is_ajax deprecated #441
92
+ * Fix - Place order button from PayPal Card Processing does not get translated #290
93
+ * Fix - AMEX missing from supported cards for DCC Australia #432
94
+ * Fix - "Save your Credit Card" text not clickable to change checkbox state #430
95
+ * Fix - Improve DCC error notice when not available #435
96
+ * Enhancement - Add View Logs link #416
97
+
98
  = 1.6.4 =
99
  * Fix - Non admin user cannot save changes to the plugin settings #278
100
  * Fix - Empty space in invoice prefix causes smart buttons to not load #390
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInitf02c5bd9f6eb9b15933b2b810aafffd5::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit5f8a535cab56f9307bff46d869d583bc::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInitf02c5bd9f6eb9b15933b2b810aafffd5
6
  {
7
  private static $loader;
8
 
@@ -22,15 +22,15 @@ class ComposerAutoloaderInitf02c5bd9f6eb9b15933b2b810aafffd5
22
  return self::$loader;
23
  }
24
 
25
- spl_autoload_register(array('ComposerAutoloaderInitf02c5bd9f6eb9b15933b2b810aafffd5', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
- spl_autoload_unregister(array('ComposerAutoloaderInitf02c5bd9f6eb9b15933b2b810aafffd5', '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\ComposerStaticInitf02c5bd9f6eb9b15933b2b810aafffd5::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
@@ -51,19 +51,19 @@ class ComposerAutoloaderInitf02c5bd9f6eb9b15933b2b810aafffd5
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
- $includeFiles = Composer\Autoload\ComposerStaticInitf02c5bd9f6eb9b15933b2b810aafffd5::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
- composerRequiref02c5bd9f6eb9b15933b2b810aafffd5($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
- function composerRequiref02c5bd9f6eb9b15933b2b810aafffd5($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit5f8a535cab56f9307bff46d869d583bc
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit5f8a535cab56f9307bff46d869d583bc', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit5f8a535cab56f9307bff46d869d583bc', '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\ComposerStaticInit5f8a535cab56f9307bff46d869d583bc::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\ComposerStaticInit5f8a535cab56f9307bff46d869d583bc::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequire5f8a535cab56f9307bff46d869d583bc($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
+ function composerRequire5f8a535cab56f9307bff46d869d583bc($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 ComposerStaticInitf02c5bd9f6eb9b15933b2b810aafffd5
8
  {
9
  public static $files = array (
10
  '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
@@ -131,8 +131,8 @@ class ComposerStaticInitf02c5bd9f6eb9b15933b2b810aafffd5
131
  public static function getInitializer(ClassLoader $loader)
132
  {
133
  return \Closure::bind(function () use ($loader) {
134
- $loader->prefixLengthsPsr4 = ComposerStaticInitf02c5bd9f6eb9b15933b2b810aafffd5::$prefixLengthsPsr4;
135
- $loader->prefixDirsPsr4 = ComposerStaticInitf02c5bd9f6eb9b15933b2b810aafffd5::$prefixDirsPsr4;
136
 
137
  }, null, ClassLoader::class);
138
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit5f8a535cab56f9307bff46d869d583bc
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 = ComposerStaticInit5f8a535cab56f9307bff46d869d583bc::$prefixLengthsPsr4;
135
+ $loader->prefixDirsPsr4 = ComposerStaticInit5f8a535cab56f9307bff46d869d583bc::$prefixDirsPsr4;
136
 
137
  }, null, ClassLoader::class);
138
  }
woocommerce-paypal-payments.php CHANGED
@@ -3,13 +3,13 @@
3
  * Plugin Name: WooCommerce PayPal Payments
4
  * Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
5
  * Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
6
- * Version: 1.6.4
7
  * Author: WooCommerce
8
  * Author URI: https://woocommerce.com/
9
  * License: GPL-2.0
10
  * Requires PHP: 7.1
11
  * WC requires at least: 3.9
12
- * WC tested up to: 6.0
13
  * Text Domain: woocommerce-paypal-payments
14
  *
15
  * @package WooCommerce\PayPalCommerce
3
  * Plugin Name: WooCommerce PayPal Payments
4
  * Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
5
  * Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
6
+ * Version: 1.6.5
7
  * Author: WooCommerce
8
  * Author URI: https://woocommerce.com/
9
  * License: GPL-2.0
10
  * Requires PHP: 7.1
11
  * WC requires at least: 3.9
12
+ * WC tested up to: 6.1
13
  * Text Domain: woocommerce-paypal-payments
14
  *
15
  * @package WooCommerce\PayPalCommerce