WooCommerce PayPal Payments - Version 1.6.2

Version Description

  • Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
  • Fix - Can't checkout to certain countries with optional postcode #330
  • Fix - Prevent subscription from being purchased when saving payment fails #308
  • Fix - Guest users must checkout twice for subscriptions, no smart buttons loaded #342
  • Fix - Failed PayPal API request causing strange error #347
  • Fix - PayPal payments page empty after switching packages #350
  • Fix - Could Not Validate Nonce Error #239
  • Fix - Refund via PayPal dashboard does not set the WooCommerce order to "Refunded" #241
  • Fix - Uncaught TypeError: round() #344
  • Fix - Broken multi-level (nested) associative array values after getting submitted from checkout page #307
  • Fix - Transaction id missing in some cases #328
  • Fix - Payment not possible in pay for order form because of terms checkbox missing #294
  • Fix - "Save your Credit Card" shouldn't be optional when paying for a subscription #368
  • Fix - When paying for a subscription and vaulting fails, cart is cleared #367
  • Fix - Fatal error when activating PayPal Checkout plugin #363
Download this release

Release Info

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

Code changes from version 1.6.1 to 1.6.2

Files changed (334) hide show
  1. changelog.txt +17 -0
  2. modules/ppcp-admin-notices/composer.json +17 -0
  3. modules/ppcp-admin-notices/services.php +3 -3
  4. modules/ppcp-admin-notices/src/{class-adminnotices.php → AdminNotices.php} +5 -9
  5. modules/ppcp-admin-notices/src/Entity/{class-message.php → Message.php} +0 -0
  6. modules/ppcp-admin-notices/src/Renderer/{class-renderer.php → Renderer.php} +0 -0
  7. modules/ppcp-admin-notices/src/Renderer/{class-rendererinterface.php → RendererInterface.php} +0 -0
  8. modules/ppcp-admin-notices/src/Repository/{class-repository.php → Repository.php} +0 -0
  9. modules/ppcp-admin-notices/src/Repository/{class-repositoryinterface.php → RepositoryInterface.php} +0 -0
  10. modules/ppcp-api-client/composer.json +17 -0
  11. modules/ppcp-api-client/services.php +39 -36
  12. modules/ppcp-api-client/src/{class-apimodule.php → ApiModule.php} +3 -7
  13. modules/ppcp-api-client/src/Authentication/{class-bearer.php → Bearer.php} +0 -0
  14. modules/ppcp-api-client/src/Authentication/{class-connectbearer.php → ConnectBearer.php} +0 -0
  15. modules/ppcp-api-client/src/Authentication/{class-paypalbearer.php → PayPalBearer.php} +0 -0
  16. modules/ppcp-api-client/src/Endpoint/{class-identitytoken.php → IdentityToken.php} +0 -0
  17. modules/ppcp-api-client/src/Endpoint/{class-loginseller.php → LoginSeller.php} +0 -0
  18. modules/ppcp-api-client/src/Endpoint/{class-orderendpoint.php → OrderEndpoint.php} +32 -1
  19. modules/ppcp-api-client/src/Endpoint/{class-partnerreferrals.php → PartnerReferrals.php} +0 -0
  20. modules/ppcp-api-client/src/Endpoint/{class-partnersendpoint.php → PartnersEndpoint.php} +0 -0
  21. modules/ppcp-api-client/src/Endpoint/{class-paymenttokenendpoint.php → PaymentTokenEndpoint.php} +0 -0
  22. modules/ppcp-api-client/src/Endpoint/{class-paymentsendpoint.php → PaymentsEndpoint.php} +1 -1
  23. modules/ppcp-api-client/src/Endpoint/{class-requesttrait.php → RequestTrait.php} +12 -5
  24. modules/ppcp-api-client/src/Endpoint/{class-webhookendpoint.php → WebhookEndpoint.php} +0 -0
  25. modules/ppcp-api-client/src/Entity/{class-address.php → Address.php} +0 -0
  26. modules/ppcp-api-client/src/Entity/{class-amount.php → Amount.php} +0 -0
  27. modules/ppcp-api-client/src/Entity/{class-amountbreakdown.php → AmountBreakdown.php} +14 -14
  28. modules/ppcp-api-client/src/Entity/{class-applicationcontext.php → ApplicationContext.php} +0 -0
  29. modules/ppcp-api-client/src/Entity/{class-authorization.php → Authorization.php} +10 -0
  30. modules/ppcp-api-client/src/Entity/{class-authorizationstatus.php → AuthorizationStatus.php} +0 -0
  31. modules/ppcp-api-client/src/Entity/{class-authorizationstatusdetails.php → AuthorizationStatusDetails.php} +0 -0
  32. modules/ppcp-api-client/src/Entity/{class-capture.php → Capture.php} +6 -5
  33. modules/ppcp-api-client/src/Entity/{class-capturestatus.php → CaptureStatus.php} +0 -0
  34. modules/ppcp-api-client/src/Entity/{class-capturestatusdetails.php → CaptureStatusDetails.php} +0 -0
  35. modules/ppcp-api-client/src/Entity/{class-cardauthenticationresult.php → CardAuthenticationResult.php} +0 -0
  36. modules/ppcp-api-client/src/Entity/{class-item.php → Item.php} +0 -0
  37. modules/ppcp-api-client/src/Entity/{class-money.php → Money.php} +0 -0
  38. modules/ppcp-api-client/src/Entity/{class-order.php → Order.php} +0 -0
  39. modules/ppcp-api-client/src/Entity/{class-orderstatus.php → OrderStatus.php} +0 -0
  40. modules/ppcp-api-client/src/Entity/{class-patch.php → Patch.php} +0 -0
  41. modules/ppcp-api-client/src/Entity/{class-patchcollection.php → PatchCollection.php} +0 -0
  42. modules/ppcp-api-client/src/Entity/{class-payee.php → Payee.php} +0 -0
  43. modules/ppcp-api-client/src/Entity/{class-payer.php → Payer.php} +0 -0
  44. modules/ppcp-api-client/src/Entity/{class-payername.php → PayerName.php} +0 -0
  45. modules/ppcp-api-client/src/Entity/{class-payertaxinfo.php → PayerTaxInfo.php} +0 -0
  46. modules/ppcp-api-client/src/Entity/{class-paymentmethod.php → PaymentMethod.php} +0 -0
  47. modules/ppcp-api-client/src/Entity/{class-paymentsource.php → PaymentSource.php} +0 -0
  48. modules/ppcp-api-client/src/Entity/{class-paymentsourcecard.php → PaymentSourceCard.php} +0 -0
  49. modules/ppcp-api-client/src/Entity/{class-paymentsourcewallet.php → PaymentSourceWallet.php} +0 -0
  50. modules/ppcp-api-client/src/Entity/{class-paymenttoken.php → PaymentToken.php} +0 -0
  51. modules/ppcp-api-client/src/Entity/{class-payments.php → Payments.php} +0 -0
  52. modules/ppcp-api-client/src/Entity/{class-phone.php → Phone.php} +0 -0
  53. modules/ppcp-api-client/src/Entity/{class-phonewithtype.php → PhoneWithType.php} +0 -0
  54. modules/ppcp-api-client/src/Entity/{class-purchaseunit.php → PurchaseUnit.php} +59 -35
  55. modules/ppcp-api-client/src/Entity/{class-refund.php → Refund.php} +0 -0
  56. modules/ppcp-api-client/src/Entity/{class-sellerstatus.php → SellerStatus.php} +0 -0
  57. modules/ppcp-api-client/src/Entity/{class-sellerstatusproduct.php → SellerStatusProduct.php} +0 -0
  58. modules/ppcp-api-client/src/Entity/{class-shipping.php → Shipping.php} +0 -0
  59. modules/ppcp-api-client/src/Entity/{class-token.php → Token.php} +0 -0
  60. modules/ppcp-api-client/src/Entity/{class-webhook.php → Webhook.php} +3 -3
  61. modules/ppcp-api-client/src/Entity/{class-webhookevent.php → WebhookEvent.php} +0 -0
  62. modules/ppcp-api-client/src/Exception/{class-notfoundexception.php → NotFoundException.php} +0 -0
  63. modules/ppcp-api-client/src/Exception/{class-paypalapiexception.php → PayPalApiException.php} +0 -0
  64. modules/ppcp-api-client/src/Exception/{class-runtimeexception.php → RuntimeException.php} +0 -0
  65. modules/ppcp-api-client/src/Factory/{class-addressfactory.php → AddressFactory.php} +0 -0
  66. modules/ppcp-api-client/src/Factory/{class-amountfactory.php → AmountFactory.php} +0 -0
  67. modules/ppcp-api-client/src/Factory/{class-applicationcontextfactory.php → ApplicationContextFactory.php} +0 -0
  68. modules/ppcp-api-client/src/Factory/{class-authorizationfactory.php → AuthorizationFactory.php} +0 -0
  69. modules/ppcp-api-client/src/Factory/{class-capturefactory.php → CaptureFactory.php} +1 -1
  70. modules/ppcp-api-client/src/Factory/{class-itemfactory.php → ItemFactory.php} +0 -0
  71. modules/ppcp-api-client/src/Factory/{class-orderfactory.php → OrderFactory.php} +0 -0
  72. modules/ppcp-api-client/src/Factory/{class-patchcollectionfactory.php → PatchCollectionFactory.php} +1 -3
  73. modules/ppcp-api-client/src/Factory/{class-payeefactory.php → PayeeFactory.php} +0 -0
  74. modules/ppcp-api-client/src/Factory/{class-payerfactory.php → PayerFactory.php} +0 -0
  75. modules/ppcp-api-client/src/Factory/{class-paymentsourcefactory.php → PaymentSourceFactory.php} +0 -0
  76. modules/ppcp-api-client/src/Factory/{class-paymenttokenfactory.php → PaymentTokenFactory.php} +0 -0
  77. modules/ppcp-api-client/src/Factory/{class-paymentsfactory.php → PaymentsFactory.php} +1 -1
  78. modules/ppcp-api-client/src/Factory/{class-purchaseunitfactory.php → PurchaseUnitFactory.php} +4 -2
  79. modules/ppcp-api-client/src/Factory/{class-sellerstatusfactory.php → SellerStatusFactory.php} +0 -0
  80. modules/ppcp-api-client/src/Factory/{class-shippingfactory.php → ShippingFactory.php} +0 -0
  81. modules/ppcp-api-client/src/Factory/{class-webhookeventfactory.php → WebhookEventFactory.php} +0 -0
  82. modules/ppcp-api-client/src/Factory/{class-webhookfactory.php → WebhookFactory.php} +7 -6
  83. modules/ppcp-api-client/src/Helper/{class-cache.php → Cache.php} +0 -0
  84. modules/ppcp-api-client/src/Helper/{class-dccapplies.php → DccApplies.php} +0 -0
  85. modules/ppcp-api-client/src/Helper/{class-errorresponse.php → ErrorResponse.php} +0 -0
  86. modules/ppcp-api-client/src/Repository/{class-applicationcontextrepository.php → ApplicationContextRepository.php} +0 -0
  87. modules/ppcp-api-client/src/Repository/{class-cartrepository.php → CartRepository.php} +0 -0
  88. modules/ppcp-api-client/src/Repository/{class-partnerreferralsdata.php → PartnerReferralsData.php} +0 -0
  89. modules/ppcp-api-client/src/Repository/{class-paypalrequestidrepository.php → PayPalRequestIdRepository.php} +0 -0
  90. modules/ppcp-api-client/src/Repository/{class-payeerepository.php → PayeeRepository.php} +0 -0
  91. modules/ppcp-api-client/src/Repository/{class-purchaseunitrepositoryinterface.php → PurchaseUnitRepositoryInterface.php} +0 -0
  92. modules/ppcp-button/assets/js/button.js +1 -1
  93. modules/ppcp-button/composer.json +17 -0
  94. modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js +4 -1
  95. modules/ppcp-button/services.php +26 -12
  96. modules/ppcp-button/src/Assets/{class-disabledsmartbutton.php → DisabledSmartButton.php} +0 -0
  97. modules/ppcp-button/src/Assets/{class-smartbutton.php → SmartButton.php} +17 -10
  98. modules/ppcp-button/src/Assets/{class-smartbuttoninterface.php → SmartButtonInterface.php} +0 -0
  99. modules/ppcp-button/src/{class-buttonmodule.php → ButtonModule.php} +10 -14
  100. modules/ppcp-button/src/Endpoint/{class-approveorderendpoint.php → ApproveOrderEndpoint.php} +1 -10
  101. modules/ppcp-button/src/Endpoint/{class-changecartendpoint.php → ChangeCartEndpoint.php} +0 -0
  102. modules/ppcp-button/src/Endpoint/{class-createorderendpoint.php → CreateOrderEndpoint.php} +28 -87
  103. modules/ppcp-button/src/Endpoint/{class-dataclientidendpoint.php → DataClientIdEndpoint.php} +0 -0
  104. modules/ppcp-button/src/Endpoint/{class-endpointinterface.php → EndpointInterface.php} +0 -0
  105. modules/ppcp-button/src/Endpoint/{class-requestdata.php → RequestData.php} +0 -0
  106. modules/ppcp-button/src/Exception/{class-runtimeexception.php → RuntimeException.php} +0 -0
  107. modules/ppcp-button/src/Helper/{class-earlyorderhandler.php → EarlyOrderHandler.php} +0 -0
  108. modules/ppcp-button/src/Helper/{class-messagesapply.php → MessagesApply.php} +0 -0
  109. modules/ppcp-button/src/Helper/{class-messagesdisclaimers.php → MessagesDisclaimers.php} +0 -0
  110. modules/ppcp-button/src/Helper/{class-threedsecure.php → ThreeDSecure.php} +0 -0
  111. modules/ppcp-compat/composer.json +17 -0
  112. modules/ppcp-compat/services.php +3 -1
  113. modules/ppcp-compat/src/{class-compatmodule.php → CompatModule.php} +3 -3
  114. modules/ppcp-compat/src/PPEC/{class-deactivatenote.php → DeactivateNote.php} +0 -0
  115. modules/ppcp-compat/src/PPEC/{class-mockgateway.php → MockGateway.php} +0 -0
  116. modules/ppcp-compat/src/PPEC/{class-ppechelper.php → PPECHelper.php} +6 -1
  117. modules/ppcp-compat/src/PPEC/{class-settingsimporter.php → SettingsImporter.php} +0 -0
  118. modules/ppcp-compat/src/PPEC/{class-subscriptionshandler.php → SubscriptionsHandler.php} +0 -0
  119. modules/ppcp-onboarding/composer.json +17 -0
  120. modules/ppcp-onboarding/services.php +23 -22
  121. modules/ppcp-onboarding/src/Assets/{class-onboardingassets.php → OnboardingAssets.php} +0 -0
  122. modules/ppcp-onboarding/src/Endpoint/{class-loginsellerendpoint.php → LoginSellerEndpoint.php} +0 -0
  123. modules/ppcp-onboarding/src/{class-environment.php → Environment.php} +0 -0
  124. modules/ppcp-onboarding/src/{class-onboardingmodule.php → OnboardingModule.php} +9 -13
  125. modules/ppcp-onboarding/src/{class-onboarding-rest-controller.php → OnboardingRESTController.php} +1 -1
  126. modules/ppcp-onboarding/src/Render/{class-onboardingrenderer.php → OnboardingRenderer.php} +0 -0
  127. modules/ppcp-onboarding/src/{class-state.php → State.php} +0 -0
  128. modules/ppcp-session/composer.json +17 -0
  129. modules/ppcp-session/services.php +4 -4
  130. modules/ppcp-session/src/Cancellation/{class-cancelcontroller.php → CancelController.php} +0 -0
  131. modules/ppcp-session/src/Cancellation/{class-cancelview.php → CancelView.php} +0 -0
  132. modules/ppcp-session/src/{class-sessionhandler.php → SessionHandler.php} +0 -0
  133. modules/ppcp-session/src/{class-sessionmodule.php → SessionModule.php} +5 -9
  134. modules/ppcp-status-report/composer.json +17 -0
  135. modules/ppcp-status-report/services.php +1 -1
  136. modules/ppcp-status-report/src/{class-renderer.php → Renderer.php} +0 -0
  137. modules/ppcp-status-report/src/{class-statusreportmodule.php → StatusReportModule.php} +8 -8
  138. modules/ppcp-subscription/composer.json +17 -0
  139. modules/ppcp-subscription/services.php +9 -2
  140. modules/ppcp-subscription/src/Helper/{class-subscriptionhelper.php → SubscriptionHelper.php} +1 -1
  141. modules/ppcp-subscription/src/{class-renewalhandler.php → RenewalHandler.php} +2 -1
  142. modules/ppcp-subscription/src/{class-subscriptionmodule.php → SubscriptionModule.php} +19 -23
  143. modules/ppcp-vaulting/composer.json +17 -0
  144. modules/ppcp-vaulting/services.php +5 -4
  145. modules/ppcp-vaulting/src/Assets/{class-myaccountpaymentsassets.php → MyAccountPaymentsAssets.php} +1 -1
  146. modules/ppcp-vaulting/src/Endpoint/{class-deletepaymenttokenendpoint.php → DeletePaymentTokenEndpoint.php} +0 -0
  147. modules/ppcp-vaulting/src/{class-paymenttokenrepository.php → PaymentTokenRepository.php} +0 -0
  148. modules/ppcp-vaulting/src/{class-paymenttokensrenderer.php → PaymentTokensRenderer.php} +0 -0
  149. modules/ppcp-vaulting/src/{class-vaultingmodule.php → VaultingModule.php} +21 -0
  150. modules/ppcp-wc-gateway/composer.json +17 -0
  151. modules/ppcp-wc-gateway/extensions.php +10 -8
  152. modules/ppcp-wc-gateway/module.php +1 -1
  153. modules/ppcp-wc-gateway/services.php +53 -45
  154. modules/ppcp-wc-gateway/src/Admin/{class-ordertablepaymentstatuscolumn.php → OrderTablePaymentStatusColumn.php} +3 -2
  155. modules/ppcp-wc-gateway/src/Admin/{class-paymentstatusorderdetail.php → PaymentStatusOrderDetail.php} +0 -0
  156. modules/ppcp-wc-gateway/src/Admin/{class-renderauthorizeaction.php → RenderAuthorizeAction.php} +21 -2
  157. modules/ppcp-wc-gateway/src/Assets/{class-settingspageassets.php → SettingsPageAssets.php} +0 -0
  158. modules/ppcp-wc-gateway/src/Checkout/{class-checkoutpaypaladdresspreset.php → CheckoutPayPalAddressPreset.php} +0 -1
  159. modules/ppcp-wc-gateway/src/Checkout/{class-disablegateways.php → DisableGateways.php} +18 -4
  160. modules/ppcp-wc-gateway/src/Endpoint/{class-returnurlendpoint.php → ReturnUrlEndpoint.php} +0 -3
  161. modules/ppcp-wc-gateway/src/Exception/{class-notfoundexception.php → NotFoundException.php} +0 -0
  162. modules/ppcp-wc-gateway/src/Gateway/{class-creditcardgateway.php → CreditCardGateway.php} +72 -22
  163. modules/ppcp-wc-gateway/src/Gateway/{class-paypalgateway.php → PayPalGateway.php} +85 -102
  164. modules/ppcp-wc-gateway/src/Gateway/{class-processpaymenttrait.php → ProcessPaymentTrait.php} +111 -2
  165. modules/ppcp-wc-gateway/src/Gateway/{class-transactionurlprovider.php → TransactionUrlProvider.php} +0 -0
  166. modules/ppcp-wc-gateway/src/Helper/{class-dccproductstatus.php → DCCProductStatus.php} +3 -3
  167. modules/ppcp-wc-gateway/src/Helper/{class-settingsstatus.php → SettingsStatus.php} +2 -2
  168. modules/ppcp-wc-gateway/src/Notice/{class-authorizeorderactionnotice.php → AuthorizeOrderActionNotice.php} +0 -0
  169. modules/ppcp-wc-gateway/src/Notice/{class-connectadminnotice.php → ConnectAdminNotice.php} +0 -0
  170. modules/ppcp-wc-gateway/src/Notice/{class-dccwithoutpaypaladminnotice.php → DccWithoutPayPalAdminNotice.php} +0 -0
  171. modules/ppcp-wc-gateway/src/Processor/{class-authorizedpaymentsprocessor.php → AuthorizedPaymentsProcessor.php} +86 -5
  172. modules/ppcp-wc-gateway/src/Processor/{class-ordermetatrait.php → OrderMetaTrait.php} +0 -0
  173. modules/ppcp-wc-gateway/src/Processor/{class-orderprocessor.php → OrderProcessor.php} +5 -56
  174. modules/ppcp-wc-gateway/src/Processor/{class-paymentstatushandlingtrait.php → PaymentsStatusHandlingTrait.php} +7 -5
  175. modules/ppcp-wc-gateway/src/Processor/{class-refundprocessor.php → RefundProcessor.php} +4 -13
  176. modules/ppcp-wc-gateway/src/Processor/TransactionIdHandlingTrait.php +85 -0
  177. modules/ppcp-wc-gateway/src/Settings/{class-pagematchertrait.php → PageMatcherTrait.php} +0 -7
  178. modules/ppcp-wc-gateway/src/Settings/{class-sectionsrenderer.php → SectionsRenderer.php} +0 -0
  179. modules/ppcp-wc-gateway/src/Settings/{class-settings.php → Settings.php} +0 -0
  180. modules/ppcp-wc-gateway/src/Settings/{class-settingslistener.php → SettingsListener.php} +0 -0
  181. modules/ppcp-wc-gateway/src/Settings/{class-settingsrenderer.php → SettingsRenderer.php} +5 -5
  182. modules/ppcp-wc-gateway/src/{class-wcgatewaymodule.php → WCGatewayModule.php} +30 -32
  183. modules/ppcp-webhooks/composer.json +17 -0
  184. modules/ppcp-webhooks/services.php +15 -15
  185. modules/ppcp-webhooks/src/Endpoint/{class-resubscribeendpoint.php → ResubscribeEndpoint.php} +0 -0
  186. modules/ppcp-webhooks/src/Endpoint/{class-simulateendpoint.php → SimulateEndpoint.php} +0 -0
  187. modules/ppcp-webhooks/src/Endpoint/{class-simulationstateendpoint.php → SimulationStateEndpoint.php} +0 -0
  188. modules/ppcp-webhooks/src/Handler/{class-checkoutorderapproved.php → CheckoutOrderApproved.php} +1 -1
  189. modules/ppcp-webhooks/src/Handler/{class-checkoutordercompleted.php → CheckoutOrderCompleted.php} +1 -1
  190. modules/ppcp-webhooks/src/Handler/PaymentCaptureCompleted.php +160 -0
  191. modules/ppcp-webhooks/src/Handler/{class-paymentcapturerefunded.php → PaymentCaptureRefunded.php} +1 -1
  192. modules/ppcp-webhooks/src/Handler/{class-paymentcapturereversed.php → PaymentCaptureReversed.php} +1 -1
  193. modules/ppcp-webhooks/src/Handler/{class-prefixtrait.php → PrefixTrait.php} +0 -0
  194. modules/ppcp-webhooks/src/Handler/{class-requesthandler.php → RequestHandler.php} +1 -1
  195. modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php +0 -141
  196. modules/ppcp-webhooks/src/{class-incomingwebhookendpoint.php → IncomingWebhookEndpoint.php} +14 -2
  197. modules/ppcp-webhooks/src/Status/Assets/{class-webhooksstatuspageassets.php → WebhooksStatusPageAssets.php} +3 -5
  198. modules/ppcp-webhooks/src/Status/{class-webhooksimulation.php → WebhookSimulation.php} +1 -1
  199. modules/ppcp-webhooks/src/Status/{class-webhooksstatuspage.php → WebhooksStatusPage.php} +0 -0
  200. modules/ppcp-webhooks/src/{class-webhookmodule.php → WebhookModule.php} +3 -7
  201. modules/ppcp-webhooks/src/{class-webhookregistrar.php → WebhookRegistrar.php} +0 -0
  202. modules/woocommerce-logging/composer.json +17 -0
  203. modules/woocommerce-logging/src/Logger/{class-nulllogger.php → NullLogger.php} +0 -0
  204. modules/woocommerce-logging/src/Logger/{class-woocommercelogger.php → WooCommerceLogger.php} +0 -0
  205. modules/woocommerce-logging/src/{class-woocommerceloggingmodule.php → WooCommerceLoggingModule.php} +3 -7
  206. psalm-baseline.xml +921 -0
  207. psalm.xml.dist +154 -0
  208. readme.txt +18 -1
  209. src/{class-pluginmodule.php → PluginModule.php} +3 -5
  210. vendor/autoload.php +1 -1
  211. vendor/composer/ClassLoader.php +14 -141
  212. vendor/composer/InstalledVersions.php +0 -337
  213. vendor/composer/autoload_classmap.php +0 -177
  214. vendor/composer/autoload_psr4.php +14 -5
  215. vendor/composer/autoload_real.php +9 -11
  216. vendor/composer/autoload_static.php +74 -207
  217. vendor/composer/installed.json +407 -660
  218. vendor/composer/installed.php +0 -131
  219. vendor/composer/platform_check.php +0 -26
  220. vendor/dhii/collections-interface/CHANGELOG.md +3 -0
  221. vendor/dhii/collections-interface/composer.json +1 -1
  222. vendor/dhii/collections-interface/psalm.xml.dist +0 -1
  223. vendor/dhii/containers/.editorconfig +16 -0
  224. vendor/dhii/containers/.env.example +7 -1
  225. vendor/dhii/containers/CHANGELOG.md +34 -1
  226. vendor/dhii/containers/README.md +143 -6
  227. vendor/dhii/containers/composer.json +12 -8
  228. vendor/dhii/containers/docker-compose.yml +28 -6
  229. vendor/dhii/containers/docker/Dockerfile +39 -0
  230. vendor/dhii/containers/docker/Dockerfile_php +0 -6
  231. vendor/dhii/containers/phpcs.xml.dist +39 -33
  232. vendor/dhii/containers/phpmd.xml +0 -24
  233. vendor/dhii/containers/phpunit.xml.dist +26 -0
  234. vendor/dhii/containers/psalm.xml.dist +152 -0
  235. vendor/dhii/containers/src/AliasingContainer.php +7 -4
  236. vendor/dhii/containers/src/CachingContainer.php +37 -24
  237. vendor/dhii/containers/src/CompositeCachingServiceProvider.php +35 -18
  238. vendor/dhii/containers/src/CompositeContainer.php +17 -8
  239. vendor/dhii/containers/src/DataStructureBasedFactory.php +9 -7
  240. vendor/dhii/containers/src/DataStructureBasedFactoryInterface.php +3 -2
  241. vendor/dhii/containers/src/DelegatingContainer.php +11 -9
  242. vendor/dhii/containers/src/DeprefixingContainer.php +8 -1
  243. vendor/dhii/containers/src/Dictionary.php +27 -3
  244. vendor/dhii/containers/src/DictionaryFactory.php +2 -1
  245. vendor/dhii/containers/src/Exception/ContainerException.php +7 -8
  246. vendor/dhii/containers/src/Exception/NotFoundException.php +7 -5
  247. vendor/dhii/containers/src/FlashContainer.php +135 -0
  248. vendor/dhii/containers/src/HierarchyContainer.php +11 -5
  249. vendor/dhii/containers/src/MappingContainer.php +7 -5
  250. vendor/dhii/containers/src/MaskingContainer.php +6 -5
  251. vendor/dhii/containers/src/NoOpContainer.php +99 -0
  252. vendor/dhii/containers/src/PathContainer.php +22 -4
  253. vendor/dhii/containers/src/PrefixingContainer.php +10 -3
  254. vendor/dhii/containers/src/ProxyContainer.php +4 -2
  255. vendor/dhii/containers/src/SegmentingContainer.php +4 -1
  256. vendor/dhii/containers/src/ServiceProvider.php +3 -1
  257. vendor/dhii/containers/src/SimpleCacheContainer.php +111 -0
  258. vendor/dhii/containers/src/Util/StringTranslatingTrait.php +14 -9
  259. vendor/dhii/containers/tests/bootstrap.php +5 -0
  260. vendor/dhii/containers/tests/functional/AliasingContainerTest.php +148 -0
  261. vendor/dhii/containers/tests/functional/CachingContainerTest.php +93 -0
  262. vendor/dhii/containers/tests/functional/CompositeCachingServiceProviderTest.php +108 -0
  263. vendor/dhii/containers/tests/functional/CompositeContainerTest.php +112 -0
  264. vendor/dhii/containers/tests/functional/DataStructureBasedFactoryTest.php +80 -0
  265. vendor/dhii/containers/tests/functional/DelegatingContainerTest.php +90 -0
  266. vendor/dhii/containers/tests/functional/DeprefixingContainerTest.php +167 -0
  267. vendor/dhii/containers/tests/functional/DictionaryTest.php +125 -0
  268. vendor/dhii/containers/tests/functional/Exception/ContainerExceptionTest.php +60 -0
  269. vendor/dhii/containers/tests/functional/Exception/NotFoundExceptionTest.php +59 -0
  270. vendor/dhii/containers/tests/functional/FlashContainerTest.php +124 -0
  271. vendor/dhii/containers/tests/functional/HierarchyContainerTest.php +158 -0
  272. vendor/dhii/containers/tests/functional/MappingContainerTest.php +125 -0
  273. vendor/dhii/containers/tests/functional/MaskingContainerTest.php +187 -0
  274. vendor/dhii/containers/tests/functional/NoOpContainerTest.php +60 -0
  275. vendor/dhii/containers/tests/functional/PathContainerTest.php +159 -0
  276. vendor/dhii/containers/tests/functional/PrefixingContainerTest.php +335 -0
  277. vendor/dhii/containers/tests/functional/SegmentingContainerTest.php +162 -0
  278. vendor/dhii/containers/tests/functional/ServiceProviderTest.php +56 -0
  279. vendor/dhii/containers/tests/functional/SimpleCacheContainerTest.php +101 -0
  280. vendor/dhii/containers/tests/helpers/AbstractMockHelper.php +70 -0
  281. vendor/dhii/containers/tests/helpers/ComponentMockeryTrait.php +258 -0
  282. vendor/dhii/containers/tests/helpers/ContainerMock.php +156 -0
  283. vendor/dhii/containers/tests/helpers/InvocableMock.php +99 -0
  284. vendor/dhii/containers/tests/helpers/ServiceProviderMock.php +69 -0
  285. vendor/dhii/containers/tests/system/MultipleAccessTypesWithMapsTest.php +93 -0
  286. vendor/dhii/containers/tests/unit/CompositeCachingServiceProviderTest.php +100 -0
  287. vendor/dhii/containers/tests/unit/ProxyContainerTest.php +84 -0
  288. vendor/dhii/data-container-interface/CHANGELOG.md +0 -38
  289. vendor/dhii/data-container-interface/LICENSE +0 -19
  290. vendor/dhii/data-container-interface/README.md +0 -79
  291. vendor/dhii/data-container-interface/composer.json +0 -50
  292. vendor/dhii/data-container-interface/src/ClearCapableContainerInterface.php +0 -16
  293. vendor/dhii/data-container-interface/src/ClearCapableInterface.php +0 -22
  294. vendor/dhii/data-container-interface/src/ContainerAwareInterface.php +0 -22
  295. vendor/dhii/data-container-interface/src/ContainerFactoryInterface.php +0 -38
  296. vendor/dhii/data-container-interface/src/ContainerInterface.php +0 -30
  297. vendor/dhii/data-container-interface/src/DataKeyAwareInterface.php +0 -22
  298. vendor/dhii/data-container-interface/src/DeleteCapableContainerInterface.php +0 -28
  299. vendor/dhii/data-container-interface/src/DeleteCapableInterface.php +0 -25
  300. vendor/dhii/data-container-interface/src/Exception/ContainerExceptionInterface.php +0 -19
  301. vendor/dhii/data-container-interface/src/Exception/NotFoundExceptionInterface.php +0 -18
  302. vendor/dhii/data-container-interface/src/HasCapableInterface.php +0 -27
  303. vendor/dhii/data-container-interface/src/SetCapableContainerInterface.php +0 -14
  304. vendor/dhii/data-container-interface/src/SetCapableInterface.php +0 -26
  305. vendor/dhii/data-container-interface/src/WritableContainerInterface.php +0 -14
  306. vendor/dhii/exception-interface/CHANGELOG.md +0 -27
  307. vendor/dhii/exception-interface/LICENSE +0 -19
  308. vendor/dhii/exception-interface/README.md +0 -46
  309. vendor/dhii/exception-interface/composer.json +0 -44
  310. vendor/dhii/exception-interface/phpmd.xml +0 -25
  311. vendor/dhii/exception-interface/src/ArgumentCodeAwareInterface.php +0 -24
  312. vendor/dhii/exception-interface/src/BadSubjectExceptionInterface.php +0 -20
  313. vendor/dhii/exception-interface/src/InternalExceptionInterface.php +0 -27
  314. vendor/dhii/exception-interface/src/InvalidArgumentExceptionInterface.php +0 -12
  315. vendor/dhii/exception-interface/src/OutOfBoundsExceptionInterface.php +0 -12
  316. vendor/dhii/exception-interface/src/OutOfRangeExceptionInterface.php +0 -12
  317. vendor/dhii/exception-interface/src/RuntimeExceptionInterface.php +0 -12
  318. vendor/dhii/exception-interface/src/ThrowableInterface.php +0 -89
  319. vendor/dhii/factory-interface/CHANGELOG.md +0 -19
  320. vendor/dhii/factory-interface/LICENSE +0 -21
  321. vendor/dhii/factory-interface/README.md +0 -22
  322. vendor/dhii/factory-interface/composer.json +0 -46
  323. vendor/dhii/factory-interface/phpmd.xml +0 -25
  324. vendor/dhii/factory-interface/src/DataObjectFactoryInterface.php +0 -20
  325. vendor/dhii/factory-interface/src/Exception/CouldNotMakeExceptionInterface.php +0 -23
  326. vendor/dhii/factory-interface/src/Exception/FactoryExceptionInterface.php +0 -17
  327. vendor/dhii/factory-interface/src/FactoryAwareInterface.php +0 -20
  328. vendor/dhii/factory-interface/src/FactoryFactoryInterface.php +0 -20
  329. vendor/dhii/factory-interface/src/FactoryInterface.php +0 -32
  330. vendor/dhii/stringable-interface/.php_cs +0 -23
  331. vendor/dhii/stringable-interface/CHANGELOG.md +0 -12
  332. vendor/dhii/stringable-interface/README.md +0 -7
  333. vendor/dhii/stringable-interface/composer.json +0 -27
  334. vendor/dhii/stringable-interface/composer.lock +0 -1385
changelog.txt CHANGED
@@ -1,5 +1,22 @@
1
  *** Changelog ***
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  = 1.6.1 - 2021-10-12 =
4
  * Fix - Handle authorization capture failures #312
5
  * Fix - Handle denied payment authorization #302
1
  *** Changelog ***
2
 
3
+ = 1.6.2 - 2021-11-22 =
4
+ * Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
5
+ * Fix - Can't checkout to certain countries with optional postcode #330
6
+ * Fix - Prevent subscription from being purchased when saving payment fails #308
7
+ * Fix - Guest users must checkout twice for subscriptions, no smart buttons loaded #342
8
+ * Fix - Failed PayPal API request causing strange error #347
9
+ * Fix - PayPal payments page empty after switching packages #350
10
+ * Fix - Could Not Validate Nonce Error #239
11
+ * Fix - Refund via PayPal dashboard does not set the WooCommerce order to "Refunded" #241
12
+ * Fix - Uncaught TypeError: round() #344
13
+ * Fix - Broken multi-level (nested) associative array values after getting submitted from checkout page #307
14
+ * Fix - Transaction id missing in some cases #328
15
+ * Fix - Payment not possible in pay for order form because of terms checkbox missing #294
16
+ * Fix - "Save your Credit Card" shouldn't be optional when paying for a subscription #368
17
+ * Fix - When paying for a subscription and vaulting fails, cart is cleared #367
18
+ * Fix - Fatal error when activating PayPal Checkout plugin #363
19
+
20
  = 1.6.1 - 2021-10-12 =
21
  * Fix - Handle authorization capture failures #312
22
  * Fix - Handle denied payment authorization #302
modules/ppcp-admin-notices/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-admin-notices",
3
+ "type": "dhii-mod",
4
+ "description": "Admin notices module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\AdminNotices\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-admin-notices/services.php CHANGED
@@ -9,19 +9,19 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\AdminNotices;
11
 
12
- use Dhii\Data\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\AdminNotices\Renderer\Renderer;
14
  use WooCommerce\PayPalCommerce\AdminNotices\Renderer\RendererInterface;
15
  use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
16
  use WooCommerce\PayPalCommerce\AdminNotices\Repository\RepositoryInterface;
17
 
18
  return array(
19
- 'admin-notices.renderer' => static function ( $container ): RendererInterface {
20
 
21
  $repository = $container->get( 'admin-notices.repository' );
22
  return new Renderer( $repository );
23
  },
24
- 'admin-notices.repository' => static function ( $container ): RepositoryInterface {
25
 
26
  return new Repository();
27
  },
9
 
10
  namespace WooCommerce\PayPalCommerce\AdminNotices;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\AdminNotices\Renderer\Renderer;
14
  use WooCommerce\PayPalCommerce\AdminNotices\Renderer\RendererInterface;
15
  use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
16
  use WooCommerce\PayPalCommerce\AdminNotices\Repository\RepositoryInterface;
17
 
18
  return array(
19
+ 'admin-notices.renderer' => static function ( ContainerInterface $container ): RendererInterface {
20
 
21
  $repository = $container->get( 'admin-notices.repository' );
22
  return new Renderer( $repository );
23
  },
24
+ 'admin-notices.repository' => static function ( ContainerInterface $container ): RepositoryInterface {
25
 
26
  return new Repository();
27
  },
modules/ppcp-admin-notices/src/{class-adminnotices.php → AdminNotices.php} RENAMED
@@ -20,9 +20,7 @@ use Psr\Container\ContainerInterface;
20
  class AdminNotices implements ModuleInterface {
21
 
22
  /**
23
- * Sets up the module.
24
- *
25
- * @return ServiceProviderInterface
26
  */
27
  public function setup(): ServiceProviderInterface {
28
  return new ServiceProvider(
@@ -32,15 +30,13 @@ class AdminNotices implements ModuleInterface {
32
  }
33
 
34
  /**
35
- * Runs the module.
36
- *
37
- * @param ContainerInterface $container The container.
38
  */
39
- public function run( ContainerInterface $container ): void {
40
  add_action(
41
  'admin_notices',
42
- function() use ( $container ) {
43
- $renderer = $container->get( 'admin-notices.renderer' );
44
  $renderer->render();
45
  }
46
  );
20
  class AdminNotices implements ModuleInterface {
21
 
22
  /**
23
+ * {@inheritDoc}
 
 
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider(
30
  }
31
 
32
  /**
33
+ * {@inheritDoc}
 
 
34
  */
35
+ public function run( ContainerInterface $c ): void {
36
  add_action(
37
  'admin_notices',
38
+ function() use ( $c ) {
39
+ $renderer = $c->get( 'admin-notices.renderer' );
40
  $renderer->render();
41
  }
42
  );
modules/ppcp-admin-notices/src/Entity/{class-message.php → Message.php} RENAMED
File without changes
modules/ppcp-admin-notices/src/Renderer/{class-renderer.php → Renderer.php} RENAMED
File without changes
modules/ppcp-admin-notices/src/Renderer/{class-rendererinterface.php → RendererInterface.php} RENAMED
File without changes
modules/ppcp-admin-notices/src/Repository/{class-repository.php → Repository.php} RENAMED
File without changes
modules/ppcp-admin-notices/src/Repository/{class-repositoryinterface.php → RepositoryInterface.php} RENAMED
File without changes
modules/ppcp-api-client/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-api-client",
3
+ "type": "dhii-mod",
4
+ "description": "API client module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\ApiClient\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-api-client/services.php CHANGED
@@ -9,6 +9,7 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient;
11
 
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
14
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
@@ -47,10 +48,10 @@ use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
47
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
48
 
49
  return array(
50
- 'api.host' => function( $container ) : string {
51
  return PAYPAL_API_URL;
52
  },
53
- 'api.paypal-host' => function( $container ) : string {
54
  return PAYPAL_API_URL;
55
  },
56
  'api.partner_merchant_id' => static function () : string {
@@ -71,7 +72,7 @@ return array(
71
  'api.prefix' => static function (): string {
72
  return 'WC-';
73
  },
74
- 'api.bearer' => static function ( $container ): Bearer {
75
  $cache = new Cache( 'ppcp-paypal-bearer' );
76
  $key = $container->get( 'api.key' );
77
  $secret = $container->get( 'api.secret' );
@@ -87,7 +88,7 @@ return array(
87
  $settings
88
  );
89
  },
90
- 'api.endpoint.partners' => static function ( $container ) : PartnersEndpoint {
91
  return new PartnersEndpoint(
92
  $container->get( 'api.host' ),
93
  $container->get( 'api.bearer' ),
@@ -97,10 +98,10 @@ return array(
97
  $container->get( 'api.merchant_id' )
98
  );
99
  },
100
- 'api.factory.sellerstatus' => static function ( $container ) : SellerStatusFactory {
101
  return new SellerStatusFactory();
102
  },
103
- 'api.endpoint.payment-token' => static function ( $container ) : PaymentTokenEndpoint {
104
  return new PaymentTokenEndpoint(
105
  $container->get( 'api.host' ),
106
  $container->get( 'api.bearer' ),
@@ -109,7 +110,7 @@ return array(
109
  $container->get( 'api.prefix' )
110
  );
111
  },
112
- 'api.endpoint.webhook' => static function ( $container ) : WebhookEndpoint {
113
 
114
  return new WebhookEndpoint(
115
  $container->get( 'api.host' ),
@@ -119,7 +120,7 @@ return array(
119
  $container->get( 'woocommerce.logger.woocommerce' )
120
  );
121
  },
122
- 'api.endpoint.partner-referrals' => static function ( $container ) : PartnerReferrals {
123
 
124
  return new PartnerReferrals(
125
  $container->get( 'api.host' ),
@@ -128,7 +129,7 @@ return array(
128
  $container->get( 'woocommerce.logger.woocommerce' )
129
  );
130
  },
131
- 'api.endpoint.identity-token' => static function ( $container ) : IdentityToken {
132
 
133
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
134
  $prefix = $container->get( 'api.prefix' );
@@ -139,7 +140,7 @@ return array(
139
  $prefix
140
  );
141
  },
142
- 'api.endpoint.payments' => static function ( $container ): PaymentsEndpoint {
143
  $authorizations_factory = $container->get( 'api.factory.authorization' );
144
  $capture_factory = $container->get( 'api.factory.capture' );
145
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
@@ -152,7 +153,7 @@ return array(
152
  $logger
153
  );
154
  },
155
- 'api.endpoint.login-seller' => static function ( $container ) : LoginSeller {
156
 
157
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
158
  return new LoginSeller(
@@ -161,7 +162,7 @@ return array(
161
  $logger
162
  );
163
  },
164
- 'api.endpoint.order' => static function ( $container ): OrderEndpoint {
165
  $order_factory = $container->get( 'api.factory.order' );
166
  $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
167
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
@@ -175,6 +176,7 @@ return array(
175
  $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
176
  $application_context_repository = $container->get( 'api.repository.application-context' );
177
  $paypal_request_id = $container->get( 'api.repository.paypal-request-id' );
 
178
  return new OrderEndpoint(
179
  $container->get( 'api.host' ),
180
  $container->get( 'api.bearer' ),
@@ -183,50 +185,51 @@ return array(
183
  $intent,
184
  $logger,
185
  $application_context_repository,
186
- $paypal_request_id
 
187
  );
188
  },
189
- 'api.repository.paypal-request-id' => static function( $container ) : PayPalRequestIdRepository {
190
  return new PayPalRequestIdRepository();
191
  },
192
- 'api.repository.application-context' => static function( $container ) : ApplicationContextRepository {
193
 
194
  $settings = $container->get( 'wcgateway.settings' );
195
  return new ApplicationContextRepository( $settings );
196
  },
197
- 'api.repository.partner-referrals-data' => static function ( $container ) : PartnerReferralsData {
198
 
199
  $merchant_email = $container->get( 'api.merchant_email' );
200
  $dcc_applies = $container->get( 'api.helpers.dccapplies' );
201
  return new PartnerReferralsData( $merchant_email, $dcc_applies );
202
  },
203
- 'api.repository.cart' => static function ( $container ): CartRepository {
204
  $factory = $container->get( 'api.factory.purchase-unit' );
205
  return new CartRepository( $factory );
206
  },
207
- 'api.repository.payee' => static function ( $container ): PayeeRepository {
208
  $merchant_email = $container->get( 'api.merchant_email' );
209
  $merchant_id = $container->get( 'api.merchant_id' );
210
  return new PayeeRepository( $merchant_email, $merchant_id );
211
  },
212
- 'api.factory.application-context' => static function ( $container ) : ApplicationContextFactory {
213
  return new ApplicationContextFactory();
214
  },
215
- 'api.factory.payment-token' => static function ( $container ) : PaymentTokenFactory {
216
  return new PaymentTokenFactory();
217
  },
218
- 'api.factory.webhook' => static function ( $container ): WebhookFactory {
219
  return new WebhookFactory();
220
  },
221
- 'api.factory.webhook-event' => static function ( $container ): WebhookEventFactory {
222
  return new WebhookEventFactory();
223
  },
224
- 'api.factory.capture' => static function ( $container ): CaptureFactory {
225
 
226
  $amount_factory = $container->get( 'api.factory.amount' );
227
  return new CaptureFactory( $amount_factory );
228
  },
229
- 'api.factory.purchase-unit' => static function ( $container ): PurchaseUnitFactory {
230
 
231
  $amount_factory = $container->get( 'api.factory.amount' );
232
  $payee_repository = $container->get( 'api.repository.payee' );
@@ -246,34 +249,34 @@ return array(
246
  $prefix
247
  );
248
  },
249
- 'api.factory.patch-collection-factory' => static function ( $container ): PatchCollectionFactory {
250
  return new PatchCollectionFactory();
251
  },
252
- 'api.factory.payee' => static function ( $container ): PayeeFactory {
253
  return new PayeeFactory();
254
  },
255
- 'api.factory.item' => static function ( $container ): ItemFactory {
256
  return new ItemFactory();
257
  },
258
- 'api.factory.shipping' => static function ( $container ): ShippingFactory {
259
  $address_factory = $container->get( 'api.factory.address' );
260
  return new ShippingFactory( $address_factory );
261
  },
262
- 'api.factory.amount' => static function ( $container ): AmountFactory {
263
  $item_factory = $container->get( 'api.factory.item' );
264
  return new AmountFactory( $item_factory );
265
  },
266
- 'api.factory.payer' => static function ( $container ): PayerFactory {
267
  $address_factory = $container->get( 'api.factory.address' );
268
  return new PayerFactory( $address_factory );
269
  },
270
- 'api.factory.address' => static function ( $container ): AddressFactory {
271
  return new AddressFactory();
272
  },
273
- 'api.factory.payment-source' => static function ( $container ): PaymentSourceFactory {
274
  return new PaymentSourceFactory();
275
  },
276
- 'api.factory.order' => static function ( $container ): OrderFactory {
277
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
278
  $payer_factory = $container->get( 'api.factory.payer' );
279
  $application_context_repository = $container->get( 'api.repository.application-context' );
@@ -287,15 +290,15 @@ return array(
287
  $payment_source_factory
288
  );
289
  },
290
- 'api.factory.payments' => static function ( $container ): PaymentsFactory {
291
  $authorizations_factory = $container->get( 'api.factory.authorization' );
292
  $capture_factory = $container->get( 'api.factory.capture' );
293
  return new PaymentsFactory( $authorizations_factory, $capture_factory );
294
  },
295
- 'api.factory.authorization' => static function ( $container ): AuthorizationFactory {
296
  return new AuthorizationFactory();
297
  },
298
- 'api.helpers.dccapplies' => static function ( $container ) : DccApplies {
299
  return new DccApplies();
300
  },
301
  );
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
14
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
15
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
48
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
49
 
50
  return array(
51
+ 'api.host' => function( ContainerInterface $container ) : string {
52
  return PAYPAL_API_URL;
53
  },
54
+ 'api.paypal-host' => function( ContainerInterface $container ) : string {
55
  return PAYPAL_API_URL;
56
  },
57
  'api.partner_merchant_id' => static function () : string {
72
  'api.prefix' => static function (): string {
73
  return 'WC-';
74
  },
75
+ 'api.bearer' => static function ( ContainerInterface $container ): Bearer {
76
  $cache = new Cache( 'ppcp-paypal-bearer' );
77
  $key = $container->get( 'api.key' );
78
  $secret = $container->get( 'api.secret' );
88
  $settings
89
  );
90
  },
91
+ 'api.endpoint.partners' => static function ( ContainerInterface $container ) : PartnersEndpoint {
92
  return new PartnersEndpoint(
93
  $container->get( 'api.host' ),
94
  $container->get( 'api.bearer' ),
98
  $container->get( 'api.merchant_id' )
99
  );
100
  },
101
+ 'api.factory.sellerstatus' => static function ( ContainerInterface $container ) : SellerStatusFactory {
102
  return new SellerStatusFactory();
103
  },
104
+ 'api.endpoint.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenEndpoint {
105
  return new PaymentTokenEndpoint(
106
  $container->get( 'api.host' ),
107
  $container->get( 'api.bearer' ),
110
  $container->get( 'api.prefix' )
111
  );
112
  },
113
+ 'api.endpoint.webhook' => static function ( ContainerInterface $container ) : WebhookEndpoint {
114
 
115
  return new WebhookEndpoint(
116
  $container->get( 'api.host' ),
120
  $container->get( 'woocommerce.logger.woocommerce' )
121
  );
122
  },
123
+ 'api.endpoint.partner-referrals' => static function ( ContainerInterface $container ) : PartnerReferrals {
124
 
125
  return new PartnerReferrals(
126
  $container->get( 'api.host' ),
129
  $container->get( 'woocommerce.logger.woocommerce' )
130
  );
131
  },
132
+ 'api.endpoint.identity-token' => static function ( ContainerInterface $container ) : IdentityToken {
133
 
134
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
135
  $prefix = $container->get( 'api.prefix' );
140
  $prefix
141
  );
142
  },
143
+ 'api.endpoint.payments' => static function ( ContainerInterface $container ): PaymentsEndpoint {
144
  $authorizations_factory = $container->get( 'api.factory.authorization' );
145
  $capture_factory = $container->get( 'api.factory.capture' );
146
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
153
  $logger
154
  );
155
  },
156
+ 'api.endpoint.login-seller' => static function ( ContainerInterface $container ) : LoginSeller {
157
 
158
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
159
  return new LoginSeller(
162
  $logger
163
  );
164
  },
165
+ 'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint {
166
  $order_factory = $container->get( 'api.factory.order' );
167
  $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
168
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
176
  $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
177
  $application_context_repository = $container->get( 'api.repository.application-context' );
178
  $paypal_request_id = $container->get( 'api.repository.paypal-request-id' );
179
+ $subscription_helper = $container->get( 'subscription.helper' );
180
  return new OrderEndpoint(
181
  $container->get( 'api.host' ),
182
  $container->get( 'api.bearer' ),
185
  $intent,
186
  $logger,
187
  $application_context_repository,
188
+ $paypal_request_id,
189
+ $subscription_helper
190
  );
191
  },
192
+ 'api.repository.paypal-request-id' => static function( ContainerInterface $container ) : PayPalRequestIdRepository {
193
  return new PayPalRequestIdRepository();
194
  },
195
+ 'api.repository.application-context' => static function( ContainerInterface $container ) : ApplicationContextRepository {
196
 
197
  $settings = $container->get( 'wcgateway.settings' );
198
  return new ApplicationContextRepository( $settings );
199
  },
200
+ 'api.repository.partner-referrals-data' => static function ( ContainerInterface $container ) : PartnerReferralsData {
201
 
202
  $merchant_email = $container->get( 'api.merchant_email' );
203
  $dcc_applies = $container->get( 'api.helpers.dccapplies' );
204
  return new PartnerReferralsData( $merchant_email, $dcc_applies );
205
  },
206
+ 'api.repository.cart' => static function ( ContainerInterface $container ): CartRepository {
207
  $factory = $container->get( 'api.factory.purchase-unit' );
208
  return new CartRepository( $factory );
209
  },
210
+ 'api.repository.payee' => static function ( ContainerInterface $container ): PayeeRepository {
211
  $merchant_email = $container->get( 'api.merchant_email' );
212
  $merchant_id = $container->get( 'api.merchant_id' );
213
  return new PayeeRepository( $merchant_email, $merchant_id );
214
  },
215
+ 'api.factory.application-context' => static function ( ContainerInterface $container ) : ApplicationContextFactory {
216
  return new ApplicationContextFactory();
217
  },
218
+ 'api.factory.payment-token' => static function ( ContainerInterface $container ) : PaymentTokenFactory {
219
  return new PaymentTokenFactory();
220
  },
221
+ 'api.factory.webhook' => static function ( ContainerInterface $container ): WebhookFactory {
222
  return new WebhookFactory();
223
  },
224
+ 'api.factory.webhook-event' => static function ( ContainerInterface $container ): WebhookEventFactory {
225
  return new WebhookEventFactory();
226
  },
227
+ 'api.factory.capture' => static function ( ContainerInterface $container ): CaptureFactory {
228
 
229
  $amount_factory = $container->get( 'api.factory.amount' );
230
  return new CaptureFactory( $amount_factory );
231
  },
232
+ 'api.factory.purchase-unit' => static function ( ContainerInterface $container ): PurchaseUnitFactory {
233
 
234
  $amount_factory = $container->get( 'api.factory.amount' );
235
  $payee_repository = $container->get( 'api.repository.payee' );
249
  $prefix
250
  );
251
  },
252
+ 'api.factory.patch-collection-factory' => static function ( ContainerInterface $container ): PatchCollectionFactory {
253
  return new PatchCollectionFactory();
254
  },
255
+ 'api.factory.payee' => static function ( ContainerInterface $container ): PayeeFactory {
256
  return new PayeeFactory();
257
  },
258
+ 'api.factory.item' => static function ( ContainerInterface $container ): ItemFactory {
259
  return new ItemFactory();
260
  },
261
+ 'api.factory.shipping' => static function ( ContainerInterface $container ): ShippingFactory {
262
  $address_factory = $container->get( 'api.factory.address' );
263
  return new ShippingFactory( $address_factory );
264
  },
265
+ 'api.factory.amount' => static function ( ContainerInterface $container ): AmountFactory {
266
  $item_factory = $container->get( 'api.factory.item' );
267
  return new AmountFactory( $item_factory );
268
  },
269
+ 'api.factory.payer' => static function ( ContainerInterface $container ): PayerFactory {
270
  $address_factory = $container->get( 'api.factory.address' );
271
  return new PayerFactory( $address_factory );
272
  },
273
+ 'api.factory.address' => static function ( ContainerInterface $container ): AddressFactory {
274
  return new AddressFactory();
275
  },
276
+ 'api.factory.payment-source' => static function ( ContainerInterface $container ): PaymentSourceFactory {
277
  return new PaymentSourceFactory();
278
  },
279
+ 'api.factory.order' => static function ( ContainerInterface $container ): OrderFactory {
280
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
281
  $payer_factory = $container->get( 'api.factory.payer' );
282
  $application_context_repository = $container->get( 'api.repository.application-context' );
290
  $payment_source_factory
291
  );
292
  },
293
+ 'api.factory.payments' => static function ( ContainerInterface $container ): PaymentsFactory {
294
  $authorizations_factory = $container->get( 'api.factory.authorization' );
295
  $capture_factory = $container->get( 'api.factory.capture' );
296
  return new PaymentsFactory( $authorizations_factory, $capture_factory );
297
  },
298
+ 'api.factory.authorization' => static function ( ContainerInterface $container ): AuthorizationFactory {
299
  return new AuthorizationFactory();
300
  },
301
+ 'api.helpers.dccapplies' => static function ( ContainerInterface $container ) : DccApplies {
302
  return new DccApplies();
303
  },
304
  );
modules/ppcp-api-client/src/{class-apimodule.php → ApiModule.php} RENAMED
@@ -20,9 +20,7 @@ use Psr\Container\ContainerInterface;
20
  class ApiModule implements ModuleInterface {
21
 
22
  /**
23
- * Sets up the module.
24
- *
25
- * @return ServiceProviderInterface
26
  */
27
  public function setup(): ServiceProviderInterface {
28
  return new ServiceProvider(
@@ -32,11 +30,9 @@ class ApiModule implements ModuleInterface {
32
  }
33
 
34
  /**
35
- * Runs the module.
36
- *
37
- * @param ContainerInterface $container The container.
38
  */
39
- public function run( ContainerInterface $container ): void {
40
  add_action(
41
  'woocommerce_after_calculate_totals',
42
  function ( \WC_Cart $cart ) {
20
  class ApiModule implements ModuleInterface {
21
 
22
  /**
23
+ * {@inheritDoc}
 
 
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider(
30
  }
31
 
32
  /**
33
+ * {@inheritDoc}
 
 
34
  */
35
+ public function run( ContainerInterface $c ): void {
36
  add_action(
37
  'woocommerce_after_calculate_totals',
38
  function ( \WC_Cart $cart ) {
modules/ppcp-api-client/src/Authentication/{class-bearer.php → Bearer.php} RENAMED
File without changes
modules/ppcp-api-client/src/Authentication/{class-connectbearer.php → ConnectBearer.php} RENAMED
File without changes
modules/ppcp-api-client/src/Authentication/{class-paypalbearer.php → PayPalBearer.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-identitytoken.php → IdentityToken.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-loginseller.php → LoginSeller.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-orderendpoint.php → OrderEndpoint.php} RENAMED
@@ -27,6 +27,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\ErrorResponse;
27
  use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
28
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
29
  use Psr\Log\LoggerInterface;
 
30
 
31
  /**
32
  * Class OrderEndpoint
@@ -35,6 +36,13 @@ class OrderEndpoint {
35
 
36
  use RequestTrait;
37
 
 
 
 
 
 
 
 
38
  /**
39
  * The host.
40
  *
@@ -109,6 +117,7 @@ class OrderEndpoint {
109
  * @param LoggerInterface $logger The logger.
110
  * @param ApplicationContextRepository $application_context_repository The application context repository.
111
  * @param PayPalRequestIdRepository $paypal_request_id_repository The paypal request id repository.
 
112
  * @param string $bn_code The BN Code.
113
  */
114
  public function __construct(
@@ -120,6 +129,7 @@ class OrderEndpoint {
120
  LoggerInterface $logger,
121
  ApplicationContextRepository $application_context_repository,
122
  PayPalRequestIdRepository $paypal_request_id_repository,
 
123
  string $bn_code = ''
124
  ) {
125
 
@@ -132,6 +142,7 @@ class OrderEndpoint {
132
  $this->application_context_repository = $application_context_repository;
133
  $this->bn_code = $bn_code;
134
  $this->paypal_request_id_repository = $paypal_request_id_repository;
 
135
  }
136
 
137
  /**
@@ -193,9 +204,13 @@ class OrderEndpoint {
193
  : ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE
194
  : ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
195
 
 
 
 
 
196
  $bearer = $this->bearer->bearer();
197
  $data = array(
198
- 'intent' => $this->intent,
199
  'purchase_units' => array_map(
200
  static function ( PurchaseUnit $item ): array {
201
  return $item->to_array();
@@ -572,4 +587,20 @@ class OrderEndpoint {
572
  $new_order = $this->order( $order_to_update->id() );
573
  return $new_order;
574
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
575
  }
27
  use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
28
  use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
29
  use Psr\Log\LoggerInterface;
30
+ use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
31
 
32
  /**
33
  * Class OrderEndpoint
36
 
37
  use RequestTrait;
38
 
39
+ /**
40
+ * The subscription helper
41
+ *
42
+ * @var SubscriptionHelper
43
+ */
44
+ protected $subscription_helper;
45
+
46
  /**
47
  * The host.
48
  *
117
  * @param LoggerInterface $logger The logger.
118
  * @param ApplicationContextRepository $application_context_repository The application context repository.
119
  * @param PayPalRequestIdRepository $paypal_request_id_repository The paypal request id repository.
120
+ * @param SubscriptionHelper $subscription_helper The subscription helper.
121
  * @param string $bn_code The BN Code.
122
  */
123
  public function __construct(
129
  LoggerInterface $logger,
130
  ApplicationContextRepository $application_context_repository,
131
  PayPalRequestIdRepository $paypal_request_id_repository,
132
+ SubscriptionHelper $subscription_helper,
133
  string $bn_code = ''
134
  ) {
135
 
142
  $this->application_context_repository = $application_context_repository;
143
  $this->bn_code = $bn_code;
144
  $this->paypal_request_id_repository = $paypal_request_id_repository;
145
+ $this->subscription_helper = $subscription_helper;
146
  }
147
 
148
  /**
204
  : ApplicationContext::SHIPPING_PREFERENCE_GET_FROM_FILE
205
  : ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
206
 
207
+ if ( $this->has_items_without_shipping( $items ) ) {
208
+ $shipping_preferences = ApplicationContext::SHIPPING_PREFERENCE_NO_SHIPPING;
209
+ }
210
+
211
  $bearer = $this->bearer->bearer();
212
  $data = array(
213
+ 'intent' => ( $this->subscription_helper->cart_contains_subscription() || $this->subscription_helper->current_product_is_subscription() ) ? 'AUTHORIZE' : $this->intent,
214
  'purchase_units' => array_map(
215
  static function ( PurchaseUnit $item ): array {
216
  return $item->to_array();
587
  $new_order = $this->order( $order_to_update->id() );
588
  return $new_order;
589
  }
590
+
591
+ /**
592
+ * Checks if there is at least one item without shipping.
593
+ *
594
+ * @param array $items The items.
595
+ * @return bool Whether items contains shipping or not.
596
+ */
597
+ private function has_items_without_shipping( array $items ): bool {
598
+ foreach ( $items as $item ) {
599
+ if ( ! $item->shipping() ) {
600
+ return true;
601
+ }
602
+ }
603
+
604
+ return false;
605
+ }
606
  }
modules/ppcp-api-client/src/Endpoint/{class-partnerreferrals.php → PartnerReferrals.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-partnersendpoint.php → PartnersEndpoint.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-paymenttokenendpoint.php → PaymentTokenEndpoint.php} RENAMED
File without changes
modules/ppcp-api-client/src/Endpoint/{class-paymentsendpoint.php → PaymentsEndpoint.php} RENAMED
@@ -11,7 +11,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Refund;
16
  use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
17
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Refund;
16
  use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
17
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
modules/ppcp-api-client/src/Endpoint/{class-requesttrait.php → RequestTrait.php} RENAMED
@@ -9,6 +9,8 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
 
 
 
12
  /**
13
  * Trait RequestTrait
14
  */
@@ -20,7 +22,7 @@ trait RequestTrait {
20
  * @param string $url The URL to request.
21
  * @param array $args The arguments by which to request.
22
  *
23
- * @return array|\WP_Error
24
  */
25
  private function request( string $url, array $args ) {
26
 
@@ -44,12 +46,12 @@ trait RequestTrait {
44
  /**
45
  * Returns request and response information as string.
46
  *
47
- * @param string $url The request URL.
48
- * @param array $args The request arguments.
49
- * @param array $response The response.
50
  * @return string
51
  */
52
- private function request_response_string( string $url, array $args, array $response ): string {
53
  $method = $args['method'] ?? '';
54
  $output = $method . ' ' . $url . "\n";
55
  if ( isset( $args['body'] ) ) {
@@ -65,6 +67,11 @@ trait RequestTrait {
65
  }
66
  }
67
 
 
 
 
 
 
68
  if ( isset( $response['headers']->getAll()['paypal-debug-id'] ) ) {
69
  $output .= 'Response Debug ID: ' . $response['headers']->getAll()['paypal-debug-id'] . "\n";
70
  }
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
11
 
12
+ use WP_Error;
13
+
14
  /**
15
  * Trait RequestTrait
16
  */
22
  * @param string $url The URL to request.
23
  * @param array $args The arguments by which to request.
24
  *
25
+ * @return array|WP_Error
26
  */
27
  private function request( string $url, array $args ) {
28
 
46
  /**
47
  * Returns request and response information as string.
48
  *
49
+ * @param string $url The request URL.
50
+ * @param array $args The request arguments.
51
+ * @param array|WP_Error $response The response.
52
  * @return string
53
  */
54
+ private function request_response_string( string $url, array $args, $response ): string {
55
  $method = $args['method'] ?? '';
56
  $output = $method . ' ' . $url . "\n";
57
  if ( isset( $args['body'] ) ) {
67
  }
68
  }
69
 
70
+ if ( $response instanceof WP_Error ) {
71
+ $output .= 'Request failed. WP error message: ' . implode( "\n", $response->get_error_messages() ) . "\n";
72
+ return $output;
73
+ }
74
+
75
  if ( isset( $response['headers']->getAll()['paypal-debug-id'] ) ) {
76
  $output .= 'Response Debug ID: ' . $response['headers']->getAll()['paypal-debug-id'] . "\n";
77
  }
modules/ppcp-api-client/src/Endpoint/{class-webhookendpoint.php → WebhookEndpoint.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-address.php → Address.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-amount.php → Amount.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-amountbreakdown.php → AmountBreakdown.php} RENAMED
@@ -17,49 +17,49 @@ class AmountBreakdown {
17
  /**
18
  * The item total.
19
  *
20
- * @var Money
21
  */
22
  private $item_total;
23
 
24
  /**
25
  * The shipping.
26
  *
27
- * @var Money
28
  */
29
  private $shipping;
30
 
31
  /**
32
  * The tax total.
33
  *
34
- * @var Money
35
  */
36
  private $tax_total;
37
 
38
  /**
39
  * The handling.
40
  *
41
- * @var Money
42
  */
43
  private $handling;
44
 
45
  /**
46
  * The insurance.
47
  *
48
- * @var Money
49
  */
50
  private $insurance;
51
 
52
  /**
53
  * The shipping discount.
54
  *
55
- * @var Money
56
  */
57
  private $shipping_discount;
58
 
59
  /**
60
  * The discount.
61
  *
62
- * @var Money
63
  */
64
  private $discount;
65
 
@@ -75,13 +75,13 @@ class AmountBreakdown {
75
  * @param Money|null $discount The discount.
76
  */
77
  public function __construct(
78
- Money $item_total = null,
79
- Money $shipping = null,
80
- Money $tax_total = null,
81
- Money $handling = null,
82
- Money $insurance = null,
83
- Money $shipping_discount = null,
84
- Money $discount = null
85
  ) {
86
 
87
  $this->item_total = $item_total;
17
  /**
18
  * The item total.
19
  *
20
+ * @var Money|null
21
  */
22
  private $item_total;
23
 
24
  /**
25
  * The shipping.
26
  *
27
+ * @var Money|null
28
  */
29
  private $shipping;
30
 
31
  /**
32
  * The tax total.
33
  *
34
+ * @var Money|null
35
  */
36
  private $tax_total;
37
 
38
  /**
39
  * The handling.
40
  *
41
+ * @var Money|null
42
  */
43
  private $handling;
44
 
45
  /**
46
  * The insurance.
47
  *
48
+ * @var Money|null
49
  */
50
  private $insurance;
51
 
52
  /**
53
  * The shipping discount.
54
  *
55
+ * @var Money|null
56
  */
57
  private $shipping_discount;
58
 
59
  /**
60
  * The discount.
61
  *
62
+ * @var Money|null
63
  */
64
  private $discount;
65
 
75
  * @param Money|null $discount The discount.
76
  */
77
  public function __construct(
78
+ ?Money $item_total = null,
79
+ ?Money $shipping = null,
80
+ ?Money $tax_total = null,
81
+ ?Money $handling = null,
82
+ ?Money $insurance = null,
83
+ ?Money $shipping_discount = null,
84
+ ?Money $discount = null
85
  ) {
86
 
87
  $this->item_total = $item_total;
modules/ppcp-api-client/src/Entity/{class-applicationcontext.php → ApplicationContext.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-authorization.php → Authorization.php} RENAMED
@@ -61,6 +61,16 @@ class Authorization {
61
  return $this->authorization_status;
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
64
  /**
65
  * Returns the object as array.
66
  *
61
  return $this->authorization_status;
62
  }
63
 
64
+ /**
65
+ * Checks whether the authorization can be voided.
66
+ *
67
+ * @return bool
68
+ */
69
+ public function is_voidable(): bool {
70
+ return $this->authorization_status->is( AuthorizationStatus::CREATED ) ||
71
+ $this->authorization_status->is( AuthorizationStatus::PENDING );
72
+ }
73
+
74
  /**
75
  * Returns the object as array.
76
  *
modules/ppcp-api-client/src/Entity/{class-authorizationstatus.php → AuthorizationStatus.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-authorizationstatusdetails.php → AuthorizationStatusDetails.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-capture.php → Capture.php} RENAMED
@@ -4,12 +4,12 @@
4
  *
5
  * @link https://developer.paypal.com/docs/api/orders/v2/#definition-capture
6
  *
7
- * @package Woocommerce\PayPalCommerce\ApiClient\Entity
8
  */
9
 
10
  declare( strict_types=1 );
11
 
12
- namespace Woocommerce\PayPalCommerce\ApiClient\Entity;
13
 
14
  /**
15
  * Class Capture
@@ -164,7 +164,7 @@ class Capture {
164
  * @return array
165
  */
166
  public function to_array() : array {
167
- $data = array(
168
  'id' => $this->id(),
169
  'status' => $this->status()->name(),
170
  'amount' => $this->amount()->to_array(),
@@ -173,8 +173,9 @@ class Capture {
173
  'invoice_id' => $this->invoice_id(),
174
  'custom_id' => $this->custom_id(),
175
  );
176
- if ( $this->status()->details() ) {
177
- $data['status_details'] = array( 'reason' => $this->status()->details()->reason() );
 
178
  }
179
  return $data;
180
  }
4
  *
5
  * @link https://developer.paypal.com/docs/api/orders/v2/#definition-capture
6
  *
7
+ * @package WooCommerce\PayPalCommerce\ApiClient\Entity
8
  */
9
 
10
  declare( strict_types=1 );
11
 
12
+ namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
13
 
14
  /**
15
  * Class Capture
164
  * @return array
165
  */
166
  public function to_array() : array {
167
+ $data = array(
168
  'id' => $this->id(),
169
  'status' => $this->status()->name(),
170
  'amount' => $this->amount()->to_array(),
173
  'invoice_id' => $this->invoice_id(),
174
  'custom_id' => $this->custom_id(),
175
  );
176
+ $details = $this->status()->details();
177
+ if ( $details ) {
178
+ $data['status_details'] = array( 'reason' => $details->reason() );
179
  }
180
  return $data;
181
  }
modules/ppcp-api-client/src/Entity/{class-capturestatus.php → CaptureStatus.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-capturestatusdetails.php → CaptureStatusDetails.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-cardauthenticationresult.php → CardAuthenticationResult.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-item.php → Item.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-money.php → Money.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-order.php → Order.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-orderstatus.php → OrderStatus.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-patch.php → Patch.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-patchcollection.php → PatchCollection.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payee.php → Payee.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payer.php → Payer.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payername.php → PayerName.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payertaxinfo.php → PayerTaxInfo.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymentmethod.php → PaymentMethod.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymentsource.php → PaymentSource.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymentsourcecard.php → PaymentSourceCard.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymentsourcewallet.php → PaymentSourceWallet.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-paymenttoken.php → PaymentToken.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-payments.php → Payments.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-phone.php → Phone.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-phonewithtype.php → PhoneWithType.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-purchaseunit.php → PurchaseUnit.php} RENAMED
@@ -303,55 +303,79 @@ class PurchaseUnit {
303
  * @return bool
304
  */
305
  private function ditch_items_when_mismatch( Amount $amount, Item ...$items ): bool {
306
- $fee_items_total = ( $amount->breakdown() && $amount->breakdown()->item_total() ) ?
307
- $amount->breakdown()->item_total()->value() : null;
308
- $fee_tax_total = ( $amount->breakdown() && $amount->breakdown()->tax_total() ) ?
309
- $amount->breakdown()->tax_total()->value() : null;
310
-
311
- foreach ( $items as $item ) {
312
- if ( null !== $fee_items_total ) {
313
- $fee_items_total -= $item->unit_amount()->value() * $item->quantity();
314
- }
315
- if ( null !== $fee_tax_total ) {
316
- $fee_tax_total -= $item->tax()->value() * $item->quantity();
317
- }
318
  }
319
 
320
- $fee_items_total = round( $fee_items_total, 2 );
321
- $fee_tax_total = round( $fee_tax_total, 2 );
 
 
 
 
 
 
 
 
 
322
 
323
- if ( 0.0 !== $fee_items_total || 0.0 !== $fee_tax_total ) {
324
- return true;
 
325
  }
326
 
327
- $breakdown = $this->amount()->breakdown();
328
- if ( ! $breakdown ) {
329
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  }
331
- $amount_total = 0;
332
- if ( $breakdown->shipping() ) {
333
- $amount_total += $breakdown->shipping()->value();
 
 
 
 
 
 
 
334
  }
335
- if ( $breakdown->item_total() ) {
336
- $amount_total += $breakdown->item_total()->value();
337
  }
338
- if ( $breakdown->discount() ) {
339
- $amount_total -= $breakdown->discount()->value();
340
  }
341
- if ( $breakdown->tax_total() ) {
342
- $amount_total += $breakdown->tax_total()->value();
343
  }
344
- if ( $breakdown->shipping_discount() ) {
345
- $amount_total -= $breakdown->shipping_discount()->value();
346
  }
347
- if ( $breakdown->handling() ) {
348
- $amount_total += $breakdown->handling()->value();
349
  }
350
- if ( $breakdown->insurance() ) {
351
- $amount_total += $breakdown->insurance()->value();
352
  }
353
 
354
- $amount_value = $this->amount()->value();
355
  $needs_to_ditch = (string) $amount_total !== (string) $amount_value;
356
  return $needs_to_ditch;
357
  }
303
  * @return bool
304
  */
305
  private function ditch_items_when_mismatch( Amount $amount, Item ...$items ): bool {
306
+ $breakdown = $amount->breakdown();
307
+ if ( ! $breakdown ) {
308
+ return false;
 
 
 
 
 
 
 
 
 
309
  }
310
 
311
+ $item_total = $breakdown->item_total();
312
+ if ( $item_total ) {
313
+ $remaining_item_total = array_reduce(
314
+ $items,
315
+ function ( float $total, Item $item ): float {
316
+ return $total - $item->unit_amount()->value() * (float) $item->quantity();
317
+ },
318
+ $item_total->value()
319
+ );
320
+
321
+ $remaining_item_total = round( $remaining_item_total, 2 );
322
 
323
+ if ( 0.0 !== $remaining_item_total ) {
324
+ return true;
325
+ }
326
  }
327
 
328
+ $tax_total = $breakdown->tax_total();
329
+ if ( $tax_total ) {
330
+ $remaining_tax_total = array_reduce(
331
+ $items,
332
+ function ( float $total, Item $item ): float {
333
+ $tax = $item->tax();
334
+ if ( $tax ) {
335
+ $total -= $tax->value() * (float) $item->quantity();
336
+ }
337
+ return $total;
338
+ },
339
+ $tax_total->value()
340
+ );
341
+
342
+ $remaining_tax_total = round( $remaining_tax_total, 2 );
343
+
344
+ if ( 0.0 !== $remaining_tax_total ) {
345
+ return true;
346
+ }
347
  }
348
+
349
+ $shipping = $breakdown->shipping();
350
+ $discount = $breakdown->discount();
351
+ $shipping_discount = $breakdown->shipping_discount();
352
+ $handling = $breakdown->handling();
353
+ $insurance = $breakdown->insurance();
354
+
355
+ $amount_total = 0.0;
356
+ if ( $shipping ) {
357
+ $amount_total += $shipping->value();
358
  }
359
+ if ( $item_total ) {
360
+ $amount_total += $item_total->value();
361
  }
362
+ if ( $discount ) {
363
+ $amount_total -= $discount->value();
364
  }
365
+ if ( $tax_total ) {
366
+ $amount_total += $tax_total->value();
367
  }
368
+ if ( $shipping_discount ) {
369
+ $amount_total -= $shipping_discount->value();
370
  }
371
+ if ( $handling ) {
372
+ $amount_total += $handling->value();
373
  }
374
+ if ( $insurance ) {
375
+ $amount_total += $insurance->value();
376
  }
377
 
378
+ $amount_value = $amount->value();
379
  $needs_to_ditch = (string) $amount_total !== (string) $amount_value;
380
  return $needs_to_ditch;
381
  }
modules/ppcp-api-client/src/Entity/{class-refund.php → Refund.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-sellerstatus.php → SellerStatus.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-sellerstatusproduct.php → SellerStatusProduct.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-shipping.php → Shipping.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-token.php → Token.php} RENAMED
File without changes
modules/ppcp-api-client/src/Entity/{class-webhook.php → Webhook.php} RENAMED
@@ -40,9 +40,9 @@ class Webhook {
40
  /**
41
  * Webhook constructor.
42
  *
43
- * @param string $url The URL of the webhook.
44
- * @param string[] $event_types The associated event types.
45
- * @param string $id The id of the webhook.
46
  */
47
  public function __construct( string $url, array $event_types, string $id = '' ) {
48
  $this->url = $url;
40
  /**
41
  * Webhook constructor.
42
  *
43
+ * @param string $url The URL of the webhook.
44
+ * @param stdClass[] $event_types The associated event types.
45
+ * @param string $id The id of the webhook.
46
  */
47
  public function __construct( string $url, array $event_types, string $id = '' ) {
48
  $this->url = $url;
modules/ppcp-api-client/src/Entity/{class-webhookevent.php → WebhookEvent.php} RENAMED
File without changes
modules/ppcp-api-client/src/Exception/{class-notfoundexception.php → NotFoundException.php} RENAMED
File without changes
modules/ppcp-api-client/src/Exception/{class-paypalapiexception.php → PayPalApiException.php} RENAMED
File without changes
modules/ppcp-api-client/src/Exception/{class-runtimeexception.php → RuntimeException.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-addressfactory.php → AddressFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-amountfactory.php → AmountFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-applicationcontextfactory.php → ApplicationContextFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-authorizationfactory.php → AuthorizationFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-capturefactory.php → CaptureFactory.php} RENAMED
@@ -9,7 +9,7 @@ declare( strict_types=1 );
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatusDetails;
15
 
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatusDetails;
15
 
modules/ppcp-api-client/src/Factory/{class-itemfactory.php → ItemFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-orderfactory.php → OrderFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-patchcollectionfactory.php → PatchCollectionFactory.php} RENAMED
@@ -52,14 +52,12 @@ class PatchCollectionFactory {
52
  array_filter(
53
  $from,
54
  static function ( PurchaseUnit $unit ) use ( $purchase_unit_to ): bool {
55
- //phpcs:disable WordPress.PHP.StrictComparisons.LooseComparison
56
  // Loose comparison needed to compare two objects.
 
57
  return $unit == $purchase_unit_to;
58
- //phpcs:enable WordPress.PHP.StrictComparisons.LooseComparison
59
  }
60
  )
61
  );
62
- $needs_update = true;
63
  if ( ! $needs_update ) {
64
  continue;
65
  }
52
  array_filter(
53
  $from,
54
  static function ( PurchaseUnit $unit ) use ( $purchase_unit_to ): bool {
 
55
  // Loose comparison needed to compare two objects.
56
+ // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
57
  return $unit == $purchase_unit_to;
 
58
  }
59
  )
60
  );
 
61
  if ( ! $needs_update ) {
62
  continue;
63
  }
modules/ppcp-api-client/src/Factory/{class-payeefactory.php → PayeeFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-payerfactory.php → PayerFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-paymentsourcefactory.php → PaymentSourceFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-paymenttokenfactory.php → PaymentTokenFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-paymentsfactory.php → PaymentsFactory.php} RENAMED
@@ -10,7 +10,7 @@ declare(strict_types=1);
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
13
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
15
 
16
  /**
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
15
 
16
  /**
modules/ppcp-api-client/src/Factory/{class-purchaseunitfactory.php → PurchaseUnitFactory.php} RENAMED
@@ -121,9 +121,11 @@ class PurchaseUnitFactory {
121
  $payee = $this->payee_repository->payee();
122
  $wc_order_id = $order->get_order_number();
123
  $custom_id = $this->prefix . $wc_order_id;
124
- $invoice_id = $this->prefix . $wc_order_id;
 
125
  $soft_descriptor = '';
126
- $purchase_unit = new PurchaseUnit(
 
127
  $amount,
128
  $items,
129
  $shipping,
121
  $payee = $this->payee_repository->payee();
122
  $wc_order_id = $order->get_order_number();
123
  $custom_id = $this->prefix . $wc_order_id;
124
+ $retry = $order->get_meta( 'ppcp-retry' ) ? '-' . $order->get_meta( 'ppcp-retry' ) : '';
125
+ $invoice_id = $this->prefix . $wc_order_id . $retry;
126
  $soft_descriptor = '';
127
+
128
+ $purchase_unit = new PurchaseUnit(
129
  $amount,
130
  $items,
131
  $shipping,
modules/ppcp-api-client/src/Factory/{class-sellerstatusfactory.php → SellerStatusFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-shippingfactory.php → ShippingFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-webhookeventfactory.php → WebhookEventFactory.php} RENAMED
File without changes
modules/ppcp-api-client/src/Factory/{class-webhookfactory.php → WebhookFactory.php} RENAMED
@@ -9,6 +9,7 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
13
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
 
@@ -20,15 +21,15 @@ class WebhookFactory {
20
  /**
21
  * Returns a webhook for a URL with an array of event types associated to this URL.
22
  *
23
- * @param string $url The URL.
24
- * @param array $event_types The event types to which this URL listens to.
25
  *
26
  * @return Webhook
27
  */
28
  public function for_url_and_events( string $url, array $event_types ): Webhook {
29
  $event_types = array_map(
30
- static function ( string $type ): array {
31
- return array( 'name' => $type );
32
  },
33
  $event_types
34
  );
@@ -52,12 +53,12 @@ class WebhookFactory {
52
  /**
53
  * Returns a Webhook based of a PayPal JSON response.
54
  *
55
- * @param \stdClass $data The JSON object.
56
  *
57
  * @return Webhook
58
  * @throws RuntimeException When JSON object is malformed.
59
  */
60
- public function from_paypal_response( \stdClass $data ): Webhook {
61
  if ( ! isset( $data->id ) ) {
62
  throw new RuntimeException(
63
  __( 'No id for webhook given.', 'woocommerce-paypal-payments' )
9
 
10
  namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
11
 
12
+ use stdClass;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
14
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
15
 
21
  /**
22
  * Returns a webhook for a URL with an array of event types associated to this URL.
23
  *
24
+ * @param string $url The URL.
25
+ * @param string[] $event_types The event types to which this URL listens to.
26
  *
27
  * @return Webhook
28
  */
29
  public function for_url_and_events( string $url, array $event_types ): Webhook {
30
  $event_types = array_map(
31
+ static function ( string $type ): stdClass {
32
+ return (object) array( 'name' => $type );
33
  },
34
  $event_types
35
  );
53
  /**
54
  * Returns a Webhook based of a PayPal JSON response.
55
  *
56
+ * @param stdClass $data The JSON object.
57
  *
58
  * @return Webhook
59
  * @throws RuntimeException When JSON object is malformed.
60
  */
61
+ public function from_paypal_response( stdClass $data ): Webhook {
62
  if ( ! isset( $data->id ) ) {
63
  throw new RuntimeException(
64
  __( 'No id for webhook given.', 'woocommerce-paypal-payments' )
modules/ppcp-api-client/src/Helper/{class-cache.php → Cache.php} RENAMED
File without changes
modules/ppcp-api-client/src/Helper/{class-dccapplies.php → DccApplies.php} RENAMED
File without changes
modules/ppcp-api-client/src/Helper/{class-errorresponse.php → ErrorResponse.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-applicationcontextrepository.php → ApplicationContextRepository.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-cartrepository.php → CartRepository.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-partnerreferralsdata.php → PartnerReferralsData.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-paypalrequestidrepository.php → PayPalRequestIdRepository.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-payeerepository.php → PayeeRepository.php} RENAMED
File without changes
modules/ppcp-api-client/src/Repository/{class-purchaseunitrepositoryinterface.php → PurchaseUnitRepositoryInterface.php} RENAMED
File without changes
modules/ppcp-button/assets/js/button.js CHANGED
@@ -1 +1 @@
1
- (()=>{"use strict";var __webpack_modules__={94:()=>{eval("\n;// CONCATENATED MODULE: ./resources/js/modules/ErrorHandler.js\nclass ErrorHandler {\n constructor(genericErrorText) {\n this.genericErrorText = genericErrorText;\n this.wrapper = document.querySelector('.woocommerce-notices-wrapper');\n this.messagesList = document.querySelector('ul.woocommerce-error');\n }\n\n genericError() {\n if (this.wrapper.classList.contains('ppcp-persist')) {\n return;\n }\n\n this.clear();\n this.message(this.genericErrorText);\n }\n\n appendPreparedErrorMessageElement(errorMessageElement) {\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n this.messagesList.replaceWith(errorMessageElement);\n }\n\n message(text, persist = false) {\n if (!typeof String || text.length === 0) {\n throw new Error('A new message text must be a non-empty string.');\n }\n\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n if (persist) {\n this.wrapper.classList.add('ppcp-persist');\n } else {\n this.wrapper.classList.remove('ppcp-persist');\n }\n\n let messageNode = this.prepareMessagesListItem(text);\n this.messagesList.appendChild(messageNode);\n jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'));\n }\n\n prepareMessagesList() {\n if (this.messagesList === null) {\n this.messagesList = document.createElement('ul');\n this.messagesList.setAttribute('class', 'woocommerce-error');\n this.messagesList.setAttribute('role', 'alert');\n this.wrapper.appendChild(this.messagesList);\n }\n }\n\n prepareMessagesListItem(message) {\n const li = document.createElement('li');\n li.innerHTML = message;\n return li;\n }\n\n sanitize(text) {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = text;\n return textarea.value.replace('Error: ', '');\n }\n\n clear() {\n if (!this.wrapper.classList.contains('woocommerce-error')) {\n return;\n }\n\n this.wrapper.classList.remove('woocommerce-error');\n this.wrapper.innerText = '';\n }\n\n}\n\n/* harmony default export */ const modules_ErrorHandler = (ErrorHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForContinue.js\nconst onApprove = (context, errorHandler) => {\n return (data, actions) => {\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n ;\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CartActionHandler.js\n\n\n\nclass CartActionHandler {\n constructor(config, errorHandler) {\n this.config = config;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units: [],\n bn_code: bnCode,\n payer,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CartActionHandler = (CartActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/MiniCartBootstap.js\n\n\n\nclass MiniCartBootstap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.actionHandler = null;\n }\n\n init() {\n this.actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.render();\n jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.mini_cart_wrapper) !== null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.renderer.render(this.gateway.button.mini_cart_wrapper, this.gateway.hosted_fields.mini_cart_wrapper, this.actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_MiniCartBootstap = (MiniCartBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/UpdateCart.js\n\n\nclass UpdateCart {\n constructor(endpoint, nonce) {\n this.endpoint = endpoint;\n this.nonce = nonce;\n }\n /**\n *\n * @param onResolve\n * @param {Product[]} products\n * @returns {Promise<unknown>}\n */\n\n\n update(onResolve, products) {\n return new Promise((resolve, reject) => {\n fetch(this.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.nonce,\n products\n })\n }).then(result => {\n return result.json();\n }).then(result => {\n if (!result.success) {\n reject(result.data);\n return;\n }\n\n const resolved = onResolve(result.data);\n resolve(resolved);\n });\n });\n }\n\n}\n\n/* harmony default export */ const Helper_UpdateCart = (UpdateCart);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/ButtonsToggleListener.js\n/**\n * When you can't add something to the cart, the PayPal buttons should not show.\n * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.\n */\nclass ButtonsToggleListener {\n constructor(element, showCallback, hideCallback) {\n this.element = element;\n this.showCallback = showCallback;\n this.hideCallback = hideCallback;\n this.observer = null;\n }\n\n init() {\n const config = {\n attributes: true\n };\n\n const callback = () => {\n if (this.element.classList.contains('disabled')) {\n this.hideCallback();\n return;\n }\n\n this.showCallback();\n };\n\n this.observer = new MutationObserver(callback);\n this.observer.observe(this.element, config);\n callback();\n }\n\n disconnect() {\n this.observer.disconnect();\n }\n\n}\n\n/* harmony default export */ const Helper_ButtonsToggleListener = (ButtonsToggleListener);\n;// CONCATENATED MODULE: ./resources/js/modules/Entity/Product.js\nclass Product {\n constructor(id, quantity, variations) {\n this.id = id;\n this.quantity = quantity;\n this.variations = variations;\n }\n\n data() {\n return {\n id: this.id,\n quantity: this.quantity,\n variations: this.variations\n };\n }\n\n}\n\n/* harmony default export */ const Entity_Product = (Product);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/SingleProductActionHandler.js\n\n\n\n\n\nclass SingleProductActionHandler {\n constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler) {\n this.config = config;\n this.updateCart = updateCart;\n this.showButtonCallback = showButtonCallback;\n this.hideButtonCallback = hideButtonCallback;\n this.formElement = formElement;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n if (this.hasVariations()) {\n const observer = new Helper_ButtonsToggleListener(this.formElement.querySelector('.single_add_to_cart_button'), this.showButtonCallback, this.hideButtonCallback);\n observer.init();\n }\n\n return {\n createOrder: this.createOrder(),\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n createOrder() {\n var getProducts = null;\n\n if (!this.isGroupedProduct()) {\n getProducts = () => {\n const id = document.querySelector('[name=\"add-to-cart\"]').value;\n const qty = document.querySelector('[name=\"quantity\"]').value;\n const variations = this.variations();\n return [new Entity_Product(id, qty, variations)];\n };\n } else {\n getProducts = () => {\n const products = [];\n this.formElement.querySelectorAll('input[type=\"number\"]').forEach(element => {\n if (!element.value) {\n return;\n }\n\n const elementName = element.getAttribute('name').match(/quantity\\[([\\d]*)\\]/);\n\n if (elementName.length !== 2) {\n return;\n }\n\n const id = parseInt(elementName[1]);\n const quantity = parseInt(element.value);\n products.push(new Entity_Product(id, quantity, null));\n });\n return products;\n };\n }\n\n const createOrder = (data, actions) => {\n this.errorHandler.clear();\n\n const onResolve = purchase_units => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units,\n payer,\n bn_code: bnCode,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n const promise = this.updateCart.update(onResolve, getProducts());\n return promise;\n };\n\n return createOrder;\n }\n\n variations() {\n if (!this.hasVariations()) {\n return null;\n }\n\n const attributes = [...this.formElement.querySelectorAll(\"[name^='attribute_']\")].map(element => {\n return {\n value: element.value,\n name: element.name\n };\n });\n return attributes;\n }\n\n hasVariations() {\n return this.formElement.classList.contains('variations_form');\n }\n\n isGroupedProduct() {\n return this.formElement.classList.contains('grouped_form');\n }\n\n}\n\n/* harmony default export */ const ActionHandler_SingleProductActionHandler = (SingleProductActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/SingleProductBootstap.js\n\n\n\n\nclass SingleProductBootstap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n }\n\n init() {\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n return;\n }\n\n this.render();\n }\n\n shouldRender() {\n if (document.querySelector('form.cart') === null) {\n return false;\n }\n\n return true;\n }\n\n render() {\n const actionHandler = new ActionHandler_SingleProductActionHandler(this.gateway, new Helper_UpdateCart(this.gateway.ajax.change_cart.endpoint, this.gateway.ajax.change_cart.nonce), () => {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseInt(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n this.messages.renderWithAmount(amount);\n }, () => {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }, document.querySelector('form.cart'), new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_SingleProductBootstap = (SingleProductBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CartBootstap.js\n\n\n\nclass CartBootstrap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n }\n\n init() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.render();\n jQuery(document.body).on('updated_cart_totals updated_checkout', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n const actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const CartBootstap = (CartBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForPayNow.js\nconst onApproveForPayNow_onApprove = (context, errorHandler, spinner) => {\n return (data, actions) => {\n spinner.block();\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\nclass CheckoutActionHandler {\n constructor(config, errorHandler, spinner) {\n this.config = config;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n }\n\n configuration() {\n const spinner = this.spinner;\n\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n const errorHandler = this.errorHandler;\n const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';\n const formValues = jQuery(formSelector).serialize();\n const createaccount = jQuery('#createaccount').is(\":checked\") ? true : false;\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n payer,\n bn_code: bnCode,\n context: this.config.context,\n order_id: this.config.order_id,\n form: formValues,\n createaccount: createaccount\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n spinner.unblock(); //handle both messages sent from Woocommerce (data.messages) and this plugin (data.data.message)\n\n if (typeof data.messages !== 'undefined') {\n const domParser = new DOMParser();\n errorHandler.appendPreparedErrorMessageElement(domParser.parseFromString(data.messages, 'text/html').querySelector('ul'));\n } else {\n errorHandler.message(data.data.message, true);\n }\n\n return;\n }\n\n const input = document.createElement('input');\n input.setAttribute('type', 'hidden');\n input.setAttribute('name', 'ppcp-resume-order');\n input.setAttribute('value', data.data.purchase_units[0].custom_id);\n document.querySelector(formSelector).append(input);\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForPayNow(this, this.errorHandler, this.spinner),\n onCancel: () => {\n spinner.unblock();\n },\n onError: () => {\n this.errorHandler.genericError();\n spinner.unblock();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CheckoutActionHandler = (CheckoutActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CheckoutBootstap.js\n\n\n\nclass CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n jQuery(document).on('hosted_fields_loaded', () => {\n jQuery('#saved-credit-card').on('change', () => {\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n });\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n switchBetweenPayPalandOrderButton() {\n jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n\n displayPlaceOrderButtonForSavedCreditCards() {\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n return;\n }\n\n if (jQuery('#saved-credit-card').length && jQuery('#saved-credit-card').val() !== '') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n this.disableCreditCardFields();\n } else {\n jQuery('#place_order').hide();\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n this.enableCreditCardFields();\n }\n }\n\n disableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", true);\n this.renderer.disableCreditCardFields();\n }\n\n enableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", false);\n this.renderer.enableCreditCardFields();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_CheckoutBootstap = (CheckoutBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/PayNowBootstrap.js\n\n\n\nclass PayNowBootstrap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n });\n this.switchBetweenPayPalandOrderButton();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n switchBetweenPayPalandOrderButton() {\n const urlParams = new URLSearchParams(window.location.search);\n\n if (urlParams.has('change_payment_method')) {\n return;\n }\n\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_PayNowBootstrap = (PayNowBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/Renderer.js\nclass Renderer {\n constructor(creditCardRenderer, defaultConfig) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig\n }).render(wrapper);\n }\n\n isAlreadyRendered(wrapper) {\n return document.querySelector(wrapper).hasChildNodes();\n }\n\n hideButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'none';\n return true;\n }\n\n showButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'block';\n return true;\n }\n\n disableCreditCardFields() {\n this.creditCardRenderer.disableFields();\n }\n\n enableCreditCardFields() {\n this.creditCardRenderer.enableFields();\n }\n\n}\n\n/* harmony default export */ const Renderer_Renderer = (Renderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/DccInputFactory.js\nconst dccInputFactory = original => {\n const styles = window.getComputedStyle(original);\n const newElement = document.createElement('span');\n newElement.setAttribute('id', original.id);\n Object.values(styles).forEach(prop => {\n if (!styles[prop] || !isNaN(prop)) {\n return;\n }\n\n newElement.style.setProperty(prop, '' + styles[prop]);\n });\n return newElement;\n};\n\n/* harmony default export */ const DccInputFactory = (dccInputFactory);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/CreditCardRenderer.js\n\n\nclass CreditCardRenderer {\n constructor(defaultConfig, errorHandler, spinner) {\n this.defaultConfig = defaultConfig;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n this.cardValid = false;\n this.formValid = false;\n this.currentHostedFieldsInstance = null;\n this.formSubmissionSubscribed = false;\n }\n\n render(wrapper, contextConfig) {\n if (this.defaultConfig.context !== 'checkout' && this.defaultConfig.context !== 'pay-now' || wrapper === null || document.querySelector(wrapper) === null) {\n return;\n }\n\n if (typeof paypal.HostedFields === 'undefined' || !paypal.HostedFields.isEligible()) {\n const wrapperElement = document.querySelector(wrapper);\n wrapperElement.parentNode.removeChild(wrapperElement);\n return;\n }\n\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.teardown().catch(err => console.error(`Hosted fields teardown error: ${err}`));\n this.currentHostedFieldsInstance = null;\n }\n\n const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');\n const oldDisplayStyle = gateWayBox.style.display;\n gateWayBox.style.display = 'block';\n const hideDccGateway = document.querySelector('#ppcp-hide-dcc');\n\n if (hideDccGateway) {\n hideDccGateway.parentNode.removeChild(hideDccGateway);\n }\n\n const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');\n const stylesRaw = window.getComputedStyle(cardNumberField);\n let styles = {};\n Object.values(stylesRaw).forEach(prop => {\n if (!stylesRaw[prop]) {\n return;\n }\n\n styles[prop] = '' + stylesRaw[prop];\n });\n const cardNumber = DccInputFactory(cardNumberField);\n cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);\n const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');\n const cardExpiry = DccInputFactory(cardExpiryField);\n cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);\n const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');\n const cardCode = DccInputFactory(cardCodeField);\n cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);\n gateWayBox.style.display = oldDisplayStyle;\n const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';\n\n if (this.defaultConfig.enforce_vault && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')) {\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);\n }\n\n paypal.HostedFields.render({\n createOrder: contextConfig.createOrder,\n styles: {\n 'input': styles\n },\n fields: {\n number: {\n selector: '#ppcp-credit-card-gateway-card-number',\n placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number\n },\n cvv: {\n selector: '#ppcp-credit-card-gateway-card-cvc',\n placeholder: this.defaultConfig.hosted_fields.labels.cvv\n },\n expirationDate: {\n selector: '#ppcp-credit-card-gateway-card-expiry',\n placeholder: this.defaultConfig.hosted_fields.labels.mm_yy\n }\n }\n }).then(hostedFields => {\n document.dispatchEvent(new CustomEvent(\"hosted_fields_loaded\"));\n this.currentHostedFieldsInstance = hostedFields;\n hostedFields.on('inputSubmitRequest', () => {\n this._submit(contextConfig);\n });\n hostedFields.on('cardTypeChange', event => {\n if (!event.cards.length) {\n this.cardValid = false;\n return;\n }\n\n const validCards = this.defaultConfig.hosted_fields.valid_cards;\n this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;\n });\n hostedFields.on('validityChange', event => {\n const formValid = Object.keys(event.fields).every(function (key) {\n return event.fields[key].isValid;\n });\n this.formValid = formValid;\n });\n\n if (!this.formSubmissionSubscribed) {\n document.querySelector(wrapper + ' button').addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n this.formSubmissionSubscribed = true;\n }\n });\n document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener('click', () => {\n document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();\n });\n }\n\n disableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.setAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n enableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n _submit(contextConfig) {\n this.spinner.block();\n this.errorHandler.clear();\n\n if (this.formValid && this.cardValid) {\n const save_card = this.defaultConfig.save_card ? true : false;\n const vault = document.getElementById('ppcp-credit-card-vault') ? document.getElementById('ppcp-credit-card-vault').checked : save_card;\n const contingency = this.defaultConfig.hosted_fields.contingency;\n const hostedFieldsData = {\n vault: vault\n };\n\n if (contingency !== 'NO_3D_SECURE') {\n hostedFieldsData.contingencies = [contingency];\n }\n\n this.currentHostedFieldsInstance.submit(hostedFieldsData).then(payload => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n }).catch(err => {\n console.error(err);\n this.spinner.unblock();\n });\n } else {\n this.spinner.unblock();\n const message = !this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;\n this.errorHandler.message(message);\n }\n }\n\n}\n\n/* harmony default export */ const Renderer_CreditCardRenderer = (CreditCardRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/DataClientIdAttributeHandler.js\nconst storageKey = 'ppcp-data-client-id';\n\nconst validateToken = (token, user) => {\n if (!token) {\n return false;\n }\n\n if (token.user !== user) {\n return false;\n }\n\n const currentTime = new Date().getTime();\n const isExpired = currentTime >= token.expiration * 1000;\n return !isExpired;\n};\n\nconst storedTokenForUser = user => {\n const token = JSON.parse(sessionStorage.getItem(storageKey));\n\n if (validateToken(token, user)) {\n return token.token;\n }\n\n return null;\n};\n\nconst storeToken = token => {\n sessionStorage.setItem(storageKey, JSON.stringify(token));\n};\n\nconst dataClientIdAttributeHandler = (script, config) => {\n fetch(config.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: config.nonce\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n const isValid = validateToken(data, config.user);\n\n if (!isValid) {\n return;\n }\n\n storeToken(data);\n script.setAttribute('data-client-token', data.token);\n document.body.append(script);\n });\n};\n\n/* harmony default export */ const DataClientIdAttributeHandler = (dataClientIdAttributeHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/MessageRenderer.js\nclass MessageRenderer {\n constructor(config) {\n this.config = config;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n renderWithAmount(amount) {\n if (!this.shouldRender()) {\n return;\n }\n\n const newWrapper = document.createElement('div');\n newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));\n const sibling = document.querySelector(this.config.wrapper).nextSibling;\n document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));\n sibling.parentElement.insertBefore(newWrapper, sibling);\n paypal.Messages({\n amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n shouldRender() {\n if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined') {\n return false;\n }\n\n if (!document.querySelector(this.config.wrapper)) {\n return false;\n }\n\n return true;\n }\n\n}\n\n/* harmony default export */ const Renderer_MessageRenderer = (MessageRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Spinner.js\nclass Spinner {\n constructor() {\n this.target = 'form.woocommerce-checkout';\n }\n\n setTarget(target) {\n this.target = target;\n }\n\n block() {\n jQuery(this.target).block({\n message: null,\n overlayCSS: {\n background: '#fff',\n opacity: 0.6\n }\n });\n }\n\n unblock() {\n jQuery(this.target).unblock();\n }\n\n}\n\n/* harmony default export */ const Helper_Spinner = (Spinner);\n;// CONCATENATED MODULE: ./resources/js/button.js\n\n\n\n\n\n\n\n\n\n\n\n\nconst bootstrap = () => {\n const errorHandler = new modules_ErrorHandler(PayPalCommerceGateway.labels.error.generic);\n const spinner = new Helper_Spinner();\n const creditCardRenderer = new Renderer_CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway);\n const messageRenderer = new Renderer_MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n\n if (context === 'mini-cart' || context === 'product') {\n if (PayPalCommerceGateway.mini_cart_buttons_enabled === '1') {\n const miniCartBootstrap = new ContextBootstrap_MiniCartBootstap(PayPalCommerceGateway, renderer);\n miniCartBootstrap.init();\n }\n }\n\n if (context === 'product' && PayPalCommerceGateway.single_product_buttons_enabled === '1') {\n const singleProductBootstrap = new ContextBootstrap_SingleProductBootstap(PayPalCommerceGateway, renderer, messageRenderer);\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstap(PayPalCommerceGateway, renderer);\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new ContextBootstrap_CheckoutBootstap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now') {\n const payNowBootstrap = new ContextBootstrap_PayNowBootstrap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (!typeof PayPalCommerceGateway) {\n console.error('PayPal button could not be configured.');\n return;\n }\n\n const script = document.createElement('script');\n script.addEventListener('load', event => {\n bootstrap();\n });\n script.setAttribute('src', PayPalCommerceGateway.button.url);\n Object.entries(PayPalCommerceGateway.script_attributes).forEach(keyValue => {\n script.setAttribute(keyValue[0], keyValue[1]);\n });\n\n if (PayPalCommerceGateway.data_client_id.set_attribute) {\n DataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);\n return;\n }\n\n document.body.append(script);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFBQSxPQUFPLENBQUNDLEtBQVIsQ0FBYyx3Q0FBZDtBQUNBO0FBQ0g7O0FBQ0QsUUFBTWdOLE1BQU0sR0FBR3ZTLFFBQVEsQ0FBQ3dCLGFBQVQsQ0FBdUIsUUFBdkIsQ0FBZjtBQUVBK1EsRUFBQUEsTUFBTSxDQUFDaEMsZ0JBQVAsQ0FBd0IsTUFBeEIsRUFBaUNWLEtBQUQsSUFBVztBQUN2Q3lELElBQUFBLFNBQVM7QUFDWixHQUZEO0FBR0FmLEVBQUFBLE1BQU0sQ0FBQzlRLFlBQVAsQ0FBb0IsS0FBcEIsRUFBMkJxQyxxQkFBcUIsQ0FBQ3NDLE1BQXRCLENBQTZCMk4sR0FBeEQ7QUFDQTVHLEVBQUFBLE1BQU0sQ0FBQzZHLE9BQVAsQ0FBZWxRLHFCQUFxQixDQUFDbVEsaUJBQXJDLEVBQXdEMUwsT0FBeEQsQ0FDSzJMLFFBQUQsSUFBYztBQUNWM0IsSUFBQUEsTUFBTSxDQUFDOVEsWUFBUCxDQUFvQnlTLFFBQVEsQ0FBQyxDQUFELENBQTVCLEVBQWlDQSxRQUFRLENBQUMsQ0FBRCxDQUF6QztBQUNILEdBSEw7O0FBTUEsTUFBSXBRLHFCQUFxQixDQUFDcVEsY0FBdEIsQ0FBcUNDLGFBQXpDLEVBQXdEO0FBQ3BEOUIsSUFBQUEsNEJBQTRCLENBQUNDLE1BQUQsRUFBU3pPLHFCQUFxQixDQUFDcVEsY0FBL0IsQ0FBNUI7QUFDQTtBQUNIOztBQUVEblUsRUFBQUEsUUFBUSxDQUFDNEMsSUFBVCxDQUFjNkgsTUFBZCxDQUFxQjhILE1BQXJCO0FBQ0gsQ0F6QkwiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRXJyb3JIYW5kbGVyLmpzP2U2NWEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanM/YzQ1NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1BheWVyRGF0YS5qcz8yYWYxIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyLmpzPzgyY2YiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcC5qcz9kNTUyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvVXBkYXRlQ2FydC5qcz9lNDIyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyLmpzP2UxOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0VudGl0eS9Qcm9kdWN0LmpzPzlmZmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIuanM/ZDliNyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAuanM/N2MxOSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAuanM/NWU5NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanM/OTMwNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXIuanM/ODUxNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwLmpzP2M4NTUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwLmpzP2Q5ZjUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyLmpzP2ZhOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9EY2NJbnB1dEZhY3RvcnkuanM/MmEyZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyLmpzPzM4N2EiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIuanM/ZWUwYiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyLmpzP2NkMDIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9TcGlubmVyLmpzPzE3MDgiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9idXR0b24uanM/MDYwZiJdLCJzb3VyY2VzQ29udGVudCI6WyJjbGFzcyBFcnJvckhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoZ2VuZXJpY0Vycm9yVGV4dClcbiAgICB7XG4gICAgICAgIHRoaXMuZ2VuZXJpY0Vycm9yVGV4dCA9IGdlbmVyaWNFcnJvclRleHQ7XG4gICAgICAgIHRoaXMud3JhcHBlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53b29jb21tZXJjZS1ub3RpY2VzLXdyYXBwZXInKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd1bC53b29jb21tZXJjZS1lcnJvcicpO1xuICAgIH1cblxuICAgIGdlbmVyaWNFcnJvcigpIHtcbiAgICAgICAgaWYgKHRoaXMud3JhcHBlci5jbGFzc0xpc3QuY29udGFpbnMoJ3BwY3AtcGVyc2lzdCcpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICB0aGlzLm1lc3NhZ2UodGhpcy5nZW5lcmljRXJyb3JUZXh0KVxuICAgIH1cblxuICAgIGFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudChlcnJvck1lc3NhZ2VFbGVtZW50KVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QucmVwbGFjZVdpdGgoZXJyb3JNZXNzYWdlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgbWVzc2FnZSh0ZXh0LCBwZXJzaXN0ID0gZmFsc2UpXG4gICAge1xuICAgICAgICBpZighIHR5cGVvZiBTdHJpbmcgfHwgdGV4dC5sZW5ndGggPT09IDApe1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIG5ldyBtZXNzYWdlIHRleHQgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCl7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwZXJzaXN0KSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmFkZCgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZSgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbWVzc2FnZU5vZGUgPSB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3RJdGVtKHRleHQpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5hcHBlbmRDaGlsZChtZXNzYWdlTm9kZSk7XG5cbiAgICAgICAgalF1ZXJ5LnNjcm9sbF90b19ub3RpY2VzKGpRdWVyeSgnLndvb2NvbW1lcmNlLW5vdGljZXMtd3JhcHBlcicpKVxuICAgIH1cblxuICAgIHByZXBhcmVNZXNzYWdlc0xpc3QoKVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpe1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdjbGFzcycsICd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdyb2xlJywgJ2FsZXJ0Jyk7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuYXBwZW5kQ2hpbGQodGhpcy5tZXNzYWdlc0xpc3QpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0obWVzc2FnZSlcbiAgICB7XG4gICAgICAgIGNvbnN0IGxpID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgICAgbGkuaW5uZXJIVE1MID0gbWVzc2FnZTtcblxuICAgICAgICByZXR1cm4gbGk7XG4gICAgfVxuXG4gICAgc2FuaXRpemUodGV4dClcbiAgICB7XG4gICAgICAgIGNvbnN0IHRleHRhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcbiAgICAgICAgdGV4dGFyZWEuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgcmV0dXJuIHRleHRhcmVhLnZhbHVlLnJlcGxhY2UoJ0Vycm9yOiAnLCAnJyk7XG4gICAgfVxuXG4gICAgY2xlYXIoKVxuICAgIHtcbiAgICAgICAgaWYgKCEgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5jb250YWlucygnd29vY29tbWVyY2UtZXJyb3InKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QucmVtb3ZlKCd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICB0aGlzLndyYXBwZXIuaW5uZXJUZXh0ID0gJyc7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFcnJvckhhbmRsZXI7XG4iLCJjb25zdCBvbkFwcHJvdmUgPSAoY29udGV4dCwgZXJyb3JIYW5kbGVyKSA9PiB7XG4gICAgcmV0dXJuIChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGNvbnRleHQuY29uZmlnLnJlZGlyZWN0O1xuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiZXhwb3J0IGNvbnN0IHBheWVyRGF0YSA9ICgpID0+IHtcbiAgICBjb25zdCBwYXllciA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5wYXllcjtcbiAgICBpZiAoISBwYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwaG9uZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpIHx8IHR5cGVvZiBwYXllci5waG9uZSAhPT0gJ3VuZGVmaW5lZCcpID9cbiAgICB7XG4gICAgICAgIHBob25lX3R5cGU6XCJIT01FXCIsXG4gICAgICAgICAgICBwaG9uZV9udW1iZXI6e1xuICAgICAgICAgICAgbmF0aW9uYWxfbnVtYmVyIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKS52YWx1ZSA6IHBheWVyLnBob25lLnBob25lX251bWJlci5uYXRpb25hbF9udW1iZXJcbiAgICAgICAgfVxuICAgIH0gOiBudWxsO1xuICAgIGNvbnN0IHBheWVyRGF0YSA9IHtcbiAgICAgICAgZW1haWxfYWRkcmVzczooZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpLnZhbHVlIDogcGF5ZXIuZW1haWxfYWRkcmVzcyxcbiAgICAgICAgbmFtZSA6IHtcbiAgICAgICAgICAgIHN1cm5hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuc3VybmFtZSxcbiAgICAgICAgICAgIGdpdmVuX25hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5naXZlbl9uYW1lXG4gICAgICAgIH0sXG4gICAgICAgIGFkZHJlc3MgOiB7XG4gICAgICAgICAgICBjb3VudHJ5X2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuY291bnRyeV9jb2RlLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8xLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8yLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8xLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMixcbiAgICAgICAgICAgIHBvc3RhbF9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MucG9zdGFsX2NvZGVcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAocGhvbmUpIHtcbiAgICAgICAgcGF5ZXJEYXRhLnBob25lID0gcGhvbmU7XG4gICAgfVxuICAgIHJldHVybiBwYXllckRhdGE7XG59XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENhcnRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOiBvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIpLFxuICAgICAgICAgICAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgTWluaUNhcnRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbignd2NfZnJhZ21lbnRzX2xvYWRlZCB3Y19mcmFnbWVudHNfcmVmcmVzaGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcikgIT09XG4gICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKVxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWluaUNhcnRCb290c3RhcDsiLCJpbXBvcnQgUHJvZHVjdCBmcm9tIFwiLi4vRW50aXR5L1Byb2R1Y3RcIjtcbmNsYXNzIFVwZGF0ZUNhcnQge1xuXG4gICAgY29uc3RydWN0b3IoZW5kcG9pbnQsIG5vbmNlKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludCA9IGVuZHBvaW50O1xuICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25SZXNvbHZlXG4gICAgICogQHBhcmFtIHtQcm9kdWN0W119IHByb2R1Y3RzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAgICovXG4gICAgdXBkYXRlKG9uUmVzb2x2ZSwgcHJvZHVjdHMpXG4gICAge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZmV0Y2goXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qc29uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gb25SZXNvbHZlKHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVcGRhdGVDYXJ0OyIsIi8qKlxuICogV2hlbiB5b3UgY2FuJ3QgYWRkIHNvbWV0aGluZyB0byB0aGUgY2FydCwgdGhlIFBheVBhbCBidXR0b25zIHNob3VsZCBub3Qgc2hvdy5cbiAqIFRoZXJlZm9yZSB3ZSBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiBhbmQgc2hvdy9oaWRlIHRoZSBidXR0b25zIGFjY29yZGluZ2x5LlxuICovXG5cbmNsYXNzIEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2hvd0NhbGxiYWNrLCBoaWRlQ2FsbGJhY2spXG4gICAge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnNob3dDYWxsYmFjayA9IHNob3dDYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2sgPSBoaWRlQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKVxuICAgIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0geyBhdHRyaWJ1dGVzIDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNob3dDYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgZGlzY29ubmVjdCgpXG4gICAge1xuICAgICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcjsiLCJjbGFzcyBQcm9kdWN0IHtcblxuICAgIGNvbnN0cnVjdG9yKGlkLCBxdWFudGl0eSwgdmFyaWF0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMucXVhbnRpdHkgPSBxdWFudGl0eTtcbiAgICAgICAgdGhpcy52YXJpYXRpb25zID0gdmFyaWF0aW9ucztcbiAgICB9XG5cbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6dGhpcy5pZCxcbiAgICAgICAgICAgIHF1YW50aXR5OnRoaXMucXVhbnRpdHksXG4gICAgICAgICAgICB2YXJpYXRpb25zOnRoaXMudmFyaWF0aW9uc1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0OyIsImltcG9ydCBCdXR0b25zVG9nZ2xlTGlzdGVuZXIgZnJvbSAnLi4vSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lcic7XG5pbXBvcnQgUHJvZHVjdCBmcm9tICcuLi9FbnRpdHkvUHJvZHVjdCc7XG5pbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHVwZGF0ZUNhcnQsXG4gICAgICAgIHNob3dCdXR0b25DYWxsYmFjayxcbiAgICAgICAgaGlkZUJ1dHRvbkNhbGxiYWNrLFxuICAgICAgICBmb3JtRWxlbWVudCxcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhcnQgPSB1cGRhdGVDYXJ0O1xuICAgICAgICB0aGlzLnNob3dCdXR0b25DYWxsYmFjayA9IHNob3dCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2sgPSBoaWRlQnV0dG9uQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnQgPSBmb3JtRWxlbWVudDtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpXG4gICAge1xuXG4gICAgICAgIGlmICggdGhpcy5oYXNWYXJpYXRpb25zKCkgKSB7XG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlX2FkZF90b19jYXJ0X2J1dHRvbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUJ1dHRvbkNhbGxiYWNrXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuaW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiB0aGlzLmNyZWF0ZU9yZGVyKCksXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU9yZGVyKClcbiAgICB7XG4gICAgICAgIHZhciBnZXRQcm9kdWN0cyA9IG51bGw7XG4gICAgICAgIGlmICghIHRoaXMuaXNHcm91cGVkUHJvZHVjdCgpICkge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cImFkZC10by1jYXJ0XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcXR5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25hbWU9XCJxdWFudGl0eVwiXScpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhdGlvbnMgPSB0aGlzLnZhcmlhdGlvbnMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBQcm9kdWN0KGlkLCBxdHksIHZhcmlhdGlvbnMpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFByb2R1Y3RzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwibnVtYmVyXCJdJykuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBlbGVtZW50LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpLm1hdGNoKC9xdWFudGl0eVxcWyhbXFxkXSopXFxdLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50TmFtZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHBhcnNlSW50KGVsZW1lbnROYW1lWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMucHVzaChuZXcgUHJvZHVjdChpZCwgcXVhbnRpdHksIG51bGwpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICBjb25zdCBvblJlc29sdmUgPSAocHVyY2hhc2VfdW5pdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnVwZGF0ZUNhcnQudXBkYXRlKG9uUmVzb2x2ZSwgZ2V0UHJvZHVjdHMoKSk7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU9yZGVyO1xuICAgIH1cblxuICAgIHZhcmlhdGlvbnMoKVxuICAgIHtcblxuICAgICAgICBpZiAoISB0aGlzLmhhc1ZhcmlhdGlvbnMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFsuLi50aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZV49J2F0dHJpYnV0ZV8nXVwiKV0ubWFwKFxuICAgICAgICAgICAgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOmVsZW1lbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ZWxlbWVudC5uYW1lXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICBoYXNWYXJpYXRpb25zKClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygndmFyaWF0aW9uc19mb3JtJyk7XG4gICAgfVxuXG4gICAgaXNHcm91cGVkUHJvZHVjdCgpXG4gICAge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyb3VwZWRfZm9ybScpO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhcnQgZnJvbSBcIi4uL0hlbHBlci9VcGRhdGVDYXJ0XCI7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIgZnJvbSBcIi4uL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXJcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXksXG4gICAgICAgICAgICBuZXcgVXBkYXRlQ2FydChcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5ub25jZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgbGV0IHByaWNlVGV4dCA9IFwiMFwiO1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlSW50KHByaWNlVGV4dC5yZXBsYWNlKC8oW15cXGQsXFwuXFxzXSopL2csICcnKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXJXaXRoQW1vdW50KGFtb3VudClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JyksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXA7IiwiaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuXG5jbGFzcyBDYXJ0Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscyB1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0Qm9vdHN0cmFwO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICBzcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmNvZGUgPT09IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbnMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhY3Rpb25zLnJlc3RhcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwbGFjZV9vcmRlcicpLmNsaWNrKClcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENoZWNrb3V0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMuc3Bpbm5lcjtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IHRoaXMuZXJyb3JIYW5kbGVyO1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtU2VsZWN0b3IgPSB0aGlzLmNvbmZpZy5jb250ZXh0ID09PSAnY2hlY2tvdXQnID8gJ2Zvcm0uY2hlY2tvdXQnIDogJ2Zvcm0jb3JkZXJfcmV2aWV3JztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSBqUXVlcnkoZm9ybVNlbGVjdG9yKS5zZXJpYWxpemUoKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlYWNjb3VudCA9IGpRdWVyeSgnI2NyZWF0ZWFjY291bnQnKS5pcyhcIjpjaGVja2VkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyX2lkOnRoaXMuY29uZmlnLm9yZGVyX2lkLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOmZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWFjY291bnQ6IGNyZWF0ZWFjY291bnRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vaGFuZGxlIGJvdGggbWVzc2FnZXMgc2VudCBmcm9tIFdvb2NvbW1lcmNlIChkYXRhLm1lc3NhZ2VzKSBhbmQgdGhpcyBwbHVnaW4gKGRhdGEuZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKGRhdGEubWVzc2FnZXMpICE9PSAndW5kZWZpbmVkJyApXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5hcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhkYXRhLm1lc3NhZ2VzLCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJ3VsJylcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3BwY3AtcmVzdW1lLW9yZGVyJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGRhdGEuZGF0YS5wdXJjaGFzZV91bml0c1swXS5jdXN0b21faWQpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVNlbGVjdG9yKS5hcHBlbmQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6b25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyLCB0aGlzLnNwaW5uZXIpLFxuICAgICAgICAgICAgb25DYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDaGVja291dEFjdGlvbkhhbmRsZXIgZnJvbSAnLi4vQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXInO1xuXG5jbGFzcyBDaGVja291dEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKClcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLlxuICAgICAgICAgIG9uKCd1cGRhdGVkX2NoZWNrb3V0IHBheW1lbnRfbWV0aG9kX3NlbGVjdGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpXG4gICAgICAgICAgICAgIHRoaXMuZGlzcGxheVBsYWNlT3JkZXJCdXR0b25Gb3JTYXZlZENyZWRpdENhcmRzKClcblxuICAgICAgICAgIH0pXG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50KS5vbignaG9zdGVkX2ZpZWxkc19sb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKVxuICAgICAgICB0aGlzLmRpc3BsYXlQbGFjZU9yZGVyQnV0dG9uRm9yU2F2ZWRDcmVkaXRDYXJkcygpXG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLmNhbmNlbF93cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKSAhPT0gbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PSBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2JykpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2Jykuc2V0QXR0cmlidXRlKCdzdHlsZScsICcnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IENoZWNrb3V0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpIHtcbiAgICAgICAgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQgb3B0aW9uOmZpcnN0JykudmFsKCkpO1xuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICAgJ2lucHV0W25hbWU9XCJwYXltZW50X21ldGhvZFwiXTpjaGVja2VkJykudmFsKCk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kICE9PSAncHBjcC1nYXRld2F5JyAmJiBjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgalF1ZXJ5KCcjcGxhY2Vfb3JkZXInKS5oaWRlKCk7XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyKClcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS5sZW5ndGggJiYgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoKSAhPT0gJycpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcilcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpXG4gICAgICAgICAgICB0aGlzLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLmVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgZmFsc2UpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEJvb3RzdGFwXG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2hlY2tvdXRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgUGF5Tm93Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5cbiAgICAgICAgb24oJ3VwZGF0ZWRfY2hlY2tvdXQgcGF5bWVudF9tZXRob2Rfc2VsZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24uY2FuY2VsX3dyYXBwZXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PSBudWxsIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcikgIT09IG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKSkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICAgICAgdGhpcy5zcGlubmVyXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgc3dpdGNoQmV0d2VlblBheVBhbGFuZE9yZGVyQnV0dG9uKCkge1xuICAgICAgICBjb25zdCB1cmxQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpXG4gICAgICAgIGlmICh1cmxQYXJhbXMuaGFzKCdjaGFuZ2VfcGF5bWVudF9tZXRob2QnKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IGpRdWVyeShcbiAgICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuXG4gICAgICAgIGlmIChjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtZ2F0ZXdheScgJiYgY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICBqUXVlcnkoJyNwbGFjZV9vcmRlcicpLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kID09PSAncHBjcC1nYXRld2F5Jykge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnJlbmRlcigpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBheU5vd0Jvb3RzdHJhcDtcbiIsImNsYXNzIFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihjcmVkaXRDYXJkUmVuZGVyZXIsIGRlZmF1bHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIgPSBjcmVkaXRDYXJkUmVuZGVyZXI7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICB0aGlzLnJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLnJlbmRlcihob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICB9XG5cbiAgICByZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSB8fCB0aGlzLmlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHx8ICd1bmRlZmluZWQnID09PSB0eXBlb2YgcGF5cGFsLkJ1dHRvbnMgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdHlsZSA9IHdyYXBwZXIgPT09IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ud3JhcHBlciA/IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24uc3R5bGUgOiB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLm1pbmlfY2FydF9zdHlsZTtcbiAgICAgICAgcGF5cGFsLkJ1dHRvbnMoe1xuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAuLi5jb250ZXh0Q29uZmlnLFxuICAgICAgICB9KS5yZW5kZXIod3JhcHBlcik7XG4gICAgfVxuXG4gICAgaXNBbHJlYWR5UmVuZGVyZWQod3JhcHBlcikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5oYXNDaGlsZE5vZGVzKCk7XG4gICAgfVxuXG4gICAgaGlkZUJ1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHNob3dCdXR0b25zKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgICAgIGlmICghIGRvbUVsZW1lbnQgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZG9tRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmRpc2FibGVGaWVsZHMoKTtcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5lbmFibGVGaWVsZHMoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlcmVyO1xuIiwiY29uc3QgZGNjSW5wdXRGYWN0b3J5ID0gKG9yaWdpbmFsKSA9PiB7XG4gICAgY29uc3Qgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUob3JpZ2luYWwpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2lkJywgb3JpZ2luYWwuaWQpO1xuICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzKS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICBpZiAoISBzdHlsZXNbcHJvcF0gfHwgISBpc05hTihwcm9wKSApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBuZXdFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KHByb3AsJycgKyBzdHlsZXNbcHJvcF0pO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBkY2NJbnB1dEZhY3Rvcnk7IiwiaW1wb3J0IGRjY0lucHV0RmFjdG9yeSBmcm9tIFwiLi4vSGVscGVyL0RjY0lucHV0RmFjdG9yeVwiO1xuXG5jbGFzcyBDcmVkaXRDYXJkUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoZGVmYXVsdENvbmZpZywgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmNvbnRleHQgIT09ICdjaGVja291dCdcbiAgICAgICAgICAgICAgICAmJiB0aGlzLmRlZmF1bHRDb25maWcuY29udGV4dCAhPT0gJ3BheS1ub3cnXG4gICAgICAgICAgICApXG4gICAgICAgICAgICB8fCB3cmFwcGVyID09PSBudWxsXG4gICAgICAgICAgICB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpID09PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYXlwYWwuSG9zdGVkRmllbGRzID09PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgfHwgISBwYXlwYWwuSG9zdGVkRmllbGRzLmlzRWxpZ2libGUoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZXJFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKTtcbiAgICAgICAgICAgIHdyYXBwZXJFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQod3JhcHBlckVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS50ZWFyZG93bigpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmVycm9yKGBIb3N0ZWQgZmllbGRzIHRlYXJkb3duIGVycm9yOiAke2Vycn1gKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBnYXRlV2F5Qm94ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBheW1lbnRfYm94LnBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpO1xuICAgICAgICBjb25zdCBvbGREaXNwbGF5U3R5bGUgPSBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXk7XG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgICAgY29uc3QgaGlkZURjY0dhdGV3YXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1oaWRlLWRjYycpO1xuICAgICAgICBpZiAoaGlkZURjY0dhdGV3YXkpIHtcbiAgICAgICAgICAgIGhpZGVEY2NHYXRld2F5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaGlkZURjY0dhdGV3YXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlckZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpO1xuXG4gICAgICAgIGNvbnN0IHN0eWxlc1JhdyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNhcmROdW1iZXJGaWVsZCk7XG4gICAgICAgIGxldCBzdHlsZXMgPSB7fTtcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzdHlsZXNSYXcpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgICAgICBpZiAoISBzdHlsZXNSYXdbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHlsZXNbcHJvcF0gPSAnJyArIHN0eWxlc1Jhd1twcm9wXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlciA9IGRjY0lucHV0RmFjdG9yeShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBjYXJkTnVtYmVyRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZE51bWJlciwgY2FyZE51bWJlckZpZWxkKTtcblxuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5RmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5Jyk7XG4gICAgICAgIGNvbnN0IGNhcmRFeHBpcnkgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZEV4cGlyeUZpZWxkKTtcbiAgICAgICAgY2FyZEV4cGlyeUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRFeHBpcnksIGNhcmRFeHBpcnlGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZENvZGVGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKTtcbiAgICAgICAgY29uc3QgY2FyZENvZGUgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZENvZGVGaWVsZCk7XG4gICAgICAgIGNhcmRDb2RlRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZENvZGUsIGNhcmRDb2RlRmllbGQpO1xuXG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9IG9sZERpc3BsYXlTdHlsZTtcblxuICAgICAgICBjb25zdCBmb3JtV3JhcHBlciA9ICcucGF5bWVudF9ib3ggcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHRcbiAgICAgICAgICAgICYmIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0JylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5cGFsLkhvc3RlZEZpZWxkcy5yZW5kZXIoe1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IGNvbnRleHRDb25maWcuY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBzdHlsZXM6IHtcbiAgICAgICAgICAgICAgICAnaW5wdXQnOiBzdHlsZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICAgICAgICBudW1iZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jcmVkaXRfY2FyZF9udW1iZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjdnY6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jdnYsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBleHBpcmF0aW9uRGF0ZToge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLm1tX3l5LFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkudGhlbihob3N0ZWRGaWVsZHMgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJob3N0ZWRfZmllbGRzX2xvYWRlZFwiKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IGhvc3RlZEZpZWxkcztcblxuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdpbnB1dFN1Ym1pdFJlcXVlc3QnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ2NhcmRUeXBlQ2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCAhIGV2ZW50LmNhcmRzLmxlbmd0aCApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZENhcmRzID0gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMudmFsaWRfY2FyZHM7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSB2YWxpZENhcmRzLmluZGV4T2YoZXZlbnQuY2FyZHNbMF0udHlwZSkgIT09IC0xO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbigndmFsaWRpdHlDaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtVmFsaWQgPSBPYmplY3Qua2V5cyhldmVudC5maWVsZHMpLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmZpZWxkc1trZXldLmlzVmFsaWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZvcm1WYWxpZDtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5mb3JtU3VibWlzc2lvblN1YnNjcmliZWQpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIgKyAnIGJ1dHRvbicpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdWJtaXQoY29udGV4dENvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2xhYmVsW2Zvcj1wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJdJykuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgIH1cblxuICAgIGRpc2FibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmFibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc3VibWl0KGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5zcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZm9ybVZhbGlkICYmIHRoaXMuY2FyZFZhbGlkKSB7XG4gICAgICAgICAgICBjb25zdCBzYXZlX2NhcmQgPSB0aGlzLmRlZmF1bHRDb25maWcuc2F2ZV9jYXJkID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICAgICAgY29uc3QgdmF1bHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpID9cbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgOiBzYXZlX2NhcmQ7XG4gICAgICAgICAgICBjb25zdCBjb250aW5nZW5jeSA9IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmNvbnRpbmdlbmN5O1xuICAgICAgICAgICAgY29uc3QgaG9zdGVkRmllbGRzRGF0YSA9IHtcbiAgICAgICAgICAgICAgICB2YXVsdDogdmF1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoY29udGluZ2VuY3kgIT09ICdOT18zRF9TRUNVUkUnKSB7XG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jb250aW5nZW5jaWVzID0gW2NvbnRpbmdlbmN5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnN1Ym1pdChob3N0ZWRGaWVsZHNEYXRhKS50aGVuKChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgcGF5bG9hZC5vcmRlcklEID0gcGF5bG9hZC5vcmRlcklkO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRDb25maWcub25BcHByb3ZlKHBheWxvYWQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSAhIHRoaXMuY2FyZFZhbGlkID8gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNhcmRfbm90X3N1cHBvcnRlZCA6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5maWVsZHNfbm90X3ZhbGlkO1xuICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IENyZWRpdENhcmRSZW5kZXJlcjtcbiIsImNvbnN0IHN0b3JhZ2VLZXkgPSAncHBjcC1kYXRhLWNsaWVudC1pZCc7XG5cbmNvbnN0IHZhbGlkYXRlVG9rZW4gPSAodG9rZW4sIHVzZXIpID0+IHtcbiAgICBpZiAoISB0b2tlbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0b2tlbi51c2VyICE9PSB1c2VyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBpc0V4cGlyZWQgPSBjdXJyZW50VGltZSA+PSB0b2tlbi5leHBpcmF0aW9uICogMTAwMDtcbiAgICByZXR1cm4gISBpc0V4cGlyZWQ7XG59XG5cbmNvbnN0IHN0b3JlZFRva2VuRm9yVXNlciA9ICh1c2VyKSA9PiB7XG4gICAgY29uc3QgdG9rZW4gPSBKU09OLnBhcnNlKHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oc3RvcmFnZUtleSkpO1xuICAgIGlmICh2YWxpZGF0ZVRva2VuKHRva2VuLCB1c2VyKSkge1xuICAgICAgICByZXR1cm4gdG9rZW4udG9rZW47XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBzdG9yZVRva2VuID0gKHRva2VuKSA9PiB7XG4gICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeSh0b2tlbikpO1xufVxuXG5jb25zdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyID0gKHNjcmlwdCwgY29uZmlnKSA9PiB7XG4gICAgZmV0Y2goY29uZmlnLmVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBub25jZTogY29uZmlnLm5vbmNlXG4gICAgICAgIH0pXG4gICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICB9KS50aGVuKChkYXRhKT0+e1xuICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdGVUb2tlbihkYXRhLCBjb25maWcudXNlcik7XG4gICAgICAgIGlmICghaXNWYWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0b3JlVG9rZW4oZGF0YSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtY2xpZW50LXRva2VuJywgZGF0YS50b2tlbik7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKHNjcmlwdCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXI7XG4iLCJjbGFzcyBNZXNzYWdlUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGF5cGFsLk1lc3NhZ2VzKHtcbiAgICAgICAgICAgIGFtb3VudDogdGhpcy5jb25maWcuYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHJlbmRlcldpdGhBbW91bnQoYW1vdW50KSB7XG5cbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3V3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBuZXdXcmFwcGVyLnNldEF0dHJpYnV0ZSgnaWQnLCB0aGlzLmNvbmZpZy53cmFwcGVyLnJlcGxhY2UoJyMnLCAnJykpO1xuXG4gICAgICAgIGNvbnN0IHNpYmxpbmcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLm5leHRTaWJsaW5nO1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSk7XG4gICAgICAgIHNpYmxpbmcucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUobmV3V3JhcHBlciwgc2libGluZyk7XG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgICBwbGFjZW1lbnQ6IHRoaXMuY29uZmlnLnBsYWNlbWVudCxcbiAgICAgICAgICAgIHN0eWxlOiB0aGlzLmNvbmZpZy5zdHlsZVxuICAgICAgICB9KS5yZW5kZXIodGhpcy5jb25maWcud3JhcHBlcik7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuXG4gICAgICAgIGlmICh0eXBlb2YgcGF5cGFsLk1lc3NhZ2VzID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgdGhpcy5jb25maWcud3JhcHBlciA9PT0gJ3VuZGVmaW5lZCcgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IE1lc3NhZ2VSZW5kZXJlcjsiLCJjbGFzcyBTcGlubmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnRhcmdldCA9ICdmb3JtLndvb2NvbW1lcmNlLWNoZWNrb3V0JztcbiAgICB9XG5cbiAgICBzZXRUYXJnZXQodGFyZ2V0KSB7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIH1cblxuICAgIGJsb2NrKCkge1xuXG4gICAgICAgIGpRdWVyeSggdGhpcy50YXJnZXQgKS5ibG9jayh7XG4gICAgICAgICAgICBtZXNzYWdlOiBudWxsLFxuICAgICAgICAgICAgb3ZlcmxheUNTUzoge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjZcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdW5ibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkudW5ibG9jaygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgU3Bpbm5lcjtcbiIsImltcG9ydCBNaW5pQ2FydEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL01pbmlDYXJ0Qm9vdHN0YXAnO1xuaW1wb3J0IFNpbmdsZVByb2R1Y3RCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAnO1xuaW1wb3J0IENhcnRCb290c3RyYXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2FydEJvb3RzdGFwJztcbmltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAnO1xuaW1wb3J0IFBheU5vd0Jvb3RzdHJhcCBmcm9tIFwiLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwXCI7XG5pbXBvcnQgUmVuZGVyZXIgZnJvbSAnLi9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyJztcbmltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi9tb2R1bGVzL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ3JlZGl0Q2FyZFJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyXCI7XG5pbXBvcnQgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciBmcm9tIFwiLi9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXJcIjtcbmltcG9ydCBNZXNzYWdlUmVuZGVyZXIgZnJvbSBcIi4vbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXJcIjtcbmltcG9ydCBTcGlubmVyIGZyb20gXCIuL21vZHVsZXMvSGVscGVyL1NwaW5uZXJcIjtcblxuY29uc3QgYm9vdHN0cmFwID0gKCkgPT4ge1xuICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IG5ldyBFcnJvckhhbmRsZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKTtcbiAgICBjb25zdCBzcGlubmVyID0gbmV3IFNwaW5uZXIoKTtcbiAgICBjb25zdCBjcmVkaXRDYXJkUmVuZGVyZXIgPSBuZXcgQ3JlZGl0Q2FyZFJlbmRlcmVyKFBheVBhbENvbW1lcmNlR2F0ZXdheSwgZXJyb3JIYW5kbGVyLCBzcGlubmVyKTtcbiAgICBjb25zdCByZW5kZXJlciA9IG5ldyBSZW5kZXJlcihjcmVkaXRDYXJkUmVuZGVyZXIsIFBheVBhbENvbW1lcmNlR2F0ZXdheSk7XG4gICAgY29uc3QgbWVzc2FnZVJlbmRlcmVyID0gbmV3IE1lc3NhZ2VSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXkubWVzc2FnZXMpO1xuICAgIGNvbnN0IGNvbnRleHQgPSBQYXlQYWxDb21tZXJjZUdhdGV3YXkuY29udGV4dDtcbiAgICBpZiAoY29udGV4dCA9PT0gJ21pbmktY2FydCcgfHwgY29udGV4dCA9PT0gJ3Byb2R1Y3QnKSB7XG4gICAgICAgIGlmIChQYXlQYWxDb21tZXJjZUdhdGV3YXkubWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgICAgICBjb25zdCBtaW5pQ2FydEJvb3RzdHJhcCA9IG5ldyBNaW5pQ2FydEJvb3RzdGFwKFxuICAgICAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgICAgICByZW5kZXJlclxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgbWluaUNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdwcm9kdWN0JyAmJiBQYXlQYWxDb21tZXJjZUdhdGV3YXkuc2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkID09PSAnMScpIHtcbiAgICAgICAgY29uc3Qgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcCA9IG5ldyBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBzaW5nbGVQcm9kdWN0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NhcnQnKSB7XG4gICAgICAgIGNvbnN0IGNhcnRCb290c3RyYXAgPSBuZXcgQ2FydEJvb3RzdHJhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICApO1xuXG4gICAgICAgIGNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAnY2hlY2tvdXQnKSB7XG4gICAgICAgIGNvbnN0IGNoZWNrb3V0Qm9vdHN0YXAgPSBuZXcgQ2hlY2tvdXRCb290c3RhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICAgICAgbWVzc2FnZVJlbmRlcmVyLFxuICAgICAgICAgICAgc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIGNoZWNrb3V0Qm9vdHN0YXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncGF5LW5vdycgKSB7XG4gICAgICAgIGNvbnN0IHBheU5vd0Jvb3RzdHJhcCA9IG5ldyBQYXlOb3dCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcbiAgICAgICAgcGF5Tm93Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCAhPT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBtZXNzYWdlUmVuZGVyZXIucmVuZGVyKCk7XG4gICAgfVxufTtcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgJ0RPTUNvbnRlbnRMb2FkZWQnLFxuICAgICgpID0+IHtcbiAgICAgICAgaWYgKCF0eXBlb2YgKFBheVBhbENvbW1lcmNlR2F0ZXdheSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1BheVBhbCBidXR0b24gY291bGQgbm90IGJlIGNvbmZpZ3VyZWQuJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cbiAgICAgICAgc2NyaXB0LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGJvb3RzdHJhcCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgc2NyaXB0LnNldEF0dHJpYnV0ZSgnc3JjJywgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmJ1dHRvbi51cmwpO1xuICAgICAgICBPYmplY3QuZW50cmllcyhQYXlQYWxDb21tZXJjZUdhdGV3YXkuc2NyaXB0X2F0dHJpYnV0ZXMpLmZvckVhY2goXG4gICAgICAgICAgICAoa2V5VmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKGtleVZhbHVlWzBdLCBrZXlWYWx1ZVsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZC5zZXRfYXR0cmlidXRlKSB7XG4gICAgICAgICAgICBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyKHNjcmlwdCwgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKHNjcmlwdCk7XG4gICAgfSxcbik7XG4iXSwibmFtZXMiOlsiRXJyb3JIYW5kbGVyIiwiY29uc3RydWN0b3IiLCJnZW5lcmljRXJyb3JUZXh0Iiwid3JhcHBlciIsImRvY3VtZW50IiwicXVlcnlTZWxlY3RvciIsIm1lc3NhZ2VzTGlzdCIsImdlbmVyaWNFcnJvciIsImNsYXNzTGlzdCIsImNvbnRhaW5zIiwiY2xlYXIiLCJtZXNzYWdlIiwiYXBwZW5kUHJlcGFyZWRFcnJvck1lc3NhZ2VFbGVtZW50IiwiZXJyb3JNZXNzYWdlRWxlbWVudCIsInByZXBhcmVNZXNzYWdlc0xpc3QiLCJyZXBsYWNlV2l0aCIsInRleHQiLCJwZXJzaXN0IiwiU3RyaW5nIiwibGVuZ3RoIiwiRXJyb3IiLCJhZGQiLCJyZW1vdmUiLCJtZXNzYWdlTm9kZSIsInByZXBhcmVNZXNzYWdlc0xpc3RJdGVtIiwiYXBwZW5kQ2hpbGQiLCJqUXVlcnkiLCJzY3JvbGxfdG9fbm90aWNlcyIsImNyZWF0ZUVsZW1lbnQiLCJzZXRBdHRyaWJ1dGUiLCJsaSIsImlubmVySFRNTCIsInNhbml0aXplIiwidGV4dGFyZWEiLCJ2YWx1ZSIsInJlcGxhY2UiLCJpbm5lclRleHQiLCJvbkFwcHJvdmUiLCJjb250ZXh0IiwiZXJyb3JIYW5kbGVyIiwiZGF0YSIsImFjdGlvbnMiLCJmZXRjaCIsImNvbmZpZyIsImFqYXgiLCJhcHByb3ZlX29yZGVyIiwiZW5kcG9pbnQiLCJtZXRob2QiLCJib2R5IiwiSlNPTiIsInN0cmluZ2lmeSIsIm5vbmNlIiwib3JkZXJfaWQiLCJvcmRlcklEIiwidGhlbiIsInJlcyIsImpzb24iLCJzdWNjZXNzIiwicmVzdGFydCIsImNhdGNoIiwiZXJyIiwibG9jYXRpb24iLCJocmVmIiwicmVkaXJlY3QiLCJwYXllckRhdGEiLCJwYXllciIsIlBheVBhbENvbW1lcmNlR2F0ZXdheSIsInBob25lIiwicGhvbmVfdHlwZSIsInBob25lX251bWJlciIsIm5hdGlvbmFsX251bWJlciIsImVtYWlsX2FkZHJlc3MiLCJuYW1lIiwic3VybmFtZSIsImdpdmVuX25hbWUiLCJhZGRyZXNzIiwiY291bnRyeV9jb2RlIiwiYWRkcmVzc19saW5lXzEiLCJhZGRyZXNzX2xpbmVfMiIsImFkbWluX2FyZWFfMSIsImFkbWluX2FyZWFfMiIsInBvc3RhbF9jb2RlIiwiQ2FydEFjdGlvbkhhbmRsZXIiLCJjb25maWd1cmF0aW9uIiwiY3JlYXRlT3JkZXIiLCJibkNvZGUiLCJibl9jb2RlcyIsImNyZWF0ZV9vcmRlciIsInB1cmNoYXNlX3VuaXRzIiwiYm5fY29kZSIsImNvbnNvbGUiLCJlcnJvciIsImlkIiwib25FcnJvciIsIk1pbmlDYXJ0Qm9vdHN0YXAiLCJnYXRld2F5IiwicmVuZGVyZXIiLCJhY3Rpb25IYW5kbGVyIiwiaW5pdCIsImxhYmVscyIsImdlbmVyaWMiLCJyZW5kZXIiLCJvbiIsInNob3VsZFJlbmRlciIsImJ1dHRvbiIsIm1pbmlfY2FydF93cmFwcGVyIiwiaG9zdGVkX2ZpZWxkcyIsIlByb2R1Y3QiLCJVcGRhdGVDYXJ0IiwidXBkYXRlIiwib25SZXNvbHZlIiwicHJvZHVjdHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlc3VsdCIsInJlc29sdmVkIiwiQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIiwiZWxlbWVudCIsInNob3dDYWxsYmFjayIsImhpZGVDYWxsYmFjayIsIm9ic2VydmVyIiwiYXR0cmlidXRlcyIsImNhbGxiYWNrIiwiTXV0YXRpb25PYnNlcnZlciIsIm9ic2VydmUiLCJkaXNjb25uZWN0IiwicXVhbnRpdHkiLCJ2YXJpYXRpb25zIiwiU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIiLCJ1cGRhdGVDYXJ0Iiwic2hvd0J1dHRvbkNhbGxiYWNrIiwiaGlkZUJ1dHRvbkNhbGxiYWNrIiwiZm9ybUVsZW1lbnQiLCJoYXNWYXJpYXRpb25zIiwiZ2V0UHJvZHVjdHMiLCJpc0dyb3VwZWRQcm9kdWN0IiwicXR5IiwicXVlcnlTZWxlY3RvckFsbCIsImZvckVhY2giLCJlbGVtZW50TmFtZSIsImdldEF0dHJpYnV0ZSIsIm1hdGNoIiwicGFyc2VJbnQiLCJwdXNoIiwicHJvbWlzZSIsIm1hcCIsIlNpbmdsZVByb2R1Y3RCb290c3RhcCIsIm1lc3NhZ2VzIiwiaGlkZUJ1dHRvbnMiLCJjaGFuZ2VfY2FydCIsInNob3dCdXR0b25zIiwicHJpY2VUZXh0IiwiYW1vdW50IiwicmVuZGVyV2l0aEFtb3VudCIsIkNhcnRCb290c3RyYXAiLCJzcGlubmVyIiwiYmxvY2siLCJ1bmJsb2NrIiwiY29kZSIsImNsaWNrIiwiQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIiwiZm9ybVNlbGVjdG9yIiwiZm9ybVZhbHVlcyIsInNlcmlhbGl6ZSIsImNyZWF0ZWFjY291bnQiLCJpcyIsImZvcm0iLCJkb21QYXJzZXIiLCJET01QYXJzZXIiLCJwYXJzZUZyb21TdHJpbmciLCJpbnB1dCIsImN1c3RvbV9pZCIsImFwcGVuZCIsIm9uQ2FuY2VsIiwiQ2hlY2tvdXRCb290c3RhcCIsInN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbiIsImRpc3BsYXlQbGFjZU9yZGVyQnV0dG9uRm9yU2F2ZWRDcmVkaXRDYXJkcyIsImNhbmNlbF93cmFwcGVyIiwidmFsIiwiY3VycmVudFBheW1lbnRNZXRob2QiLCJzaG93IiwiaGlkZSIsImRpc2FibGVDcmVkaXRDYXJkRmllbGRzIiwiZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcyIsImFkZENsYXNzIiwiYXR0ciIsInJlbW92ZUNsYXNzIiwiUGF5Tm93Qm9vdHN0cmFwIiwidXJsUGFyYW1zIiwiVVJMU2VhcmNoUGFyYW1zIiwid2luZG93Iiwic2VhcmNoIiwiaGFzIiwiUmVuZGVyZXIiLCJjcmVkaXRDYXJkUmVuZGVyZXIiLCJkZWZhdWx0Q29uZmlnIiwiaG9zdGVkRmllbGRzV3JhcHBlciIsImNvbnRleHRDb25maWciLCJyZW5kZXJCdXR0b25zIiwiaXNBbHJlYWR5UmVuZGVyZWQiLCJwYXlwYWwiLCJCdXR0b25zIiwic3R5bGUiLCJtaW5pX2NhcnRfc3R5bGUiLCJoYXNDaGlsZE5vZGVzIiwiZG9tRWxlbWVudCIsImRpc3BsYXkiLCJkaXNhYmxlRmllbGRzIiwiZW5hYmxlRmllbGRzIiwiZGNjSW5wdXRGYWN0b3J5Iiwib3JpZ2luYWwiLCJzdHlsZXMiLCJnZXRDb21wdXRlZFN0eWxlIiwibmV3RWxlbWVudCIsIk9iamVjdCIsInZhbHVlcyIsInByb3AiLCJpc05hTiIsInNldFByb3BlcnR5IiwiQ3JlZGl0Q2FyZFJlbmRlcmVyIiwiY2FyZFZhbGlkIiwiZm9ybVZhbGlkIiwiY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlIiwiZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkIiwiSG9zdGVkRmllbGRzIiwiaXNFbGlnaWJsZSIsIndyYXBwZXJFbGVtZW50IiwicGFyZW50Tm9kZSIsInJlbW92ZUNoaWxkIiwidGVhcmRvd24iLCJnYXRlV2F5Qm94Iiwib2xkRGlzcGxheVN0eWxlIiwiaGlkZURjY0dhdGV3YXkiLCJjYXJkTnVtYmVyRmllbGQiLCJzdHlsZXNSYXciLCJjYXJkTnVtYmVyIiwicmVwbGFjZUNoaWxkIiwiY2FyZEV4cGlyeUZpZWxkIiwiY2FyZEV4cGlyeSIsImNhcmRDb2RlRmllbGQiLCJjYXJkQ29kZSIsImZvcm1XcmFwcGVyIiwiZW5mb3JjZV92YXVsdCIsImNoZWNrZWQiLCJmaWVsZHMiLCJudW1iZXIiLCJzZWxlY3RvciIsInBsYWNlaG9sZGVyIiwiY3JlZGl0X2NhcmRfbnVtYmVyIiwiY3Z2IiwiZXhwaXJhdGlvbkRhdGUiLCJtbV95eSIsImhvc3RlZEZpZWxkcyIsImRpc3BhdGNoRXZlbnQiLCJDdXN0b21FdmVudCIsIl9zdWJtaXQiLCJldmVudCIsImNhcmRzIiwidmFsaWRDYXJkcyIsInZhbGlkX2NhcmRzIiwiaW5kZXhPZiIsInR5cGUiLCJrZXlzIiwiZXZlcnkiLCJrZXkiLCJpc1ZhbGlkIiwiYWRkRXZlbnRMaXN0ZW5lciIsInByZXZlbnREZWZhdWx0IiwiZmllbGQiLCJhdHRyaWJ1dGUiLCJyZW1vdmVBdHRyaWJ1dGUiLCJzYXZlX2NhcmQiLCJ2YXVsdCIsImdldEVsZW1lbnRCeUlkIiwiY29udGluZ2VuY3kiLCJob3N0ZWRGaWVsZHNEYXRhIiwiY29udGluZ2VuY2llcyIsInN1Ym1pdCIsInBheWxvYWQiLCJvcmRlcklkIiwiY2FyZF9ub3Rfc3VwcG9ydGVkIiwiZmllbGRzX25vdF92YWxpZCIsInN0b3JhZ2VLZXkiLCJ2YWxpZGF0ZVRva2VuIiwidG9rZW4iLCJ1c2VyIiwiY3VycmVudFRpbWUiLCJEYXRlIiwiZ2V0VGltZSIsImlzRXhwaXJlZCIsImV4cGlyYXRpb24iLCJzdG9yZWRUb2tlbkZvclVzZXIiLCJwYXJzZSIsInNlc3Npb25TdG9yYWdlIiwiZ2V0SXRlbSIsInN0b3JlVG9rZW4iLCJzZXRJdGVtIiwiZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciIsInNjcmlwdCIsIk1lc3NhZ2VSZW5kZXJlciIsIk1lc3NhZ2VzIiwicGxhY2VtZW50IiwibmV3V3JhcHBlciIsInNpYmxpbmciLCJuZXh0U2libGluZyIsInBhcmVudEVsZW1lbnQiLCJpbnNlcnRCZWZvcmUiLCJTcGlubmVyIiwidGFyZ2V0Iiwic2V0VGFyZ2V0Iiwib3ZlcmxheUNTUyIsImJhY2tncm91bmQiLCJvcGFjaXR5IiwiYm9vdHN0cmFwIiwibWVzc2FnZVJlbmRlcmVyIiwibWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCIsIm1pbmlDYXJ0Qm9vdHN0cmFwIiwic2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkIiwic2luZ2xlUHJvZHVjdEJvb3RzdHJhcCIsImNhcnRCb290c3RyYXAiLCJjaGVja291dEJvb3RzdGFwIiwicGF5Tm93Qm9vdHN0cmFwIiwidXJsIiwiZW50cmllcyIsInNjcmlwdF9hdHRyaWJ1dGVzIiwia2V5VmFsdWUiLCJkYXRhX2NsaWVudF9pZCIsInNldF9hdHRyaWJ1dGUiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///94\n")}},__webpack_exports__={};__webpack_modules__[94]()})();
1
+ (()=>{"use strict";var __webpack_modules__={94:()=>{eval("\n;// CONCATENATED MODULE: ./resources/js/modules/ErrorHandler.js\nclass ErrorHandler {\n constructor(genericErrorText) {\n this.genericErrorText = genericErrorText;\n this.wrapper = document.querySelector('.woocommerce-notices-wrapper');\n this.messagesList = document.querySelector('ul.woocommerce-error');\n }\n\n genericError() {\n if (this.wrapper.classList.contains('ppcp-persist')) {\n return;\n }\n\n this.clear();\n this.message(this.genericErrorText);\n }\n\n appendPreparedErrorMessageElement(errorMessageElement) {\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n this.messagesList.replaceWith(errorMessageElement);\n }\n\n message(text, persist = false) {\n if (!typeof String || text.length === 0) {\n throw new Error('A new message text must be a non-empty string.');\n }\n\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n if (persist) {\n this.wrapper.classList.add('ppcp-persist');\n } else {\n this.wrapper.classList.remove('ppcp-persist');\n }\n\n let messageNode = this.prepareMessagesListItem(text);\n this.messagesList.appendChild(messageNode);\n jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'));\n }\n\n prepareMessagesList() {\n if (this.messagesList === null) {\n this.messagesList = document.createElement('ul');\n this.messagesList.setAttribute('class', 'woocommerce-error');\n this.messagesList.setAttribute('role', 'alert');\n this.wrapper.appendChild(this.messagesList);\n }\n }\n\n prepareMessagesListItem(message) {\n const li = document.createElement('li');\n li.innerHTML = message;\n return li;\n }\n\n sanitize(text) {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = text;\n return textarea.value.replace('Error: ', '');\n }\n\n clear() {\n if (!this.wrapper.classList.contains('woocommerce-error')) {\n return;\n }\n\n this.wrapper.classList.remove('woocommerce-error');\n this.wrapper.innerText = '';\n }\n\n}\n\n/* harmony default export */ const modules_ErrorHandler = (ErrorHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForContinue.js\nconst onApprove = (context, errorHandler) => {\n return (data, actions) => {\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n ;\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CartActionHandler.js\n\n\n\nclass CartActionHandler {\n constructor(config, errorHandler) {\n this.config = config;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units: [],\n bn_code: bnCode,\n payer,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CartActionHandler = (CartActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/MiniCartBootstap.js\n\n\n\nclass MiniCartBootstap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.actionHandler = null;\n }\n\n init() {\n this.actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.render();\n jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.mini_cart_wrapper) !== null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.renderer.render(this.gateway.button.mini_cart_wrapper, this.gateway.hosted_fields.mini_cart_wrapper, this.actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_MiniCartBootstap = (MiniCartBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/UpdateCart.js\n\n\nclass UpdateCart {\n constructor(endpoint, nonce) {\n this.endpoint = endpoint;\n this.nonce = nonce;\n }\n /**\n *\n * @param onResolve\n * @param {Product[]} products\n * @returns {Promise<unknown>}\n */\n\n\n update(onResolve, products) {\n return new Promise((resolve, reject) => {\n fetch(this.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.nonce,\n products\n })\n }).then(result => {\n return result.json();\n }).then(result => {\n if (!result.success) {\n reject(result.data);\n return;\n }\n\n const resolved = onResolve(result.data);\n resolve(resolved);\n });\n });\n }\n\n}\n\n/* harmony default export */ const Helper_UpdateCart = (UpdateCart);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/ButtonsToggleListener.js\n/**\n * When you can't add something to the cart, the PayPal buttons should not show.\n * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.\n */\nclass ButtonsToggleListener {\n constructor(element, showCallback, hideCallback) {\n this.element = element;\n this.showCallback = showCallback;\n this.hideCallback = hideCallback;\n this.observer = null;\n }\n\n init() {\n const config = {\n attributes: true\n };\n\n const callback = () => {\n if (this.element.classList.contains('disabled')) {\n this.hideCallback();\n return;\n }\n\n this.showCallback();\n };\n\n this.observer = new MutationObserver(callback);\n this.observer.observe(this.element, config);\n callback();\n }\n\n disconnect() {\n this.observer.disconnect();\n }\n\n}\n\n/* harmony default export */ const Helper_ButtonsToggleListener = (ButtonsToggleListener);\n;// CONCATENATED MODULE: ./resources/js/modules/Entity/Product.js\nclass Product {\n constructor(id, quantity, variations) {\n this.id = id;\n this.quantity = quantity;\n this.variations = variations;\n }\n\n data() {\n return {\n id: this.id,\n quantity: this.quantity,\n variations: this.variations\n };\n }\n\n}\n\n/* harmony default export */ const Entity_Product = (Product);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/SingleProductActionHandler.js\n\n\n\n\n\nclass SingleProductActionHandler {\n constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler) {\n this.config = config;\n this.updateCart = updateCart;\n this.showButtonCallback = showButtonCallback;\n this.hideButtonCallback = hideButtonCallback;\n this.formElement = formElement;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n if (this.hasVariations()) {\n const observer = new Helper_ButtonsToggleListener(this.formElement.querySelector('.single_add_to_cart_button'), this.showButtonCallback, this.hideButtonCallback);\n observer.init();\n }\n\n return {\n createOrder: this.createOrder(),\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n createOrder() {\n var getProducts = null;\n\n if (!this.isGroupedProduct()) {\n getProducts = () => {\n const id = document.querySelector('[name=\"add-to-cart\"]').value;\n const qty = document.querySelector('[name=\"quantity\"]').value;\n const variations = this.variations();\n return [new Entity_Product(id, qty, variations)];\n };\n } else {\n getProducts = () => {\n const products = [];\n this.formElement.querySelectorAll('input[type=\"number\"]').forEach(element => {\n if (!element.value) {\n return;\n }\n\n const elementName = element.getAttribute('name').match(/quantity\\[([\\d]*)\\]/);\n\n if (elementName.length !== 2) {\n return;\n }\n\n const id = parseInt(elementName[1]);\n const quantity = parseInt(element.value);\n products.push(new Entity_Product(id, quantity, null));\n });\n return products;\n };\n }\n\n const createOrder = (data, actions) => {\n this.errorHandler.clear();\n\n const onResolve = purchase_units => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units,\n payer,\n bn_code: bnCode,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n const promise = this.updateCart.update(onResolve, getProducts());\n return promise;\n };\n\n return createOrder;\n }\n\n variations() {\n if (!this.hasVariations()) {\n return null;\n }\n\n const attributes = [...this.formElement.querySelectorAll(\"[name^='attribute_']\")].map(element => {\n return {\n value: element.value,\n name: element.name\n };\n });\n return attributes;\n }\n\n hasVariations() {\n return this.formElement.classList.contains('variations_form');\n }\n\n isGroupedProduct() {\n return this.formElement.classList.contains('grouped_form');\n }\n\n}\n\n/* harmony default export */ const ActionHandler_SingleProductActionHandler = (SingleProductActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/SingleProductBootstap.js\n\n\n\n\nclass SingleProductBootstap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n }\n\n init() {\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n return;\n }\n\n this.render();\n }\n\n shouldRender() {\n if (document.querySelector('form.cart') === null) {\n return false;\n }\n\n return true;\n }\n\n render() {\n const actionHandler = new ActionHandler_SingleProductActionHandler(this.gateway, new Helper_UpdateCart(this.gateway.ajax.change_cart.endpoint, this.gateway.ajax.change_cart.nonce), () => {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseInt(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n this.messages.renderWithAmount(amount);\n }, () => {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }, document.querySelector('form.cart'), new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_SingleProductBootstap = (SingleProductBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CartBootstap.js\n\n\n\nclass CartBootstrap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n }\n\n init() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.render();\n jQuery(document.body).on('updated_cart_totals updated_checkout', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n const actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const CartBootstap = (CartBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForPayNow.js\nconst onApproveForPayNow_onApprove = (context, errorHandler, spinner) => {\n return (data, actions) => {\n spinner.block();\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\nclass CheckoutActionHandler {\n constructor(config, errorHandler, spinner) {\n this.config = config;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n }\n\n configuration() {\n const spinner = this.spinner;\n\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n const errorHandler = this.errorHandler;\n const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';\n const formValues = jQuery(formSelector).serialize();\n const createaccount = jQuery('#createaccount').is(\":checked\") ? true : false;\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n payer,\n bn_code: bnCode,\n context: this.config.context,\n order_id: this.config.order_id,\n form: formValues,\n createaccount: createaccount\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n spinner.unblock(); //handle both messages sent from Woocommerce (data.messages) and this plugin (data.data.message)\n\n if (typeof data.messages !== 'undefined') {\n const domParser = new DOMParser();\n errorHandler.appendPreparedErrorMessageElement(domParser.parseFromString(data.messages, 'text/html').querySelector('ul'));\n } else {\n errorHandler.message(data.data.message, true);\n }\n\n return;\n }\n\n const input = document.createElement('input');\n input.setAttribute('type', 'hidden');\n input.setAttribute('name', 'ppcp-resume-order');\n input.setAttribute('value', data.data.purchase_units[0].custom_id);\n document.querySelector(formSelector).append(input);\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForPayNow(this, this.errorHandler, this.spinner),\n onCancel: () => {\n spinner.unblock();\n },\n onError: () => {\n this.errorHandler.genericError();\n spinner.unblock();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CheckoutActionHandler = (CheckoutActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CheckoutBootstap.js\n\n\n\nclass CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n jQuery(document).on('hosted_fields_loaded', () => {\n jQuery('#saved-credit-card').on('change', () => {\n this.displayPlaceOrderButtonForSavedCreditCards();\n });\n });\n this.switchBetweenPayPalandOrderButton();\n this.displayPlaceOrderButtonForSavedCreditCards();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n switchBetweenPayPalandOrderButton() {\n jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n\n displayPlaceOrderButtonForSavedCreditCards() {\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n return;\n }\n\n if (jQuery('#saved-credit-card').length && jQuery('#saved-credit-card').val() !== '') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n this.disableCreditCardFields();\n } else {\n jQuery('#place_order').hide();\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n this.enableCreditCardFields();\n }\n }\n\n disableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", true);\n this.renderer.disableCreditCardFields();\n }\n\n enableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", false);\n this.renderer.enableCreditCardFields();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_CheckoutBootstap = (CheckoutBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/PayNowBootstrap.js\n\n\n\nclass PayNowBootstrap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n }\n\n init() {\n this.render();\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.switchBetweenPayPalandOrderButton();\n });\n this.switchBetweenPayPalandOrderButton();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n switchBetweenPayPalandOrderButton() {\n const urlParams = new URLSearchParams(window.location.search);\n\n if (urlParams.has('change_payment_method')) {\n return;\n }\n\n const currentPaymentMethod = jQuery('input[name=\"payment_method\"]:checked').val();\n\n if (currentPaymentMethod !== 'ppcp-gateway' && currentPaymentMethod !== 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n jQuery('#place_order').show();\n } else {\n jQuery('#place_order').hide();\n\n if (currentPaymentMethod === 'ppcp-gateway') {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.messages.wrapper);\n this.messages.render();\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }\n\n if (currentPaymentMethod === 'ppcp-credit-card-gateway') {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.messages.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n }\n }\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_PayNowBootstrap = (PayNowBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/Renderer.js\nclass Renderer {\n constructor(creditCardRenderer, defaultConfig) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig\n }).render(wrapper);\n }\n\n isAlreadyRendered(wrapper) {\n return document.querySelector(wrapper).hasChildNodes();\n }\n\n hideButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'none';\n return true;\n }\n\n showButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'block';\n return true;\n }\n\n disableCreditCardFields() {\n this.creditCardRenderer.disableFields();\n }\n\n enableCreditCardFields() {\n this.creditCardRenderer.enableFields();\n }\n\n}\n\n/* harmony default export */ const Renderer_Renderer = (Renderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/DccInputFactory.js\nconst dccInputFactory = original => {\n const styles = window.getComputedStyle(original);\n const newElement = document.createElement('span');\n newElement.setAttribute('id', original.id);\n Object.values(styles).forEach(prop => {\n if (!styles[prop] || !isNaN(prop)) {\n return;\n }\n\n newElement.style.setProperty(prop, '' + styles[prop]);\n });\n return newElement;\n};\n\n/* harmony default export */ const DccInputFactory = (dccInputFactory);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/CreditCardRenderer.js\n\n\nclass CreditCardRenderer {\n constructor(defaultConfig, errorHandler, spinner) {\n this.defaultConfig = defaultConfig;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n this.cardValid = false;\n this.formValid = false;\n this.currentHostedFieldsInstance = null;\n this.formSubmissionSubscribed = false;\n }\n\n render(wrapper, contextConfig) {\n if (this.defaultConfig.context !== 'checkout' && this.defaultConfig.context !== 'pay-now' || wrapper === null || document.querySelector(wrapper) === null) {\n return;\n }\n\n if (typeof paypal.HostedFields === 'undefined' || !paypal.HostedFields.isEligible()) {\n const wrapperElement = document.querySelector(wrapper);\n wrapperElement.parentNode.removeChild(wrapperElement);\n return;\n }\n\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.teardown().catch(err => console.error(`Hosted fields teardown error: ${err}`));\n this.currentHostedFieldsInstance = null;\n }\n\n const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');\n const oldDisplayStyle = gateWayBox.style.display;\n gateWayBox.style.display = 'block';\n const hideDccGateway = document.querySelector('#ppcp-hide-dcc');\n\n if (hideDccGateway) {\n hideDccGateway.parentNode.removeChild(hideDccGateway);\n }\n\n const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');\n const stylesRaw = window.getComputedStyle(cardNumberField);\n let styles = {};\n Object.values(stylesRaw).forEach(prop => {\n if (!stylesRaw[prop]) {\n return;\n }\n\n styles[prop] = '' + stylesRaw[prop];\n });\n const cardNumber = DccInputFactory(cardNumberField);\n cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);\n const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');\n const cardExpiry = DccInputFactory(cardExpiryField);\n cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);\n const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');\n const cardCode = DccInputFactory(cardCodeField);\n cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);\n gateWayBox.style.display = oldDisplayStyle;\n const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';\n\n if (this.defaultConfig.enforce_vault && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')) {\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);\n }\n\n paypal.HostedFields.render({\n createOrder: contextConfig.createOrder,\n styles: {\n 'input': styles\n },\n fields: {\n number: {\n selector: '#ppcp-credit-card-gateway-card-number',\n placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number\n },\n cvv: {\n selector: '#ppcp-credit-card-gateway-card-cvc',\n placeholder: this.defaultConfig.hosted_fields.labels.cvv\n },\n expirationDate: {\n selector: '#ppcp-credit-card-gateway-card-expiry',\n placeholder: this.defaultConfig.hosted_fields.labels.mm_yy\n }\n }\n }).then(hostedFields => {\n document.dispatchEvent(new CustomEvent(\"hosted_fields_loaded\"));\n this.currentHostedFieldsInstance = hostedFields;\n hostedFields.on('inputSubmitRequest', () => {\n this._submit(contextConfig);\n });\n hostedFields.on('cardTypeChange', event => {\n if (!event.cards.length) {\n this.cardValid = false;\n return;\n }\n\n const validCards = this.defaultConfig.hosted_fields.valid_cards;\n this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;\n });\n hostedFields.on('validityChange', event => {\n const formValid = Object.keys(event.fields).every(function (key) {\n return event.fields[key].isValid;\n });\n this.formValid = formValid;\n });\n\n if (!this.formSubmissionSubscribed) {\n document.querySelector(wrapper + ' button').addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n this.formSubmissionSubscribed = true;\n }\n });\n document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener('click', () => {\n document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();\n });\n }\n\n disableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.setAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n enableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n _submit(contextConfig) {\n this.spinner.block();\n this.errorHandler.clear();\n\n if (this.formValid && this.cardValid) {\n const save_card = this.defaultConfig.save_card ? true : false;\n let vault = document.getElementById('ppcp-credit-card-vault') ? document.getElementById('ppcp-credit-card-vault').checked : save_card;\n\n if (this.defaultConfig.enforce_vault) {\n vault = true;\n }\n\n const contingency = this.defaultConfig.hosted_fields.contingency;\n const hostedFieldsData = {\n vault: vault\n };\n\n if (contingency !== 'NO_3D_SECURE') {\n hostedFieldsData.contingencies = [contingency];\n }\n\n this.currentHostedFieldsInstance.submit(hostedFieldsData).then(payload => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n }).catch(err => {\n console.error(err);\n this.spinner.unblock();\n });\n } else {\n this.spinner.unblock();\n const message = !this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;\n this.errorHandler.message(message);\n }\n }\n\n}\n\n/* harmony default export */ const Renderer_CreditCardRenderer = (CreditCardRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/DataClientIdAttributeHandler.js\nconst storageKey = 'ppcp-data-client-id';\n\nconst validateToken = (token, user) => {\n if (!token) {\n return false;\n }\n\n if (token.user !== user) {\n return false;\n }\n\n const currentTime = new Date().getTime();\n const isExpired = currentTime >= token.expiration * 1000;\n return !isExpired;\n};\n\nconst storedTokenForUser = user => {\n const token = JSON.parse(sessionStorage.getItem(storageKey));\n\n if (validateToken(token, user)) {\n return token.token;\n }\n\n return null;\n};\n\nconst storeToken = token => {\n sessionStorage.setItem(storageKey, JSON.stringify(token));\n};\n\nconst dataClientIdAttributeHandler = (script, config) => {\n fetch(config.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: config.nonce\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n const isValid = validateToken(data, config.user);\n\n if (!isValid) {\n return;\n }\n\n storeToken(data);\n script.setAttribute('data-client-token', data.token);\n document.body.append(script);\n });\n};\n\n/* harmony default export */ const DataClientIdAttributeHandler = (dataClientIdAttributeHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/MessageRenderer.js\nclass MessageRenderer {\n constructor(config) {\n this.config = config;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n renderWithAmount(amount) {\n if (!this.shouldRender()) {\n return;\n }\n\n const newWrapper = document.createElement('div');\n newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));\n const sibling = document.querySelector(this.config.wrapper).nextSibling;\n document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));\n sibling.parentElement.insertBefore(newWrapper, sibling);\n paypal.Messages({\n amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n shouldRender() {\n if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined') {\n return false;\n }\n\n if (!document.querySelector(this.config.wrapper)) {\n return false;\n }\n\n return true;\n }\n\n}\n\n/* harmony default export */ const Renderer_MessageRenderer = (MessageRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Spinner.js\nclass Spinner {\n constructor() {\n this.target = 'form.woocommerce-checkout';\n }\n\n setTarget(target) {\n this.target = target;\n }\n\n block() {\n jQuery(this.target).block({\n message: null,\n overlayCSS: {\n background: '#fff',\n opacity: 0.6\n }\n });\n }\n\n unblock() {\n jQuery(this.target).unblock();\n }\n\n}\n\n/* harmony default export */ const Helper_Spinner = (Spinner);\n;// CONCATENATED MODULE: ./resources/js/button.js\n\n\n\n\n\n\n\n\n\n\n\n\nconst bootstrap = () => {\n const errorHandler = new modules_ErrorHandler(PayPalCommerceGateway.labels.error.generic);\n const spinner = new Helper_Spinner();\n const creditCardRenderer = new Renderer_CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway);\n const messageRenderer = new Renderer_MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n\n if (context === 'mini-cart' || context === 'product') {\n if (PayPalCommerceGateway.mini_cart_buttons_enabled === '1') {\n const miniCartBootstrap = new ContextBootstrap_MiniCartBootstap(PayPalCommerceGateway, renderer);\n miniCartBootstrap.init();\n }\n }\n\n if (context === 'product' && PayPalCommerceGateway.single_product_buttons_enabled === '1') {\n const singleProductBootstrap = new ContextBootstrap_SingleProductBootstap(PayPalCommerceGateway, renderer, messageRenderer);\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstap(PayPalCommerceGateway, renderer);\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new ContextBootstrap_CheckoutBootstap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now') {\n const payNowBootstrap = new ContextBootstrap_PayNowBootstrap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (!typeof PayPalCommerceGateway) {\n console.error('PayPal button could not be configured.');\n return;\n }\n\n const script = document.createElement('script');\n script.addEventListener('load', event => {\n bootstrap();\n });\n script.setAttribute('src', PayPalCommerceGateway.button.url);\n Object.entries(PayPalCommerceGateway.script_attributes).forEach(keyValue => {\n script.setAttribute(keyValue[0], keyValue[1]);\n });\n\n if (PayPalCommerceGateway.data_client_id.set_attribute) {\n DataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);\n return;\n }\n\n document.body.append(script);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LENBQUN1USxnQkFBVCxDQUNJLGtCQURKLEVBRUksTUFBTTtBQUNGLE1BQUksQ0FBQyxPQUFRek0scUJBQWIsRUFBcUM7QUFDakN3QixJQUFBQSxPQUFPLENBQUNDLEtBQVIsQ0FBYyx3Q0FBZDtBQUNBO0FBQ0g7O0FBQ0QsUUFBTWdOLE1BQU0sR0FBR3ZTLFFBQVEsQ0FBQ3dCLGFBQVQsQ0FBdUIsUUFBdkIsQ0FBZjtBQUVBK1EsRUFBQUEsTUFBTSxDQUFDaEMsZ0JBQVAsQ0FBd0IsTUFBeEIsRUFBaUNWLEtBQUQsSUFBVztBQUN2Q3lELElBQUFBLFNBQVM7QUFDWixHQUZEO0FBR0FmLEVBQUFBLE1BQU0sQ0FBQzlRLFlBQVAsQ0FBb0IsS0FBcEIsRUFBMkJxQyxxQkFBcUIsQ0FBQ3NDLE1BQXRCLENBQTZCMk4sR0FBeEQ7QUFDQTVHLEVBQUFBLE1BQU0sQ0FBQzZHLE9BQVAsQ0FBZWxRLHFCQUFxQixDQUFDbVEsaUJBQXJDLEVBQXdEMUwsT0FBeEQsQ0FDSzJMLFFBQUQsSUFBYztBQUNWM0IsSUFBQUEsTUFBTSxDQUFDOVEsWUFBUCxDQUFvQnlTLFFBQVEsQ0FBQyxDQUFELENBQTVCLEVBQWlDQSxRQUFRLENBQUMsQ0FBRCxDQUF6QztBQUNILEdBSEw7O0FBTUEsTUFBSXBRLHFCQUFxQixDQUFDcVEsY0FBdEIsQ0FBcUNDLGFBQXpDLEVBQXdEO0FBQ3BEOUIsSUFBQUEsNEJBQTRCLENBQUNDLE1BQUQsRUFBU3pPLHFCQUFxQixDQUFDcVEsY0FBL0IsQ0FBNUI7QUFDQTtBQUNIOztBQUVEblUsRUFBQUEsUUFBUSxDQUFDNEMsSUFBVCxDQUFjNkgsTUFBZCxDQUFxQjhILE1BQXJCO0FBQ0gsQ0F6QkwiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRXJyb3JIYW5kbGVyLmpzP2U2NWEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanM/YzQ1NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1BheWVyRGF0YS5qcz8yYWYxIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyLmpzPzgyY2YiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcC5qcz9kNTUyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvVXBkYXRlQ2FydC5qcz9lNDIyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyLmpzP2UxOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0VudGl0eS9Qcm9kdWN0LmpzPzlmZmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIuanM/ZDliNyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAuanM/N2MxOSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAuanM/NWU5NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanM/OTMwNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXIuanM/ODUxNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwLmpzP2M4NTUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwLmpzP2Q5ZjUiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyLmpzP2ZhOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9EY2NJbnB1dEZhY3RvcnkuanM/MmEyZiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyLmpzPzM4N2EiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIuanM/ZWUwYiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyLmpzP2NkMDIiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0hlbHBlci9TcGlubmVyLmpzPzE3MDgiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9idXR0b24uanM/MDYwZiJdLCJzb3VyY2VzQ29udGVudCI6WyJjbGFzcyBFcnJvckhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoZ2VuZXJpY0Vycm9yVGV4dClcbiAgICB7XG4gICAgICAgIHRoaXMuZ2VuZXJpY0Vycm9yVGV4dCA9IGdlbmVyaWNFcnJvclRleHQ7XG4gICAgICAgIHRoaXMud3JhcHBlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53b29jb21tZXJjZS1ub3RpY2VzLXdyYXBwZXInKTtcbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd1bC53b29jb21tZXJjZS1lcnJvcicpO1xuICAgIH1cblxuICAgIGdlbmVyaWNFcnJvcigpIHtcbiAgICAgICAgaWYgKHRoaXMud3JhcHBlci5jbGFzc0xpc3QuY29udGFpbnMoJ3BwY3AtcGVyc2lzdCcpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICB0aGlzLm1lc3NhZ2UodGhpcy5nZW5lcmljRXJyb3JUZXh0KVxuICAgIH1cblxuICAgIGFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudChlcnJvck1lc3NhZ2VFbGVtZW50KVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QucmVwbGFjZVdpdGgoZXJyb3JNZXNzYWdlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgbWVzc2FnZSh0ZXh0LCBwZXJzaXN0ID0gZmFsc2UpXG4gICAge1xuICAgICAgICBpZighIHR5cGVvZiBTdHJpbmcgfHwgdGV4dC5sZW5ndGggPT09IDApe1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIG5ldyBtZXNzYWdlIHRleHQgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCl7XG4gICAgICAgICAgICB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwZXJzaXN0KSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmFkZCgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZSgncHBjcC1wZXJzaXN0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbWVzc2FnZU5vZGUgPSB0aGlzLnByZXBhcmVNZXNzYWdlc0xpc3RJdGVtKHRleHQpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5hcHBlbmRDaGlsZChtZXNzYWdlTm9kZSk7XG5cbiAgICAgICAgalF1ZXJ5LnNjcm9sbF90b19ub3RpY2VzKGpRdWVyeSgnLndvb2NvbW1lcmNlLW5vdGljZXMtd3JhcHBlcicpKVxuICAgIH1cblxuICAgIHByZXBhcmVNZXNzYWdlc0xpc3QoKVxuICAgIHtcbiAgICAgICAgaWYodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpe1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdjbGFzcycsICd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlc0xpc3Quc2V0QXR0cmlidXRlKCdyb2xlJywgJ2FsZXJ0Jyk7XG4gICAgICAgICAgICB0aGlzLndyYXBwZXIuYXBwZW5kQ2hpbGQodGhpcy5tZXNzYWdlc0xpc3QpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0obWVzc2FnZSlcbiAgICB7XG4gICAgICAgIGNvbnN0IGxpID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgICAgbGkuaW5uZXJIVE1MID0gbWVzc2FnZTtcblxuICAgICAgICByZXR1cm4gbGk7XG4gICAgfVxuXG4gICAgc2FuaXRpemUodGV4dClcbiAgICB7XG4gICAgICAgIGNvbnN0IHRleHRhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcbiAgICAgICAgdGV4dGFyZWEuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgcmV0dXJuIHRleHRhcmVhLnZhbHVlLnJlcGxhY2UoJ0Vycm9yOiAnLCAnJyk7XG4gICAgfVxuXG4gICAgY2xlYXIoKVxuICAgIHtcbiAgICAgICAgaWYgKCEgdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5jb250YWlucygnd29vY29tbWVyY2UtZXJyb3InKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QucmVtb3ZlKCd3b29jb21tZXJjZS1lcnJvcicpO1xuICAgICAgICB0aGlzLndyYXBwZXIuaW5uZXJUZXh0ID0gJyc7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBFcnJvckhhbmRsZXI7XG4iLCJjb25zdCBvbkFwcHJvdmUgPSAoY29udGV4dCwgZXJyb3JIYW5kbGVyKSA9PiB7XG4gICAgcmV0dXJuIChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGNvbnRleHQuY29uZmlnLnJlZGlyZWN0O1xuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiZXhwb3J0IGNvbnN0IHBheWVyRGF0YSA9ICgpID0+IHtcbiAgICBjb25zdCBwYXllciA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5wYXllcjtcbiAgICBpZiAoISBwYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwaG9uZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpIHx8IHR5cGVvZiBwYXllci5waG9uZSAhPT0gJ3VuZGVmaW5lZCcpID9cbiAgICB7XG4gICAgICAgIHBob25lX3R5cGU6XCJIT01FXCIsXG4gICAgICAgICAgICBwaG9uZV9udW1iZXI6e1xuICAgICAgICAgICAgbmF0aW9uYWxfbnVtYmVyIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKS52YWx1ZSA6IHBheWVyLnBob25lLnBob25lX251bWJlci5uYXRpb25hbF9udW1iZXJcbiAgICAgICAgfVxuICAgIH0gOiBudWxsO1xuICAgIGNvbnN0IHBheWVyRGF0YSA9IHtcbiAgICAgICAgZW1haWxfYWRkcmVzczooZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpLnZhbHVlIDogcGF5ZXIuZW1haWxfYWRkcmVzcyxcbiAgICAgICAgbmFtZSA6IHtcbiAgICAgICAgICAgIHN1cm5hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuc3VybmFtZSxcbiAgICAgICAgICAgIGdpdmVuX25hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5naXZlbl9uYW1lXG4gICAgICAgIH0sXG4gICAgICAgIGFkZHJlc3MgOiB7XG4gICAgICAgICAgICBjb3VudHJ5X2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuY291bnRyeV9jb2RlLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8xLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8yLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8xLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMixcbiAgICAgICAgICAgIHBvc3RhbF9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MucG9zdGFsX2NvZGVcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAocGhvbmUpIHtcbiAgICAgICAgcGF5ZXJEYXRhLnBob25lID0gcGhvbmU7XG4gICAgfVxuICAgIHJldHVybiBwYXllckRhdGE7XG59XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENhcnRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOiBvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIpLFxuICAgICAgICAgICAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgTWluaUNhcnRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbignd2NfZnJhZ21lbnRzX2xvYWRlZCB3Y19mcmFnbWVudHNfcmVmcmVzaGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcikgIT09XG4gICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKVxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWluaUNhcnRCb290c3RhcDsiLCJpbXBvcnQgUHJvZHVjdCBmcm9tIFwiLi4vRW50aXR5L1Byb2R1Y3RcIjtcbmNsYXNzIFVwZGF0ZUNhcnQge1xuXG4gICAgY29uc3RydWN0b3IoZW5kcG9pbnQsIG5vbmNlKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludCA9IGVuZHBvaW50O1xuICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25SZXNvbHZlXG4gICAgICogQHBhcmFtIHtQcm9kdWN0W119IHByb2R1Y3RzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAgICovXG4gICAgdXBkYXRlKG9uUmVzb2x2ZSwgcHJvZHVjdHMpXG4gICAge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZmV0Y2goXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qc29uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gb25SZXNvbHZlKHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVcGRhdGVDYXJ0OyIsIi8qKlxuICogV2hlbiB5b3UgY2FuJ3QgYWRkIHNvbWV0aGluZyB0byB0aGUgY2FydCwgdGhlIFBheVBhbCBidXR0b25zIHNob3VsZCBub3Qgc2hvdy5cbiAqIFRoZXJlZm9yZSB3ZSBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiBhbmQgc2hvdy9oaWRlIHRoZSBidXR0b25zIGFjY29yZGluZ2x5LlxuICovXG5cbmNsYXNzIEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2hvd0NhbGxiYWNrLCBoaWRlQ2FsbGJhY2spXG4gICAge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnNob3dDYWxsYmFjayA9IHNob3dDYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2sgPSBoaWRlQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKVxuICAgIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0geyBhdHRyaWJ1dGVzIDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNob3dDYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgZGlzY29ubmVjdCgpXG4gICAge1xuICAgICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcjsiLCJjbGFzcyBQcm9kdWN0IHtcblxuICAgIGNvbnN0cnVjdG9yKGlkLCBxdWFudGl0eSwgdmFyaWF0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMucXVhbnRpdHkgPSBxdWFudGl0eTtcbiAgICAgICAgdGhpcy52YXJpYXRpb25zID0gdmFyaWF0aW9ucztcbiAgICB9XG5cbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6dGhpcy5pZCxcbiAgICAgICAgICAgIHF1YW50aXR5OnRoaXMucXVhbnRpdHksXG4gICAgICAgICAgICB2YXJpYXRpb25zOnRoaXMudmFyaWF0aW9uc1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0OyIsImltcG9ydCBCdXR0b25zVG9nZ2xlTGlzdGVuZXIgZnJvbSAnLi4vSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lcic7XG5pbXBvcnQgUHJvZHVjdCBmcm9tICcuLi9FbnRpdHkvUHJvZHVjdCc7XG5pbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHVwZGF0ZUNhcnQsXG4gICAgICAgIHNob3dCdXR0b25DYWxsYmFjayxcbiAgICAgICAgaGlkZUJ1dHRvbkNhbGxiYWNrLFxuICAgICAgICBmb3JtRWxlbWVudCxcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhcnQgPSB1cGRhdGVDYXJ0O1xuICAgICAgICB0aGlzLnNob3dCdXR0b25DYWxsYmFjayA9IHNob3dCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2sgPSBoaWRlQnV0dG9uQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnQgPSBmb3JtRWxlbWVudDtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpXG4gICAge1xuXG4gICAgICAgIGlmICggdGhpcy5oYXNWYXJpYXRpb25zKCkgKSB7XG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlX2FkZF90b19jYXJ0X2J1dHRvbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUJ1dHRvbkNhbGxiYWNrXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuaW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiB0aGlzLmNyZWF0ZU9yZGVyKCksXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU9yZGVyKClcbiAgICB7XG4gICAgICAgIHZhciBnZXRQcm9kdWN0cyA9IG51bGw7XG4gICAgICAgIGlmICghIHRoaXMuaXNHcm91cGVkUHJvZHVjdCgpICkge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cImFkZC10by1jYXJ0XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcXR5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25hbWU9XCJxdWFudGl0eVwiXScpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhdGlvbnMgPSB0aGlzLnZhcmlhdGlvbnMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBQcm9kdWN0KGlkLCBxdHksIHZhcmlhdGlvbnMpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFByb2R1Y3RzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwibnVtYmVyXCJdJykuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBlbGVtZW50LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpLm1hdGNoKC9xdWFudGl0eVxcWyhbXFxkXSopXFxdLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50TmFtZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHBhcnNlSW50KGVsZW1lbnROYW1lWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMucHVzaChuZXcgUHJvZHVjdChpZCwgcXVhbnRpdHksIG51bGwpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICBjb25zdCBvblJlc29sdmUgPSAocHVyY2hhc2VfdW5pdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnVwZGF0ZUNhcnQudXBkYXRlKG9uUmVzb2x2ZSwgZ2V0UHJvZHVjdHMoKSk7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU9yZGVyO1xuICAgIH1cblxuICAgIHZhcmlhdGlvbnMoKVxuICAgIHtcblxuICAgICAgICBpZiAoISB0aGlzLmhhc1ZhcmlhdGlvbnMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFsuLi50aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZV49J2F0dHJpYnV0ZV8nXVwiKV0ubWFwKFxuICAgICAgICAgICAgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOmVsZW1lbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ZWxlbWVudC5uYW1lXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICBoYXNWYXJpYXRpb25zKClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygndmFyaWF0aW9uc19mb3JtJyk7XG4gICAgfVxuXG4gICAgaXNHcm91cGVkUHJvZHVjdCgpXG4gICAge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyb3VwZWRfZm9ybScpO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhcnQgZnJvbSBcIi4uL0hlbHBlci9VcGRhdGVDYXJ0XCI7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIgZnJvbSBcIi4uL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXJcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXksXG4gICAgICAgICAgICBuZXcgVXBkYXRlQ2FydChcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5ub25jZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgbGV0IHByaWNlVGV4dCA9IFwiMFwiO1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlSW50KHByaWNlVGV4dC5yZXBsYWNlKC8oW15cXGQsXFwuXFxzXSopL2csICcnKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXJXaXRoQW1vdW50KGFtb3VudClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JyksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXA7IiwiaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuXG5jbGFzcyBDYXJ0Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscyB1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0Qm9vdHN0cmFwO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICBzcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklEXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmNvZGUgPT09IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbnMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhY3Rpb25zLnJlc3RhcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwbGFjZV9vcmRlcicpLmNsaWNrKClcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENoZWNrb3V0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMuc3Bpbm5lcjtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IHRoaXMuZXJyb3JIYW5kbGVyO1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtU2VsZWN0b3IgPSB0aGlzLmNvbmZpZy5jb250ZXh0ID09PSAnY2hlY2tvdXQnID8gJ2Zvcm0uY2hlY2tvdXQnIDogJ2Zvcm0jb3JkZXJfcmV2aWV3JztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSBqUXVlcnkoZm9ybVNlbGVjdG9yKS5zZXJpYWxpemUoKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlYWNjb3VudCA9IGpRdWVyeSgnI2NyZWF0ZWFjY291bnQnKS5pcyhcIjpjaGVja2VkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyX2lkOnRoaXMuY29uZmlnLm9yZGVyX2lkLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOmZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWFjY291bnQ6IGNyZWF0ZWFjY291bnRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vaGFuZGxlIGJvdGggbWVzc2FnZXMgc2VudCBmcm9tIFdvb2NvbW1lcmNlIChkYXRhLm1lc3NhZ2VzKSBhbmQgdGhpcyBwbHVnaW4gKGRhdGEuZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKGRhdGEubWVzc2FnZXMpICE9PSAndW5kZWZpbmVkJyApXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5hcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhkYXRhLm1lc3NhZ2VzLCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJ3VsJylcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3BwY3AtcmVzdW1lLW9yZGVyJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGRhdGEuZGF0YS5wdXJjaGFzZV91bml0c1swXS5jdXN0b21faWQpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVNlbGVjdG9yKS5hcHBlbmQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6b25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyLCB0aGlzLnNwaW5uZXIpLFxuICAgICAgICAgICAgb25DYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDaGVja291dEFjdGlvbkhhbmRsZXIgZnJvbSAnLi4vQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXInO1xuXG5jbGFzcyBDaGVja291dEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKClcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLlxuICAgICAgICAgIG9uKCd1cGRhdGVkX2NoZWNrb3V0IHBheW1lbnRfbWV0aG9kX3NlbGVjdGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpXG4gICAgICAgICAgICAgIHRoaXMuZGlzcGxheVBsYWNlT3JkZXJCdXR0b25Gb3JTYXZlZENyZWRpdENhcmRzKClcblxuICAgICAgICAgIH0pXG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50KS5vbignaG9zdGVkX2ZpZWxkc19sb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKVxuICAgICAgICB0aGlzLmRpc3BsYXlQbGFjZU9yZGVyQnV0dG9uRm9yU2F2ZWRDcmVkaXRDYXJkcygpXG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLmNhbmNlbF93cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKSAhPT0gbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PSBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2JykpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2Jykuc2V0QXR0cmlidXRlKCdzdHlsZScsICcnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IENoZWNrb3V0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpIHtcbiAgICAgICAgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQgb3B0aW9uOmZpcnN0JykudmFsKCkpO1xuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICAgJ2lucHV0W25hbWU9XCJwYXltZW50X21ldGhvZFwiXTpjaGVja2VkJykudmFsKCk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kICE9PSAncHBjcC1nYXRld2F5JyAmJiBjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgalF1ZXJ5KCcjcGxhY2Vfb3JkZXInKS5oaWRlKCk7XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyKClcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0galF1ZXJ5KFxuICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS5sZW5ndGggJiYgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoKSAhPT0gJycpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKVxuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcilcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuc2hvdygpXG4gICAgICAgICAgICB0aGlzLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcilcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpXG4gICAgICAgICAgICB0aGlzLmVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgZmFsc2UpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEJvb3RzdGFwXG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2hlY2tvdXRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgUGF5Tm93Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5cbiAgICAgICAgb24oJ3VwZGF0ZWRfY2hlY2tvdXQgcGF5bWVudF9tZXRob2Rfc2VsZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN3aXRjaEJldHdlZW5QYXlQYWxhbmRPcmRlckJ1dHRvbigpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24oKTtcbiAgICB9XG5cbiAgICBzaG91bGRSZW5kZXIoKSB7XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24uY2FuY2VsX3dyYXBwZXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PSBudWxsIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcikgIT09IG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKSkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyICsgJz5kaXYnKS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICAgICAgdGhpcy5zcGlubmVyXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgc3dpdGNoQmV0d2VlblBheVBhbGFuZE9yZGVyQnV0dG9uKCkge1xuICAgICAgICBjb25zdCB1cmxQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpXG4gICAgICAgIGlmICh1cmxQYXJhbXMuaGFzKCdjaGFuZ2VfcGF5bWVudF9tZXRob2QnKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IGpRdWVyeShcbiAgICAgICAgICAgICdpbnB1dFtuYW1lPVwicGF5bWVudF9tZXRob2RcIl06Y2hlY2tlZCcpLnZhbCgpO1xuXG4gICAgICAgIGlmIChjdXJyZW50UGF5bWVudE1ldGhvZCAhPT0gJ3BwY3AtZ2F0ZXdheScgJiYgY3VycmVudFBheW1lbnRNZXRob2QgIT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICBqUXVlcnkoJyNwbGFjZV9vcmRlcicpLnNob3coKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3BsYWNlX29yZGVyJykuaGlkZSgpO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRQYXltZW50TWV0aG9kID09PSAncHBjcC1nYXRld2F5Jykge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5tZXNzYWdlcy53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnJlbmRlcigpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3VycmVudFBheW1lbnRNZXRob2QgPT09ICdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBheU5vd0Jvb3RzdHJhcDtcbiIsImNsYXNzIFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihjcmVkaXRDYXJkUmVuZGVyZXIsIGRlZmF1bHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIgPSBjcmVkaXRDYXJkUmVuZGVyZXI7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICB0aGlzLnJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLnJlbmRlcihob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICB9XG5cbiAgICByZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSB8fCB0aGlzLmlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHx8ICd1bmRlZmluZWQnID09PSB0eXBlb2YgcGF5cGFsLkJ1dHRvbnMgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdHlsZSA9IHdyYXBwZXIgPT09IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ud3JhcHBlciA/IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24uc3R5bGUgOiB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLm1pbmlfY2FydF9zdHlsZTtcbiAgICAgICAgcGF5cGFsLkJ1dHRvbnMoe1xuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAuLi5jb250ZXh0Q29uZmlnLFxuICAgICAgICB9KS5yZW5kZXIod3JhcHBlcik7XG4gICAgfVxuXG4gICAgaXNBbHJlYWR5UmVuZGVyZWQod3JhcHBlcikge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5oYXNDaGlsZE5vZGVzKCk7XG4gICAgfVxuXG4gICAgaGlkZUJ1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHNob3dCdXR0b25zKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgICAgIGlmICghIGRvbUVsZW1lbnQgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZG9tRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmRpc2FibGVGaWVsZHMoKTtcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5lbmFibGVGaWVsZHMoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlcmVyO1xuIiwiY29uc3QgZGNjSW5wdXRGYWN0b3J5ID0gKG9yaWdpbmFsKSA9PiB7XG4gICAgY29uc3Qgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUob3JpZ2luYWwpO1xuICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgbmV3RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2lkJywgb3JpZ2luYWwuaWQpO1xuICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzKS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICBpZiAoISBzdHlsZXNbcHJvcF0gfHwgISBpc05hTihwcm9wKSApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBuZXdFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KHByb3AsJycgKyBzdHlsZXNbcHJvcF0pO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG5leHBvcnQgZGVmYXVsdCBkY2NJbnB1dEZhY3Rvcnk7IiwiaW1wb3J0IGRjY0lucHV0RmFjdG9yeSBmcm9tIFwiLi4vSGVscGVyL0RjY0lucHV0RmFjdG9yeVwiO1xuXG5jbGFzcyBDcmVkaXRDYXJkUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoZGVmYXVsdENvbmZpZywgZXJyb3JIYW5kbGVyLCBzcGlubmVyKSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZyA9IGRlZmF1bHRDb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICAoXG4gICAgICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmNvbnRleHQgIT09ICdjaGVja291dCdcbiAgICAgICAgICAgICAgICAmJiB0aGlzLmRlZmF1bHRDb25maWcuY29udGV4dCAhPT0gJ3BheS1ub3cnXG4gICAgICAgICAgICApXG4gICAgICAgICAgICB8fCB3cmFwcGVyID09PSBudWxsXG4gICAgICAgICAgICB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpID09PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYXlwYWwuSG9zdGVkRmllbGRzID09PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgfHwgISBwYXlwYWwuSG9zdGVkRmllbGRzLmlzRWxpZ2libGUoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZXJFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKTtcbiAgICAgICAgICAgIHdyYXBwZXJFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQod3JhcHBlckVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS50ZWFyZG93bigpXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmVycm9yKGBIb3N0ZWQgZmllbGRzIHRlYXJkb3duIGVycm9yOiAke2Vycn1gKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBnYXRlV2F5Qm94ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnBheW1lbnRfYm94LnBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpO1xuICAgICAgICBjb25zdCBvbGREaXNwbGF5U3R5bGUgPSBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXk7XG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cbiAgICAgICAgY29uc3QgaGlkZURjY0dhdGV3YXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1oaWRlLWRjYycpO1xuICAgICAgICBpZiAoaGlkZURjY0dhdGV3YXkpIHtcbiAgICAgICAgICAgIGhpZGVEY2NHYXRld2F5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaGlkZURjY0dhdGV3YXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlckZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpO1xuXG4gICAgICAgIGNvbnN0IHN0eWxlc1JhdyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGNhcmROdW1iZXJGaWVsZCk7XG4gICAgICAgIGxldCBzdHlsZXMgPSB7fTtcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzdHlsZXNSYXcpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgICAgICBpZiAoISBzdHlsZXNSYXdbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHlsZXNbcHJvcF0gPSAnJyArIHN0eWxlc1Jhd1twcm9wXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2FyZE51bWJlciA9IGRjY0lucHV0RmFjdG9yeShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBjYXJkTnVtYmVyRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZE51bWJlciwgY2FyZE51bWJlckZpZWxkKTtcblxuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5RmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5Jyk7XG4gICAgICAgIGNvbnN0IGNhcmRFeHBpcnkgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZEV4cGlyeUZpZWxkKTtcbiAgICAgICAgY2FyZEV4cGlyeUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRFeHBpcnksIGNhcmRFeHBpcnlGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZENvZGVGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKTtcbiAgICAgICAgY29uc3QgY2FyZENvZGUgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZENvZGVGaWVsZCk7XG4gICAgICAgIGNhcmRDb2RlRmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZENvZGUsIGNhcmRDb2RlRmllbGQpO1xuXG4gICAgICAgIGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheSA9IG9sZERpc3BsYXlTdHlsZTtcblxuICAgICAgICBjb25zdCBmb3JtV3JhcHBlciA9ICcucGF5bWVudF9ib3ggcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHRcbiAgICAgICAgICAgICYmIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0JylcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgPSB0cnVlO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5zZXRBdHRyaWJ1dGUoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF5cGFsLkhvc3RlZEZpZWxkcy5yZW5kZXIoe1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IGNvbnRleHRDb25maWcuY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBzdHlsZXM6IHtcbiAgICAgICAgICAgICAgICAnaW5wdXQnOiBzdHlsZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICAgICAgICBudW1iZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jcmVkaXRfY2FyZF9udW1iZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjdnY6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jdnYsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBleHBpcmF0aW9uRGF0ZToge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLm1tX3l5LFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkudGhlbihob3N0ZWRGaWVsZHMgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJob3N0ZWRfZmllbGRzX2xvYWRlZFwiKSk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSA9IGhvc3RlZEZpZWxkcztcblxuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdpbnB1dFN1Ym1pdFJlcXVlc3QnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ2NhcmRUeXBlQ2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCAhIGV2ZW50LmNhcmRzLmxlbmd0aCApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZENhcmRzID0gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMudmFsaWRfY2FyZHM7XG4gICAgICAgICAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSB2YWxpZENhcmRzLmluZGV4T2YoZXZlbnQuY2FyZHNbMF0udHlwZSkgIT09IC0xO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbigndmFsaWRpdHlDaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtVmFsaWQgPSBPYmplY3Qua2V5cyhldmVudC5maWVsZHMpLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LmZpZWxkc1trZXldLmlzVmFsaWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZCA9IGZvcm1WYWxpZDtcblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5mb3JtU3VibWlzc2lvblN1YnNjcmliZWQpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIgKyAnIGJ1dHRvbicpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdWJtaXQoY29udGV4dENvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybVN1Ym1pc3Npb25TdWJzY3JpYmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheScpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2xhYmVsW2Zvcj1wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJdJykuY2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgIH1cblxuICAgIGRpc2FibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2Uuc2V0QXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmFibGVGaWVsZHMoKSB7XG4gICAgICAgIGlmKCB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2N2dicsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UucmVtb3ZlQXR0cmlidXRlKHtcbiAgICAgICAgICAgICAgICBmaWVsZDogJ2V4cGlyYXRpb25EYXRlJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfc3VibWl0KGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgdGhpcy5zcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZm9ybVZhbGlkICYmIHRoaXMuY2FyZFZhbGlkKSB7XG4gICAgICAgICAgICBjb25zdCBzYXZlX2NhcmQgPSB0aGlzLmRlZmF1bHRDb25maWcuc2F2ZV9jYXJkID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICAgICAgbGV0IHZhdWx0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKSA/XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5jaGVja2VkIDogc2F2ZV9jYXJkO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbmZpZy5lbmZvcmNlX3ZhdWx0KSB7XG4gICAgICAgICAgICAgICAgdmF1bHQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY29udGluZ2VuY3kgPSB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5jb250aW5nZW5jeTtcbiAgICAgICAgICAgIGNvbnN0IGhvc3RlZEZpZWxkc0RhdGEgPSB7XG4gICAgICAgICAgICAgICAgdmF1bHQ6IHZhdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGNvbnRpbmdlbmN5ICE9PSAnTk9fM0RfU0VDVVJFJykge1xuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY29udGluZ2VuY2llcyA9IFtjb250aW5nZW5jeV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zdWJtaXQoaG9zdGVkRmllbGRzRGF0YSkudGhlbigocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgIHBheWxvYWQub3JkZXJJRCA9IHBheWxvYWQub3JkZXJJZDtcbiAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0Q29uZmlnLm9uQXBwcm92ZShwYXlsb2FkKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gISB0aGlzLmNhcmRWYWxpZCA/IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jYXJkX25vdF9zdXBwb3J0ZWQgOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuZmllbGRzX25vdF92YWxpZDtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBDcmVkaXRDYXJkUmVuZGVyZXI7XG4iLCJjb25zdCBzdG9yYWdlS2V5ID0gJ3BwY3AtZGF0YS1jbGllbnQtaWQnO1xuXG5jb25zdCB2YWxpZGF0ZVRva2VuID0gKHRva2VuLCB1c2VyKSA9PiB7XG4gICAgaWYgKCEgdG9rZW4pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodG9rZW4udXNlciAhPT0gdXNlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgY29uc3QgaXNFeHBpcmVkID0gY3VycmVudFRpbWUgPj0gdG9rZW4uZXhwaXJhdGlvbiAqIDEwMDA7XG4gICAgcmV0dXJuICEgaXNFeHBpcmVkO1xufVxuXG5jb25zdCBzdG9yZWRUb2tlbkZvclVzZXIgPSAodXNlcikgPT4ge1xuICAgIGNvbnN0IHRva2VuID0gSlNPTi5wYXJzZShzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHN0b3JhZ2VLZXkpKTtcbiAgICBpZiAodmFsaWRhdGVUb2tlbih0b2tlbiwgdXNlcikpIHtcbiAgICAgICAgcmV0dXJuIHRva2VuLnRva2VuO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuY29uc3Qgc3RvcmVUb2tlbiA9ICh0b2tlbikgPT4ge1xuICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oc3RvcmFnZUtleSwgSlNPTi5zdHJpbmdpZnkodG9rZW4pKTtcbn1cblxuY29uc3QgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciA9IChzY3JpcHQsIGNvbmZpZykgPT4ge1xuICAgIGZldGNoKGNvbmZpZy5lbmRwb2ludCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgbm9uY2U6IGNvbmZpZy5ub25jZVxuICAgICAgICB9KVxuICAgIH0pLnRoZW4oKHJlcyk9PntcbiAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgY29uc3QgaXNWYWxpZCA9IHZhbGlkYXRlVG9rZW4oZGF0YSwgY29uZmlnLnVzZXIpO1xuICAgICAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzdG9yZVRva2VuKGRhdGEpO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdkYXRhLWNsaWVudC10b2tlbicsIGRhdGEudG9rZW4pO1xuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChzY3JpcHQpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyO1xuIiwiY2xhc3MgTWVzc2FnZVJlbmRlcmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQ6IHRoaXMuY29uZmlnLmFtb3VudCxcbiAgICAgICAgICAgIHBsYWNlbWVudDogdGhpcy5jb25maWcucGxhY2VtZW50LFxuICAgICAgICAgICAgc3R5bGU6IHRoaXMuY29uZmlnLnN0eWxlXG4gICAgICAgIH0pLnJlbmRlcih0aGlzLmNvbmZpZy53cmFwcGVyKTtcbiAgICB9XG5cbiAgICByZW5kZXJXaXRoQW1vdW50KGFtb3VudCkge1xuXG4gICAgICAgIGlmICghIHRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5ld1dyYXBwZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgbmV3V3JhcHBlci5zZXRBdHRyaWJ1dGUoJ2lkJywgdGhpcy5jb25maWcud3JhcHBlci5yZXBsYWNlKCcjJywgJycpKTtcblxuICAgICAgICBjb25zdCBzaWJsaW5nID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5uZXh0U2libGluZztcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKS5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpO1xuICAgICAgICBzaWJsaW5nLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKG5ld1dyYXBwZXIsIHNpYmxpbmcpO1xuICAgICAgICBwYXlwYWwuTWVzc2FnZXMoe1xuICAgICAgICAgICAgYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcblxuICAgICAgICBpZiAodHlwZW9mIHBheXBhbC5NZXNzYWdlcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHRoaXMuY29uZmlnLndyYXBwZXIgPT09ICd1bmRlZmluZWQnICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5jb25maWcud3JhcHBlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBNZXNzYWdlUmVuZGVyZXI7IiwiY2xhc3MgU3Bpbm5lciB7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy50YXJnZXQgPSAnZm9ybS53b29jb21tZXJjZS1jaGVja291dCc7XG4gICAgfVxuXG4gICAgc2V0VGFyZ2V0KHRhcmdldCkge1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICB9XG5cbiAgICBibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkuYmxvY2soe1xuICAgICAgICAgICAgbWVzc2FnZTogbnVsbCxcbiAgICAgICAgICAgIG92ZXJsYXlDU1M6IHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAnI2ZmZicsXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMC42XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVuYmxvY2soKSB7XG5cbiAgICAgICAgalF1ZXJ5KCB0aGlzLnRhcmdldCApLnVuYmxvY2soKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNwaW5uZXI7XG4iLCJpbXBvcnQgTWluaUNhcnRCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9NaW5pQ2FydEJvb3RzdGFwJztcbmltcG9ydCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvU2luZ2xlUHJvZHVjdEJvb3RzdGFwJztcbmltcG9ydCBDYXJ0Qm9vdHN0cmFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NhcnRCb290c3RhcCc7XG5pbXBvcnQgQ2hlY2tvdXRCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DaGVja291dEJvb3RzdGFwJztcbmltcG9ydCBQYXlOb3dCb290c3RyYXAgZnJvbSBcIi4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL1BheU5vd0Jvb3RzdHJhcFwiO1xuaW1wb3J0IFJlbmRlcmVyIGZyb20gJy4vbW9kdWxlcy9SZW5kZXJlci9SZW5kZXJlcic7XG5pbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4vbW9kdWxlcy9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENyZWRpdENhcmRSZW5kZXJlciBmcm9tIFwiLi9tb2R1bGVzL1JlbmRlcmVyL0NyZWRpdENhcmRSZW5kZXJlclwiO1xuaW1wb3J0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIgZnJvbSBcIi4vbW9kdWxlcy9EYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyXCI7XG5pbXBvcnQgTWVzc2FnZVJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvTWVzc2FnZVJlbmRlcmVyXCI7XG5pbXBvcnQgU3Bpbm5lciBmcm9tIFwiLi9tb2R1bGVzL0hlbHBlci9TcGlubmVyXCI7XG5cbmNvbnN0IGJvb3RzdHJhcCA9ICgpID0+IHtcbiAgICBjb25zdCBlcnJvckhhbmRsZXIgPSBuZXcgRXJyb3JIYW5kbGVyKFBheVBhbENvbW1lcmNlR2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyk7XG4gICAgY29uc3Qgc3Bpbm5lciA9IG5ldyBTcGlubmVyKCk7XG4gICAgY29uc3QgY3JlZGl0Q2FyZFJlbmRlcmVyID0gbmV3IENyZWRpdENhcmRSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXksIGVycm9ySGFuZGxlciwgc3Bpbm5lcik7XG4gICAgY29uc3QgcmVuZGVyZXIgPSBuZXcgUmVuZGVyZXIoY3JlZGl0Q2FyZFJlbmRlcmVyLCBQYXlQYWxDb21tZXJjZUdhdGV3YXkpO1xuICAgIGNvbnN0IG1lc3NhZ2VSZW5kZXJlciA9IG5ldyBNZXNzYWdlUmVuZGVyZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1lc3NhZ2VzKTtcbiAgICBjb25zdCBjb250ZXh0ID0gUGF5UGFsQ29tbWVyY2VHYXRld2F5LmNvbnRleHQ7XG4gICAgaWYgKGNvbnRleHQgPT09ICdtaW5pLWNhcnQnIHx8IGNvbnRleHQgPT09ICdwcm9kdWN0Jykge1xuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5Lm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQgPT09ICcxJykge1xuICAgICAgICAgICAgY29uc3QgbWluaUNhcnRCb290c3RyYXAgPSBuZXcgTWluaUNhcnRCb290c3RhcChcbiAgICAgICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICAgICAgcmVuZGVyZXJcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIG1pbmlDYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncHJvZHVjdCcgJiYgUGF5UGFsQ29tbWVyY2VHYXRld2F5LnNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgIGNvbnN0IHNpbmdsZVByb2R1Y3RCb290c3RyYXAgPSBuZXcgU2luZ2xlUHJvZHVjdEJvb3RzdGFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICk7XG5cbiAgICAgICAgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdjYXJ0Jykge1xuICAgICAgICBjb25zdCBjYXJ0Qm9vdHN0cmFwID0gbmV3IENhcnRCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBjYXJ0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBjb25zdCBjaGVja291dEJvb3RzdGFwID0gbmV3IENoZWNrb3V0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcblxuICAgICAgICBjaGVja291dEJvb3RzdGFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ3BheS1ub3cnICkge1xuICAgICAgICBjb25zdCBwYXlOb3dCb290c3RyYXAgPSBuZXcgUGF5Tm93Qm9vdHN0cmFwKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgcmVuZGVyZXIsXG4gICAgICAgICAgICBtZXNzYWdlUmVuZGVyZXIsXG4gICAgICAgICAgICBzcGlubmVyXG4gICAgICAgICk7XG4gICAgICAgIHBheU5vd0Jvb3RzdHJhcC5pbml0KCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgIT09ICdjaGVja291dCcpIHtcbiAgICAgICAgbWVzc2FnZVJlbmRlcmVyLnJlbmRlcigpO1xuICAgIH1cbn07XG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICdET01Db250ZW50TG9hZGVkJyxcbiAgICAoKSA9PiB7XG4gICAgICAgIGlmICghdHlwZW9mIChQYXlQYWxDb21tZXJjZUdhdGV3YXkpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdQYXlQYWwgYnV0dG9uIGNvdWxkIG5vdCBiZSBjb25maWd1cmVkLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gICAgICAgIHNjcmlwdC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBib290c3RyYXAoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ3NyYycsIFBheVBhbENvbW1lcmNlR2F0ZXdheS5idXR0b24udXJsKTtcbiAgICAgICAgT2JqZWN0LmVudHJpZXMoUGF5UGFsQ29tbWVyY2VHYXRld2F5LnNjcmlwdF9hdHRyaWJ1dGVzKS5mb3JFYWNoKFxuICAgICAgICAgICAgKGtleVZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgc2NyaXB0LnNldEF0dHJpYnV0ZShrZXlWYWx1ZVswXSwga2V5VmFsdWVbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQuc2V0X2F0dHJpYnV0ZSkge1xuICAgICAgICAgICAgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlcihzY3JpcHQsIFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChzY3JpcHQpO1xuICAgIH0sXG4pO1xuIl0sIm5hbWVzIjpbIkVycm9ySGFuZGxlciIsImNvbnN0cnVjdG9yIiwiZ2VuZXJpY0Vycm9yVGV4dCIsIndyYXBwZXIiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJtZXNzYWdlc0xpc3QiLCJnZW5lcmljRXJyb3IiLCJjbGFzc0xpc3QiLCJjb250YWlucyIsImNsZWFyIiwibWVzc2FnZSIsImFwcGVuZFByZXBhcmVkRXJyb3JNZXNzYWdlRWxlbWVudCIsImVycm9yTWVzc2FnZUVsZW1lbnQiLCJwcmVwYXJlTWVzc2FnZXNMaXN0IiwicmVwbGFjZVdpdGgiLCJ0ZXh0IiwicGVyc2lzdCIsIlN0cmluZyIsImxlbmd0aCIsIkVycm9yIiwiYWRkIiwicmVtb3ZlIiwibWVzc2FnZU5vZGUiLCJwcmVwYXJlTWVzc2FnZXNMaXN0SXRlbSIsImFwcGVuZENoaWxkIiwialF1ZXJ5Iiwic2Nyb2xsX3RvX25vdGljZXMiLCJjcmVhdGVFbGVtZW50Iiwic2V0QXR0cmlidXRlIiwibGkiLCJpbm5lckhUTUwiLCJzYW5pdGl6ZSIsInRleHRhcmVhIiwidmFsdWUiLCJyZXBsYWNlIiwiaW5uZXJUZXh0Iiwib25BcHByb3ZlIiwiY29udGV4dCIsImVycm9ySGFuZGxlciIsImRhdGEiLCJhY3Rpb25zIiwiZmV0Y2giLCJjb25maWciLCJhamF4IiwiYXBwcm92ZV9vcmRlciIsImVuZHBvaW50IiwibWV0aG9kIiwiYm9keSIsIkpTT04iLCJzdHJpbmdpZnkiLCJub25jZSIsIm9yZGVyX2lkIiwib3JkZXJJRCIsInRoZW4iLCJyZXMiLCJqc29uIiwic3VjY2VzcyIsInJlc3RhcnQiLCJjYXRjaCIsImVyciIsImxvY2F0aW9uIiwiaHJlZiIsInJlZGlyZWN0IiwicGF5ZXJEYXRhIiwicGF5ZXIiLCJQYXlQYWxDb21tZXJjZUdhdGV3YXkiLCJwaG9uZSIsInBob25lX3R5cGUiLCJwaG9uZV9udW1iZXIiLCJuYXRpb25hbF9udW1iZXIiLCJlbWFpbF9hZGRyZXNzIiwibmFtZSIsInN1cm5hbWUiLCJnaXZlbl9uYW1lIiwiYWRkcmVzcyIsImNvdW50cnlfY29kZSIsImFkZHJlc3NfbGluZV8xIiwiYWRkcmVzc19saW5lXzIiLCJhZG1pbl9hcmVhXzEiLCJhZG1pbl9hcmVhXzIiLCJwb3N0YWxfY29kZSIsIkNhcnRBY3Rpb25IYW5kbGVyIiwiY29uZmlndXJhdGlvbiIsImNyZWF0ZU9yZGVyIiwiYm5Db2RlIiwiYm5fY29kZXMiLCJjcmVhdGVfb3JkZXIiLCJwdXJjaGFzZV91bml0cyIsImJuX2NvZGUiLCJjb25zb2xlIiwiZXJyb3IiLCJpZCIsIm9uRXJyb3IiLCJNaW5pQ2FydEJvb3RzdGFwIiwiZ2F0ZXdheSIsInJlbmRlcmVyIiwiYWN0aW9uSGFuZGxlciIsImluaXQiLCJsYWJlbHMiLCJnZW5lcmljIiwicmVuZGVyIiwib24iLCJzaG91bGRSZW5kZXIiLCJidXR0b24iLCJtaW5pX2NhcnRfd3JhcHBlciIsImhvc3RlZF9maWVsZHMiLCJQcm9kdWN0IiwiVXBkYXRlQ2FydCIsInVwZGF0ZSIsIm9uUmVzb2x2ZSIsInByb2R1Y3RzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJyZXN1bHQiLCJyZXNvbHZlZCIsIkJ1dHRvbnNUb2dnbGVMaXN0ZW5lciIsImVsZW1lbnQiLCJzaG93Q2FsbGJhY2siLCJoaWRlQ2FsbGJhY2siLCJvYnNlcnZlciIsImF0dHJpYnV0ZXMiLCJjYWxsYmFjayIsIk11dGF0aW9uT2JzZXJ2ZXIiLCJvYnNlcnZlIiwiZGlzY29ubmVjdCIsInF1YW50aXR5IiwidmFyaWF0aW9ucyIsIlNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIiwidXBkYXRlQ2FydCIsInNob3dCdXR0b25DYWxsYmFjayIsImhpZGVCdXR0b25DYWxsYmFjayIsImZvcm1FbGVtZW50IiwiaGFzVmFyaWF0aW9ucyIsImdldFByb2R1Y3RzIiwiaXNHcm91cGVkUHJvZHVjdCIsInF0eSIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJmb3JFYWNoIiwiZWxlbWVudE5hbWUiLCJnZXRBdHRyaWJ1dGUiLCJtYXRjaCIsInBhcnNlSW50IiwicHVzaCIsInByb21pc2UiLCJtYXAiLCJTaW5nbGVQcm9kdWN0Qm9vdHN0YXAiLCJtZXNzYWdlcyIsImhpZGVCdXR0b25zIiwiY2hhbmdlX2NhcnQiLCJzaG93QnV0dG9ucyIsInByaWNlVGV4dCIsImFtb3VudCIsInJlbmRlcldpdGhBbW91bnQiLCJDYXJ0Qm9vdHN0cmFwIiwic3Bpbm5lciIsImJsb2NrIiwidW5ibG9jayIsImNvZGUiLCJjbGljayIsIkNoZWNrb3V0QWN0aW9uSGFuZGxlciIsImZvcm1TZWxlY3RvciIsImZvcm1WYWx1ZXMiLCJzZXJpYWxpemUiLCJjcmVhdGVhY2NvdW50IiwiaXMiLCJmb3JtIiwiZG9tUGFyc2VyIiwiRE9NUGFyc2VyIiwicGFyc2VGcm9tU3RyaW5nIiwiaW5wdXQiLCJjdXN0b21faWQiLCJhcHBlbmQiLCJvbkNhbmNlbCIsIkNoZWNrb3V0Qm9vdHN0YXAiLCJzd2l0Y2hCZXR3ZWVuUGF5UGFsYW5kT3JkZXJCdXR0b24iLCJkaXNwbGF5UGxhY2VPcmRlckJ1dHRvbkZvclNhdmVkQ3JlZGl0Q2FyZHMiLCJjYW5jZWxfd3JhcHBlciIsInZhbCIsImN1cnJlbnRQYXltZW50TWV0aG9kIiwic2hvdyIsImhpZGUiLCJkaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcyIsImVuYWJsZUNyZWRpdENhcmRGaWVsZHMiLCJhZGRDbGFzcyIsImF0dHIiLCJyZW1vdmVDbGFzcyIsIlBheU5vd0Jvb3RzdHJhcCIsInVybFBhcmFtcyIsIlVSTFNlYXJjaFBhcmFtcyIsIndpbmRvdyIsInNlYXJjaCIsImhhcyIsIlJlbmRlcmVyIiwiY3JlZGl0Q2FyZFJlbmRlcmVyIiwiZGVmYXVsdENvbmZpZyIsImhvc3RlZEZpZWxkc1dyYXBwZXIiLCJjb250ZXh0Q29uZmlnIiwicmVuZGVyQnV0dG9ucyIsImlzQWxyZWFkeVJlbmRlcmVkIiwicGF5cGFsIiwiQnV0dG9ucyIsInN0eWxlIiwibWluaV9jYXJ0X3N0eWxlIiwiaGFzQ2hpbGROb2RlcyIsImRvbUVsZW1lbnQiLCJkaXNwbGF5IiwiZGlzYWJsZUZpZWxkcyIsImVuYWJsZUZpZWxkcyIsImRjY0lucHV0RmFjdG9yeSIsIm9yaWdpbmFsIiwic3R5bGVzIiwiZ2V0Q29tcHV0ZWRTdHlsZSIsIm5ld0VsZW1lbnQiLCJPYmplY3QiLCJ2YWx1ZXMiLCJwcm9wIiwiaXNOYU4iLCJzZXRQcm9wZXJ0eSIsIkNyZWRpdENhcmRSZW5kZXJlciIsImNhcmRWYWxpZCIsImZvcm1WYWxpZCIsImN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSIsImZvcm1TdWJtaXNzaW9uU3Vic2NyaWJlZCIsIkhvc3RlZEZpZWxkcyIsImlzRWxpZ2libGUiLCJ3cmFwcGVyRWxlbWVudCIsInBhcmVudE5vZGUiLCJyZW1vdmVDaGlsZCIsInRlYXJkb3duIiwiZ2F0ZVdheUJveCIsIm9sZERpc3BsYXlTdHlsZSIsImhpZGVEY2NHYXRld2F5IiwiY2FyZE51bWJlckZpZWxkIiwic3R5bGVzUmF3IiwiY2FyZE51bWJlciIsInJlcGxhY2VDaGlsZCIsImNhcmRFeHBpcnlGaWVsZCIsImNhcmRFeHBpcnkiLCJjYXJkQ29kZUZpZWxkIiwiY2FyZENvZGUiLCJmb3JtV3JhcHBlciIsImVuZm9yY2VfdmF1bHQiLCJjaGVja2VkIiwiZmllbGRzIiwibnVtYmVyIiwic2VsZWN0b3IiLCJwbGFjZWhvbGRlciIsImNyZWRpdF9jYXJkX251bWJlciIsImN2diIsImV4cGlyYXRpb25EYXRlIiwibW1feXkiLCJob3N0ZWRGaWVsZHMiLCJkaXNwYXRjaEV2ZW50IiwiQ3VzdG9tRXZlbnQiLCJfc3VibWl0IiwiZXZlbnQiLCJjYXJkcyIsInZhbGlkQ2FyZHMiLCJ2YWxpZF9jYXJkcyIsImluZGV4T2YiLCJ0eXBlIiwia2V5cyIsImV2ZXJ5Iiwia2V5IiwiaXNWYWxpZCIsImFkZEV2ZW50TGlzdGVuZXIiLCJwcmV2ZW50RGVmYXVsdCIsImZpZWxkIiwiYXR0cmlidXRlIiwicmVtb3ZlQXR0cmlidXRlIiwic2F2ZV9jYXJkIiwidmF1bHQiLCJnZXRFbGVtZW50QnlJZCIsImNvbnRpbmdlbmN5IiwiaG9zdGVkRmllbGRzRGF0YSIsImNvbnRpbmdlbmNpZXMiLCJzdWJtaXQiLCJwYXlsb2FkIiwib3JkZXJJZCIsImNhcmRfbm90X3N1cHBvcnRlZCIsImZpZWxkc19ub3RfdmFsaWQiLCJzdG9yYWdlS2V5IiwidmFsaWRhdGVUb2tlbiIsInRva2VuIiwidXNlciIsImN1cnJlbnRUaW1lIiwiRGF0ZSIsImdldFRpbWUiLCJpc0V4cGlyZWQiLCJleHBpcmF0aW9uIiwic3RvcmVkVG9rZW5Gb3JVc2VyIiwicGFyc2UiLCJzZXNzaW9uU3RvcmFnZSIsImdldEl0ZW0iLCJzdG9yZVRva2VuIiwic2V0SXRlbSIsImRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIiLCJzY3JpcHQiLCJNZXNzYWdlUmVuZGVyZXIiLCJNZXNzYWdlcyIsInBsYWNlbWVudCIsIm5ld1dyYXBwZXIiLCJzaWJsaW5nIiwibmV4dFNpYmxpbmciLCJwYXJlbnRFbGVtZW50IiwiaW5zZXJ0QmVmb3JlIiwiU3Bpbm5lciIsInRhcmdldCIsInNldFRhcmdldCIsIm92ZXJsYXlDU1MiLCJiYWNrZ3JvdW5kIiwib3BhY2l0eSIsImJvb3RzdHJhcCIsIm1lc3NhZ2VSZW5kZXJlciIsIm1pbmlfY2FydF9idXR0b25zX2VuYWJsZWQiLCJtaW5pQ2FydEJvb3RzdHJhcCIsInNpbmdsZV9wcm9kdWN0X2J1dHRvbnNfZW5hYmxlZCIsInNpbmdsZVByb2R1Y3RCb290c3RyYXAiLCJjYXJ0Qm9vdHN0cmFwIiwiY2hlY2tvdXRCb290c3RhcCIsInBheU5vd0Jvb3RzdHJhcCIsInVybCIsImVudHJpZXMiLCJzY3JpcHRfYXR0cmlidXRlcyIsImtleVZhbHVlIiwiZGF0YV9jbGllbnRfaWQiLCJzZXRfYXR0cmlidXRlIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///94\n")}},__webpack_exports__={};__webpack_modules__[94]()})();
modules/ppcp-button/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-button",
3
+ "type": "dhii-mod",
4
+ "description": "Button module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Button\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js CHANGED
@@ -182,8 +182,11 @@ class CreditCardRenderer {
182
 
183
  if (this.formValid && this.cardValid) {
184
  const save_card = this.defaultConfig.save_card ? true : false;
185
- const vault = document.getElementById('ppcp-credit-card-vault') ?
186
  document.getElementById('ppcp-credit-card-vault').checked : save_card;
 
 
 
187
  const contingency = this.defaultConfig.hosted_fields.contingency;
188
  const hostedFieldsData = {
189
  vault: vault
182
 
183
  if (this.formValid && this.cardValid) {
184
  const save_card = this.defaultConfig.save_card ? true : false;
185
+ let vault = document.getElementById('ppcp-credit-card-vault') ?
186
  document.getElementById('ppcp-credit-card-vault').checked : save_card;
187
+ if (this.defaultConfig.enforce_vault) {
188
+ vault = true;
189
+ }
190
  const contingency = this.defaultConfig.hosted_fields.contingency;
191
  const hostedFieldsData = {
192
  vault: vault
modules/ppcp-button/services.php CHANGED
@@ -9,6 +9,7 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Button;
11
 
 
12
  use WooCommerce\PayPalCommerce\Button\Assets\DisabledSmartButton;
13
  use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
14
  use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
@@ -25,7 +26,7 @@ use WooCommerce\PayPalCommerce\Onboarding\Environment;
25
  use WooCommerce\PayPalCommerce\Onboarding\State;
26
 
27
  return array(
28
- 'button.client_id' => static function ( $container ): string {
29
 
30
  $settings = $container->get( 'wcgateway.settings' );
31
  $client_id = $settings->has( 'client_id' ) ? $settings->get( 'client_id' ) : '';
@@ -43,7 +44,7 @@ return array(
43
  return $env->current_environment_is( Environment::SANDBOX ) ?
44
  CONNECT_WOO_SANDBOX_CLIENT_ID : CONNECT_WOO_CLIENT_ID;
45
  },
46
- 'button.smart-button' => static function ( $container ): SmartButtonInterface {
47
 
48
  $state = $container->get( 'onboarding.state' );
49
  /**
@@ -84,16 +85,16 @@ return array(
84
  $settings_status
85
  );
86
  },
87
- 'button.url' => static function ( $container ): string {
88
  return plugins_url(
89
  '/modules/ppcp-button/',
90
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
91
  );
92
  },
93
- 'button.request-data' => static function ( $container ): RequestData {
94
  return new RequestData();
95
  },
96
- 'button.endpoint.change-cart' => static function ( $container ): ChangeCartEndpoint {
97
  if ( ! \WC()->cart ) {
98
  throw new RuntimeException( 'cant initialize endpoint at this moment' );
99
  }
@@ -105,7 +106,7 @@ return array(
105
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
106
  return new ChangeCartEndpoint( $cart, $shipping, $request_data, $repository, $data_store, $logger );
107
  },
108
- 'button.endpoint.create-order' => static function ( $container ): CreateOrderEndpoint {
109
  $request_data = $container->get( 'button.request-data' );
110
  $cart_repository = $container->get( 'api.repository.cart' );
111
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
@@ -114,7 +115,8 @@ return array(
114
  $session_handler = $container->get( 'session.handler' );
115
  $settings = $container->get( 'wcgateway.settings' );
116
  $early_order_handler = $container->get( 'button.helper.early-order-handler' );
117
- $logger = $container->get( 'woocommerce.logger.woocommerce' );
 
118
  return new CreateOrderEndpoint(
119
  $request_data,
120
  $cart_repository,
@@ -124,10 +126,11 @@ return array(
124
  $session_handler,
125
  $settings,
126
  $early_order_handler,
 
127
  $logger
128
  );
129
  },
130
- 'button.helper.early-order-handler' => static function ( $container ) : EarlyOrderHandler {
131
 
132
  $state = $container->get( 'onboarding.state' );
133
  $order_processor = $container->get( 'wcgateway.order-processor' );
@@ -135,7 +138,7 @@ return array(
135
  $prefix = $container->get( 'api.prefix' );
136
  return new EarlyOrderHandler( $state, $order_processor, $session_handler, $prefix );
137
  },
138
- 'button.endpoint.approve-order' => static function ( $container ): ApproveOrderEndpoint {
139
  $request_data = $container->get( 'button.request-data' );
140
  $order_endpoint = $container->get( 'api.endpoint.order' );
141
  $session_handler = $container->get( 'session.handler' );
@@ -153,7 +156,7 @@ return array(
153
  $logger
154
  );
155
  },
156
- 'button.endpoint.data-client-id' => static function( $container ) : DataClientIdEndpoint {
157
  $request_data = $container->get( 'button.request-data' );
158
  $identity_token = $container->get( 'api.endpoint.identity-token' );
159
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
@@ -163,11 +166,22 @@ return array(
163
  $logger
164
  );
165
  },
166
- 'button.helper.three-d-secure' => static function ( $container ): ThreeDSecure {
167
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
168
  return new ThreeDSecure( $logger );
169
  },
170
- 'button.helper.messages-apply' => static function ( $container ): MessagesApply {
171
  return new MessagesApply();
172
  },
 
 
 
 
 
 
 
 
 
 
 
173
  );
9
 
10
  namespace WooCommerce\PayPalCommerce\Button;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\Button\Assets\DisabledSmartButton;
14
  use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
15
  use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
26
  use WooCommerce\PayPalCommerce\Onboarding\State;
27
 
28
  return array(
29
+ 'button.client_id' => static function ( ContainerInterface $container ): string {
30
 
31
  $settings = $container->get( 'wcgateway.settings' );
32
  $client_id = $settings->has( 'client_id' ) ? $settings->get( 'client_id' ) : '';
44
  return $env->current_environment_is( Environment::SANDBOX ) ?
45
  CONNECT_WOO_SANDBOX_CLIENT_ID : CONNECT_WOO_CLIENT_ID;
46
  },
47
+ 'button.smart-button' => static function ( ContainerInterface $container ): SmartButtonInterface {
48
 
49
  $state = $container->get( 'onboarding.state' );
50
  /**
85
  $settings_status
86
  );
87
  },
88
+ 'button.url' => static function ( ContainerInterface $container ): string {
89
  return plugins_url(
90
  '/modules/ppcp-button/',
91
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
92
  );
93
  },
94
+ 'button.request-data' => static function ( ContainerInterface $container ): RequestData {
95
  return new RequestData();
96
  },
97
+ 'button.endpoint.change-cart' => static function ( ContainerInterface $container ): ChangeCartEndpoint {
98
  if ( ! \WC()->cart ) {
99
  throw new RuntimeException( 'cant initialize endpoint at this moment' );
100
  }
106
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
107
  return new ChangeCartEndpoint( $cart, $shipping, $request_data, $repository, $data_store, $logger );
108
  },
109
+ 'button.endpoint.create-order' => static function ( ContainerInterface $container ): CreateOrderEndpoint {
110
  $request_data = $container->get( 'button.request-data' );
111
  $cart_repository = $container->get( 'api.repository.cart' );
112
  $purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
115
  $session_handler = $container->get( 'session.handler' );
116
  $settings = $container->get( 'wcgateway.settings' );
117
  $early_order_handler = $container->get( 'button.helper.early-order-handler' );
118
+ $registration_needed = $container->get( 'button.current-user-must-register' );
119
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
120
  return new CreateOrderEndpoint(
121
  $request_data,
122
  $cart_repository,
126
  $session_handler,
127
  $settings,
128
  $early_order_handler,
129
+ $registration_needed,
130
  $logger
131
  );
132
  },
133
+ 'button.helper.early-order-handler' => static function ( ContainerInterface $container ) : EarlyOrderHandler {
134
 
135
  $state = $container->get( 'onboarding.state' );
136
  $order_processor = $container->get( 'wcgateway.order-processor' );
138
  $prefix = $container->get( 'api.prefix' );
139
  return new EarlyOrderHandler( $state, $order_processor, $session_handler, $prefix );
140
  },
141
+ 'button.endpoint.approve-order' => static function ( ContainerInterface $container ): ApproveOrderEndpoint {
142
  $request_data = $container->get( 'button.request-data' );
143
  $order_endpoint = $container->get( 'api.endpoint.order' );
144
  $session_handler = $container->get( 'session.handler' );
156
  $logger
157
  );
158
  },
159
+ 'button.endpoint.data-client-id' => static function( ContainerInterface $container ) : DataClientIdEndpoint {
160
  $request_data = $container->get( 'button.request-data' );
161
  $identity_token = $container->get( 'api.endpoint.identity-token' );
162
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
166
  $logger
167
  );
168
  },
169
+ 'button.helper.three-d-secure' => static function ( ContainerInterface $container ): ThreeDSecure {
170
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
171
  return new ThreeDSecure( $logger );
172
  },
173
+ 'button.helper.messages-apply' => static function ( ContainerInterface $container ): MessagesApply {
174
  return new MessagesApply();
175
  },
176
+
177
+ 'button.is-logged-in' => static function ( ContainerInterface $container ): bool {
178
+ return is_user_logged_in();
179
+ },
180
+ 'button.registration-required' => static function ( ContainerInterface $container ): bool {
181
+ return WC()->checkout()->is_registration_required();
182
+ },
183
+ 'button.current-user-must-register' => static function ( ContainerInterface $container ): bool {
184
+ return ! $container->get( 'button.is-logged-in' ) &&
185
+ $container->get( 'button.registration-required' );
186
+ },
187
  );
modules/ppcp-button/src/Assets/{class-disabledsmartbutton.php → DisabledSmartButton.php} RENAMED
File without changes
modules/ppcp-button/src/Assets/{class-smartbutton.php → SmartButton.php} RENAMED
@@ -22,7 +22,7 @@ use WooCommerce\PayPalCommerce\Session\SessionHandler;
22
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
23
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
24
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
25
- use Woocommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
26
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
27
 
28
  /**
@@ -199,14 +199,18 @@ class SmartButton implements SmartButtonInterface {
199
  11
200
  );
201
 
 
202
  add_filter(
203
  'woocommerce_credit_card_form_fields',
204
- function ( $default_fields, $id ) {
205
  if ( is_user_logged_in() && $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) && CreditCardGateway::ID === $id ) {
206
- $default_fields['card-vault'] = sprintf(
207
- '<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>',
208
- esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' )
209
- );
 
 
 
210
 
211
  $tokens = $this->payment_token_repository->all_for_user_id( get_current_user_id() );
212
  if ( $tokens && $this->payment_token_repository->tokens_contains_card( $tokens ) ) {
@@ -728,7 +732,7 @@ class SmartButton implements SmartButtonInterface {
728
  private function payerData() {
729
 
730
  $customer = WC()->customer;
731
- if ( ! is_user_logged_in() || ! is_a( $customer, \WC_Customer::class ) ) {
732
  return null;
733
  }
734
  return $this->payer_factory->from_customer( $customer )->to_array();
@@ -741,6 +745,8 @@ class SmartButton implements SmartButtonInterface {
741
  * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting was not found.
742
  */
743
  private function url(): string {
 
 
744
  $params = array(
745
  'client-id' => $this->client_id,
746
  'currency' => get_woocommerce_currency(),
@@ -748,13 +754,14 @@ class SmartButton implements SmartButtonInterface {
748
  'components' => implode( ',', $this->components() ),
749
  'vault' => $this->can_save_vault_token() ? 'true' : 'false',
750
  'commit' => is_checkout() ? 'true' : 'false',
751
- 'intent' => ( $this->settings->has( 'intent' ) ) ?
752
- $this->settings->get( 'intent' ) : 'capture',
 
753
  );
754
  if (
755
  $this->environment->current_environment_is( Environment::SANDBOX )
756
  && defined( 'WP_DEBUG' ) && \WP_DEBUG && is_user_logged_in()
757
- && WC()->customer && WC()->customer->get_billing_country()
758
  && 2 === strlen( WC()->customer->get_billing_country() )
759
  ) {
760
  $params['buyer-country'] = WC()->customer->get_billing_country();
22
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
23
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
24
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
25
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
26
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
27
 
28
  /**
199
  11
200
  );
201
 
202
+ $subscription_helper = $this->subscription_helper;
203
  add_filter(
204
  'woocommerce_credit_card_form_fields',
205
+ function ( array $default_fields, $id ) use ( $subscription_helper ) : array {
206
  if ( is_user_logged_in() && $this->settings->has( 'vault_enabled' ) && $this->settings->get( 'vault_enabled' ) && CreditCardGateway::ID === $id ) {
207
+
208
+ if ( ! $subscription_helper->cart_contains_subscription() ) {
209
+ $default_fields['card-vault'] = sprintf(
210
+ '<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>',
211
+ esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' )
212
+ );
213
+ }
214
 
215
  $tokens = $this->payment_token_repository->all_for_user_id( get_current_user_id() );
216
  if ( $tokens && $this->payment_token_repository->tokens_contains_card( $tokens ) ) {
732
  private function payerData() {
733
 
734
  $customer = WC()->customer;
735
+ if ( ! is_user_logged_in() || ! ( $customer instanceof \WC_Customer ) ) {
736
  return null;
737
  }
738
  return $this->payer_factory->from_customer( $customer )->to_array();
745
  * @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting was not found.
746
  */
747
  private function url(): string {
748
+ $intent = ( $this->settings->has( 'intent' ) ) ? $this->settings->get( 'intent' ) : 'capture';
749
+
750
  $params = array(
751
  'client-id' => $this->client_id,
752
  'currency' => get_woocommerce_currency(),
754
  'components' => implode( ',', $this->components() ),
755
  'vault' => $this->can_save_vault_token() ? 'true' : 'false',
756
  'commit' => is_checkout() ? 'true' : 'false',
757
+ 'intent' => ( $this->subscription_helper->cart_contains_subscription() || $this->subscription_helper->current_product_is_subscription() )
758
+ ? 'authorize'
759
+ : $intent,
760
  );
761
  if (
762
  $this->environment->current_environment_is( Environment::SANDBOX )
763
  && defined( 'WP_DEBUG' ) && \WP_DEBUG && is_user_logged_in()
764
+ && WC()->customer instanceof \WC_Customer && WC()->customer->get_billing_country()
765
  && 2 === strlen( WC()->customer->get_billing_country() )
766
  ) {
767
  $params['buyer-country'] = WC()->customer->get_billing_country();
modules/ppcp-button/src/Assets/{class-smartbuttoninterface.php → SmartButtonInterface.php} RENAMED
File without changes
modules/ppcp-button/src/{class-buttonmodule.php → ButtonModule.php} RENAMED
@@ -27,9 +27,7 @@ class ButtonModule implements ModuleInterface {
27
 
28
 
29
  /**
30
- * Sets up the module.
31
- *
32
- * @return ServiceProviderInterface
33
  */
34
  public function setup(): ServiceProviderInterface {
35
  return new ServiceProvider(
@@ -39,19 +37,17 @@ class ButtonModule implements ModuleInterface {
39
  }
40
 
41
  /**
42
- * Runs the module.
43
- *
44
- * @param ContainerInterface|null $container The Container.
45
  */
46
- public function run( ContainerInterface $container ): void {
47
 
48
  add_action(
49
  'wp',
50
- static function () use ( $container ) {
51
  if ( is_admin() ) {
52
  return;
53
  }
54
- $smart_button = $container->get( 'button.smart-button' );
55
  /**
56
  * The Smart Button.
57
  *
@@ -62,9 +58,9 @@ class ButtonModule implements ModuleInterface {
62
  );
63
  add_action(
64
  'wp_enqueue_scripts',
65
- static function () use ( $container ) {
66
 
67
- $smart_button = $container->get( 'button.smart-button' );
68
  /**
69
  * The Smart Button.
70
  *
@@ -76,8 +72,8 @@ class ButtonModule implements ModuleInterface {
76
 
77
  add_filter(
78
  'woocommerce_create_order',
79
- static function ( $value ) use ( $container ) {
80
- $early_order_handler = $container->get( 'button.helper.early-order-handler' );
81
  if ( ! is_null( $value ) ) {
82
  $value = (int) $value;
83
  }
@@ -90,7 +86,7 @@ class ButtonModule implements ModuleInterface {
90
  }
91
  );
92
 
93
- $this->register_ajax_endpoints( $container );
94
  }
95
 
96
  /**
27
 
28
 
29
  /**
30
+ * {@inheritDoc}
 
 
31
  */
32
  public function setup(): ServiceProviderInterface {
33
  return new ServiceProvider(
37
  }
38
 
39
  /**
40
+ * {@inheritDoc}
 
 
41
  */
42
+ public function run( ContainerInterface $c ): void {
43
 
44
  add_action(
45
  'wp',
46
+ static function () use ( $c ) {
47
  if ( is_admin() ) {
48
  return;
49
  }
50
+ $smart_button = $c->get( 'button.smart-button' );
51
  /**
52
  * The Smart Button.
53
  *
58
  );
59
  add_action(
60
  'wp_enqueue_scripts',
61
+ static function () use ( $c ) {
62
 
63
+ $smart_button = $c->get( 'button.smart-button' );
64
  /**
65
  * The Smart Button.
66
  *
72
 
73
  add_filter(
74
  'woocommerce_create_order',
75
+ static function ( $value ) use ( $c ) {
76
+ $early_order_handler = $c->get( 'button.helper.early-order-handler' );
77
  if ( ! is_null( $value ) ) {
78
  $value = (int) $value;
79
  }
86
  }
87
  );
88
 
89
+ $this->register_ajax_endpoints( $c );
90
  }
91
 
92
  /**
modules/ppcp-button/src/Endpoint/{class-approveorderendpoint.php → ApproveOrderEndpoint.php} RENAMED
@@ -121,7 +121,7 @@ class ApproveOrderEndpoint implements EndpointInterface {
121
  * Handles the request.
122
  *
123
  * @return bool
124
- * @throws RuntimeException When no order was found.
125
  */
126
  public function handle_request(): bool {
127
  try {
@@ -133,15 +133,6 @@ class ApproveOrderEndpoint implements EndpointInterface {
133
  }
134
 
135
  $order = $this->api_endpoint->order( $data['order_id'] );
136
- if ( ! $order ) {
137
- throw new RuntimeException(
138
- sprintf(
139
- // translators: %s is the id of the order.
140
- __( 'Order %s not found.', 'woocommerce-paypal-payments' ),
141
- $data['order_id']
142
- )
143
- );
144
- }
145
 
146
  if ( $order->payment_source() && $order->payment_source()->card() ) {
147
  if ( $this->settings->has( 'disable_cards' ) ) {
121
  * Handles the request.
122
  *
123
  * @return bool
124
+ * @throws RuntimeException When order not found or handling failed.
125
  */
126
  public function handle_request(): bool {
127
  try {
133
  }
134
 
135
  $order = $this->api_endpoint->order( $data['order_id'] );
 
 
 
 
 
 
 
 
 
136
 
137
  if ( $order->payment_source() && $order->payment_source()->card() ) {
138
  if ( $this->settings->has( 'disable_cards' ) ) {
modules/ppcp-button/src/Endpoint/{class-changecartendpoint.php → ChangeCartEndpoint.php} RENAMED
File without changes
modules/ppcp-button/src/Endpoint/{class-createorderendpoint.php → CreateOrderEndpoint.php} RENAMED
@@ -31,7 +31,6 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
31
  */
32
  class CreateOrderEndpoint implements EndpointInterface {
33
 
34
-
35
  const ENDPOINT = 'ppc-create-order';
36
 
37
  /**
@@ -104,6 +103,13 @@ class CreateOrderEndpoint implements EndpointInterface {
104
  */
105
  private $purchase_units;
106
 
 
 
 
 
 
 
 
107
  /**
108
  * The logger.
109
  *
@@ -122,6 +128,7 @@ class CreateOrderEndpoint implements EndpointInterface {
122
  * @param SessionHandler $session_handler The SessionHandler object.
123
  * @param Settings $settings The Settings object.
124
  * @param EarlyOrderHandler $early_order_handler The EarlyOrderHandler object.
 
125
  * @param LoggerInterface $logger The logger.
126
  */
127
  public function __construct(
@@ -133,6 +140,7 @@ class CreateOrderEndpoint implements EndpointInterface {
133
  SessionHandler $session_handler,
134
  Settings $settings,
135
  EarlyOrderHandler $early_order_handler,
 
136
  LoggerInterface $logger
137
  ) {
138
 
@@ -144,6 +152,7 @@ class CreateOrderEndpoint implements EndpointInterface {
144
  $this->session_handler = $session_handler;
145
  $this->settings = $settings;
146
  $this->early_order_handler = $early_order_handler;
 
147
  $this->logger = $logger;
148
  }
149
 
@@ -160,6 +169,7 @@ class CreateOrderEndpoint implements EndpointInterface {
160
  * Handles the request.
161
  *
162
  * @return bool
 
163
  */
164
  public function handle_request(): bool {
165
  try {
@@ -186,21 +196,31 @@ class CreateOrderEndpoint implements EndpointInterface {
186
  $this->set_bn_code( $data );
187
 
188
  if ( 'checkout' === $data['context'] ) {
189
- if ( isset( $data['createaccount'] ) && '1' === $data['createaccount'] ) {
190
- $this->process_checkout_form_when_creating_account( $data['form'], $wc_order );
 
 
 
191
  }
192
 
193
- $this->process_checkout_form( $data['form'] );
 
 
 
 
 
 
 
194
  }
 
195
  if ( 'pay-now' === $data['context'] && get_option( 'woocommerce_terms_page_id', '' ) !== '' ) {
196
  $this->validate_paynow_form( $data['form'] );
197
  }
198
 
199
- // if we are here so the context is not 'checkout' as it exits before. Therefore, a PayPal order is not created yet.
200
- // It would be a good idea to refactor the checkout process in the future.
201
  $order = $this->create_paypal_order( $wc_order );
202
  wp_send_json_success( $order->to_array() );
203
  return true;
 
204
  } catch ( \RuntimeException $error ) {
205
  $this->logger->error( 'Order creation failed: ' . $error->getMessage() );
206
 
@@ -275,7 +295,7 @@ class CreateOrderEndpoint implements EndpointInterface {
275
  * @throws RuntimeException If create order request fails.
276
  */
277
  private function create_paypal_order( \WC_Order $wc_order = null ): Order {
278
- $needs_shipping = WC()->cart && WC()->cart->needs_shipping();
279
  $shipping_address_is_fix = $needs_shipping && 'checkout' === $this->parsed_request_data['context'];
280
 
281
  return $this->api_endpoint->create(
@@ -320,7 +340,6 @@ class CreateOrderEndpoint implements EndpointInterface {
320
  return $payer;
321
  }
322
 
323
-
324
  /**
325
  * Sets the BN Code for the following request.
326
  *
@@ -354,41 +373,6 @@ class CreateOrderEndpoint implements EndpointInterface {
354
  return $payment_method;
355
  }
356
 
357
- /**
358
- * Prepare the Request parameter and process the checkout form and validate it.
359
- *
360
- * @param string $form_values The values of the form.
361
- *
362
- * @throws Exception On Error.
363
- */
364
- private function process_checkout_form( string $form_values ) {
365
- $form_values = explode( '&', $form_values );
366
-
367
- $parsed_values = array();
368
- foreach ( $form_values as $field ) {
369
- $field = explode( '=', $field );
370
-
371
- if ( count( $field ) !== 2 ) {
372
- continue;
373
- }
374
- $parsed_values[ $field[0] ] = $field[1];
375
- }
376
- $_POST = $parsed_values;
377
- $_REQUEST = $parsed_values;
378
-
379
- add_filter(
380
- 'woocommerce_after_checkout_validation',
381
- array(
382
- $this,
383
- 'after_checkout_validation',
384
- ),
385
- 10,
386
- 2
387
- );
388
- $checkout = \WC()->checkout();
389
- $checkout->process_checkout();
390
- }
391
-
392
  /**
393
  * Checks whether the terms input field is checked.
394
  *
@@ -397,53 +381,10 @@ class CreateOrderEndpoint implements EndpointInterface {
397
  */
398
  private function validate_paynow_form( string $form_values ) {
399
  $parsed_values = wp_parse_args( $form_values );
400
- if ( ! isset( $parsed_values['terms'] ) ) {
401
  throw new \RuntimeException(
402
  __( 'Please read and accept the terms and conditions to proceed with your order.', 'woocommerce-paypal-payments' )
403
  );
404
  }
405
  }
406
-
407
- /**
408
- * Processes checkout and creates the PayPal order after success form validation.
409
- *
410
- * @param string $form_values The values of the form.
411
- * @param \WC_Order|null $wc_order WC order to get data from.
412
- * @throws Exception On Error.
413
- */
414
- private function process_checkout_form_when_creating_account( string $form_values, \WC_Order $wc_order = null ) {
415
- $form_values = explode( '&', $form_values );
416
- $parsed_values = array();
417
- foreach ( $form_values as $field ) {
418
- $field = explode( '=', $field );
419
-
420
- if ( count( $field ) !== 2 ) {
421
- continue;
422
- }
423
- $parsed_values[ $field[0] ] = $field[1];
424
- }
425
- $_POST = $parsed_values;
426
- $_REQUEST = $parsed_values;
427
-
428
- add_action(
429
- 'woocommerce_after_checkout_validation',
430
- function ( array $data, \WP_Error $errors ) use ( $wc_order ) {
431
- if ( ! $errors->errors ) {
432
- try {
433
- $order = $this->create_paypal_order( $wc_order );
434
- } catch ( Exception $exception ) {
435
- $this->logger->error( 'Order creation failed: ' . $exception->getMessage() );
436
- throw $exception;
437
- }
438
- wp_send_json_success( $order->to_array() );
439
- return true;
440
- }
441
- },
442
- 10,
443
- 2
444
- );
445
-
446
- $checkout = \WC()->checkout();
447
- $checkout->process_checkout();
448
- }
449
  }
31
  */
32
  class CreateOrderEndpoint implements EndpointInterface {
33
 
 
34
  const ENDPOINT = 'ppc-create-order';
35
 
36
  /**
103
  */
104
  private $purchase_units;
105
 
106
+ /**
107
+ * Whether a new user must be registered during checkout.
108
+ *
109
+ * @var bool
110
+ */
111
+ private $registration_needed;
112
+
113
  /**
114
  * The logger.
115
  *
128
  * @param SessionHandler $session_handler The SessionHandler object.
129
  * @param Settings $settings The Settings object.
130
  * @param EarlyOrderHandler $early_order_handler The EarlyOrderHandler object.
131
+ * @param bool $registration_needed Whether a new user must be registered during checkout.
132
  * @param LoggerInterface $logger The logger.
133
  */
134
  public function __construct(
140
  SessionHandler $session_handler,
141
  Settings $settings,
142
  EarlyOrderHandler $early_order_handler,
143
+ bool $registration_needed,
144
  LoggerInterface $logger
145
  ) {
146
 
152
  $this->session_handler = $session_handler;
153
  $this->settings = $settings;
154
  $this->early_order_handler = $early_order_handler;
155
+ $this->registration_needed = $registration_needed;
156
  $this->logger = $logger;
157
  }
158
 
169
  * Handles the request.
170
  *
171
  * @return bool
172
+ * @throws Exception On Error.
173
  */
174
  public function handle_request(): bool {
175
  try {
196
  $this->set_bn_code( $data );
197
 
198
  if ( 'checkout' === $data['context'] ) {
199
+ try {
200
+ $order = $this->create_paypal_order( $wc_order );
201
+ } catch ( Exception $exception ) {
202
+ $this->logger->error( 'Order creation failed: ' . $exception->getMessage() );
203
+ throw $exception;
204
  }
205
 
206
+ if (
207
+ ! $this->early_order_handler->should_create_early_order()
208
+ || $this->registration_needed
209
+ || isset( $data['createaccount'] ) && '1' === $data['createaccount'] ) {
210
+ wp_send_json_success( $order->to_array() );
211
+ }
212
+
213
+ $this->early_order_handler->register_for_order( $order );
214
  }
215
+
216
  if ( 'pay-now' === $data['context'] && get_option( 'woocommerce_terms_page_id', '' ) !== '' ) {
217
  $this->validate_paynow_form( $data['form'] );
218
  }
219
 
 
 
220
  $order = $this->create_paypal_order( $wc_order );
221
  wp_send_json_success( $order->to_array() );
222
  return true;
223
+
224
  } catch ( \RuntimeException $error ) {
225
  $this->logger->error( 'Order creation failed: ' . $error->getMessage() );
226
 
295
  * @throws RuntimeException If create order request fails.
296
  */
297
  private function create_paypal_order( \WC_Order $wc_order = null ): Order {
298
+ $needs_shipping = WC()->cart instanceof \WC_Cart && WC()->cart->needs_shipping();
299
  $shipping_address_is_fix = $needs_shipping && 'checkout' === $this->parsed_request_data['context'];
300
 
301
  return $this->api_endpoint->create(
340
  return $payer;
341
  }
342
 
 
343
  /**
344
  * Sets the BN Code for the following request.
345
  *
373
  return $payment_method;
374
  }
375
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  /**
377
  * Checks whether the terms input field is checked.
378
  *
381
  */
382
  private function validate_paynow_form( string $form_values ) {
383
  $parsed_values = wp_parse_args( $form_values );
384
+ if ( isset( $parsed_values['terms-field'] ) && ! isset( $parsed_values['terms'] ) ) {
385
  throw new \RuntimeException(
386
  __( 'Please read and accept the terms and conditions to proceed with your order.', 'woocommerce-paypal-payments' )
387
  );
388
  }
389
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  }
modules/ppcp-button/src/Endpoint/{class-dataclientidendpoint.php → DataClientIdEndpoint.php} RENAMED
File without changes
modules/ppcp-button/src/Endpoint/{class-endpointinterface.php → EndpointInterface.php} RENAMED
File without changes
modules/ppcp-button/src/Endpoint/{class-requestdata.php → RequestData.php} RENAMED
File without changes
modules/ppcp-button/src/Exception/{class-runtimeexception.php → RuntimeException.php} RENAMED
File without changes
modules/ppcp-button/src/Helper/{class-earlyorderhandler.php → EarlyOrderHandler.php} RENAMED
File without changes
modules/ppcp-button/src/Helper/{class-messagesapply.php → MessagesApply.php} RENAMED
File without changes
modules/ppcp-button/src/Helper/{class-messagesdisclaimers.php → MessagesDisclaimers.php} RENAMED
File without changes
modules/ppcp-button/src/Helper/{class-threedsecure.php → ThreeDSecure.php} RENAMED
File without changes
modules/ppcp-compat/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-compat",
3
+ "type": "dhii-mod",
4
+ "description": "Compatibility module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Compat\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-compat/services.php CHANGED
@@ -9,6 +9,8 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Compat;
11
 
 
 
12
  return array(
13
 
14
  'compat.ppec.mock-gateway' => static function( $container ) {
@@ -23,7 +25,7 @@ return array(
23
  return new PPEC\MockGateway( $title );
24
  },
25
 
26
- 'compat.ppec.subscriptions-handler' => static function ( $container ) {
27
  $ppcp_renewal_handler = $container->get( 'subscription.renewal-handler' );
28
  $gateway = $container->get( 'compat.ppec.mock-gateway' );
29
 
9
 
10
  namespace WooCommerce\PayPalCommerce\Compat;
11
 
12
+ use Psr\Container\ContainerInterface;
13
+
14
  return array(
15
 
16
  'compat.ppec.mock-gateway' => static function( $container ) {
25
  return new PPEC\MockGateway( $title );
26
  },
27
 
28
+ 'compat.ppec.subscriptions-handler' => static function ( ContainerInterface $container ) {
29
  $ppcp_renewal_handler = $container->get( 'subscription.renewal-handler' );
30
  $gateway = $container->get( 'compat.ppec.mock-gateway' );
31
 
modules/ppcp-compat/src/{class-compatmodule.php → CompatModule.php} RENAMED
@@ -35,10 +35,10 @@ class CompatModule implements ModuleInterface {
35
  /**
36
  * Run the compatibility module.
37
  *
38
- * @param ContainerInterface|null $container The Container.
39
  */
40
- public function run( ContainerInterface $container ): void {
41
- $this->initialize_ppec_compat_layer( $container );
42
  }
43
 
44
  /**
35
  /**
36
  * Run the compatibility module.
37
  *
38
+ * @param ContainerInterface|null $c The Container.
39
  */
40
+ public function run( ContainerInterface $c ): void {
41
+ $this->initialize_ppec_compat_layer( $c );
42
  }
43
 
44
  /**
modules/ppcp-compat/src/PPEC/{class-deactivatenote.php → DeactivateNote.php} RENAMED
File without changes
modules/ppcp-compat/src/PPEC/{class-mockgateway.php → MockGateway.php} RENAMED
File without changes
modules/ppcp-compat/src/PPEC/{class-ppechelper.php → PPECHelper.php} RENAMED
@@ -44,7 +44,12 @@ class PPECHelper {
44
  * @return bool
45
  */
46
  public static function is_gateway_available() {
47
- return self::is_plugin_active() && is_callable( 'wc_gateway_ppec' ) && wc_gateway_ppec()->settings->get_active_api_credentials();
 
 
 
 
 
48
  }
49
 
50
  /**
44
  * @return bool
45
  */
46
  public static function is_gateway_available() {
47
+ if ( ! self::is_plugin_active() || ! is_callable( 'wc_gateway_ppec' ) ) {
48
+ return false;
49
+ }
50
+
51
+ $ppec = wc_gateway_ppec();
52
+ return is_object( $ppec ) && $ppec->settings && $ppec->settings->get_active_api_credentials();
53
  }
54
 
55
  /**
modules/ppcp-compat/src/PPEC/{class-settingsimporter.php → SettingsImporter.php} RENAMED
File without changes
modules/ppcp-compat/src/PPEC/{class-subscriptionshandler.php → SubscriptionsHandler.php} RENAMED
File without changes
modules/ppcp-onboarding/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-onboarding",
3
+ "type": "dhii-mod",
4
+ "description": "Onboarding module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Onboarding\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-onboarding/services.php CHANGED
@@ -9,6 +9,7 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Onboarding;
11
 
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\ConnectBearer;
14
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
@@ -18,10 +19,10 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
18
  use WooCommerce\PayPalCommerce\Onboarding\Assets\OnboardingAssets;
19
  use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
20
  use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
21
- use WooCommerce\PayPalCommerce\Onboarding\Onboarding_REST_Controller;
22
 
23
  return array(
24
- 'api.sandbox-host' => static function ( $container ): string {
25
 
26
  $state = $container->get( 'onboarding.state' );
27
 
@@ -35,7 +36,7 @@ return array(
35
  }
36
  return CONNECT_WOO_SANDBOX_URL;
37
  },
38
- 'api.production-host' => static function ( $container ): string {
39
 
40
  $state = $container->get( 'onboarding.state' );
41
 
@@ -50,7 +51,7 @@ return array(
50
  }
51
  return CONNECT_WOO_URL;
52
  },
53
- 'api.host' => static function ( $container ): string {
54
  $environment = $container->get( 'onboarding.environment' );
55
 
56
  /**
@@ -62,19 +63,19 @@ return array(
62
  ? (string) $container->get( 'api.sandbox-host' ) : (string) $container->get( 'api.production-host' );
63
 
64
  },
65
- 'api.paypal-host-production' => static function( $container ) : string {
66
  return PAYPAL_API_URL;
67
  },
68
- 'api.paypal-host-sandbox' => static function( $container ) : string {
69
  return PAYPAL_SANDBOX_API_URL;
70
  },
71
- 'api.partner_merchant_id-production' => static function( $container ) : string {
72
  return CONNECT_WOO_MERCHANT_ID;
73
  },
74
- 'api.partner_merchant_id-sandbox' => static function( $container ) : string {
75
  return CONNECT_WOO_SANDBOX_MERCHANT_ID;
76
  },
77
- 'api.paypal-host' => function( $container ) : string {
78
  $environment = $container->get( 'onboarding.environment' );
79
  /**
80
  * The current environment.
@@ -88,7 +89,7 @@ return array(
88
 
89
  },
90
 
91
- 'api.bearer' => static function ( $container ): Bearer {
92
 
93
  $state = $container->get( 'onboarding.state' );
94
 
@@ -115,17 +116,17 @@ return array(
115
  $settings
116
  );
117
  },
118
- 'onboarding.state' => function( $container ) : State {
119
  $environment = $container->get( 'onboarding.environment' );
120
  $settings = $container->get( 'wcgateway.settings' );
121
  return new State( $environment, $settings );
122
  },
123
- 'onboarding.environment' => function( $container ) : Environment {
124
  $settings = $container->get( 'wcgateway.settings' );
125
  return new Environment( $settings );
126
  },
127
 
128
- 'onboarding.assets' => function( $container ) : OnboardingAssets {
129
  $state = $container->get( 'onboarding.state' );
130
  $login_seller_endpoint = $container->get( 'onboarding.endpoint.login-seller' );
131
  return new OnboardingAssets(
@@ -135,14 +136,14 @@ return array(
135
  );
136
  },
137
 
138
- 'onboarding.url' => static function ( $container ): string {
139
  return plugins_url(
140
  '/modules/ppcp-onboarding/',
141
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
142
  );
143
  },
144
 
145
- 'api.endpoint.login-seller-production' => static function ( $container ) : LoginSeller {
146
 
147
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
148
  return new LoginSeller(
@@ -152,7 +153,7 @@ return array(
152
  );
153
  },
154
 
155
- 'api.endpoint.login-seller-sandbox' => static function ( $container ) : LoginSeller {
156
 
157
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
158
  return new LoginSeller(
@@ -162,7 +163,7 @@ return array(
162
  );
163
  },
164
 
165
- 'onboarding.endpoint.login-seller' => static function ( $container ) : LoginSellerEndpoint {
166
 
167
  $request_data = $container->get( 'button.request-data' );
168
  $login_seller_production = $container->get( 'api.endpoint.login-seller-production' );
@@ -182,7 +183,7 @@ return array(
182
  $logger
183
  );
184
  },
185
- 'api.endpoint.partner-referrals-sandbox' => static function ( $container ) : PartnerReferrals {
186
 
187
  return new PartnerReferrals(
188
  CONNECT_WOO_SANDBOX_URL,
@@ -191,7 +192,7 @@ return array(
191
  $container->get( 'woocommerce.logger.woocommerce' )
192
  );
193
  },
194
- 'api.endpoint.partner-referrals-production' => static function ( $container ) : PartnerReferrals {
195
 
196
  return new PartnerReferrals(
197
  CONNECT_WOO_URL,
@@ -200,7 +201,7 @@ return array(
200
  $container->get( 'woocommerce.logger.woocommerce' )
201
  );
202
  },
203
- 'onboarding.render' => static function ( $container ) : OnboardingRenderer {
204
 
205
  $partner_referrals = $container->get( 'api.endpoint.partner-referrals-production' );
206
  $partner_referrals_sandbox = $container->get( 'api.endpoint.partner-referrals-sandbox' );
@@ -211,7 +212,7 @@ return array(
211
  $partner_referrals_sandbox
212
  );
213
  },
214
- 'onboarding.rest' => static function( $container ) : Onboarding_REST_Controller {
215
- return new Onboarding_REST_Controller( $container );
216
  },
217
  );
9
 
10
  namespace WooCommerce\PayPalCommerce\Onboarding;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
14
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\ConnectBearer;
15
  use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
19
  use WooCommerce\PayPalCommerce\Onboarding\Assets\OnboardingAssets;
20
  use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
21
  use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
22
+ use WooCommerce\PayPalCommerce\Onboarding\OnboardingRESTController;
23
 
24
  return array(
25
+ 'api.sandbox-host' => static function ( ContainerInterface $container ): string {
26
 
27
  $state = $container->get( 'onboarding.state' );
28
 
36
  }
37
  return CONNECT_WOO_SANDBOX_URL;
38
  },
39
+ 'api.production-host' => static function ( ContainerInterface $container ): string {
40
 
41
  $state = $container->get( 'onboarding.state' );
42
 
51
  }
52
  return CONNECT_WOO_URL;
53
  },
54
+ 'api.host' => static function ( ContainerInterface $container ): string {
55
  $environment = $container->get( 'onboarding.environment' );
56
 
57
  /**
63
  ? (string) $container->get( 'api.sandbox-host' ) : (string) $container->get( 'api.production-host' );
64
 
65
  },
66
+ 'api.paypal-host-production' => static function( ContainerInterface $container ) : string {
67
  return PAYPAL_API_URL;
68
  },
69
+ 'api.paypal-host-sandbox' => static function( ContainerInterface $container ) : string {
70
  return PAYPAL_SANDBOX_API_URL;
71
  },
72
+ 'api.partner_merchant_id-production' => static function( ContainerInterface $container ) : string {
73
  return CONNECT_WOO_MERCHANT_ID;
74
  },
75
+ 'api.partner_merchant_id-sandbox' => static function( ContainerInterface $container ) : string {
76
  return CONNECT_WOO_SANDBOX_MERCHANT_ID;
77
  },
78
+ 'api.paypal-host' => function( ContainerInterface $container ) : string {
79
  $environment = $container->get( 'onboarding.environment' );
80
  /**
81
  * The current environment.
89
 
90
  },
91
 
92
+ 'api.bearer' => static function ( ContainerInterface $container ): Bearer {
93
 
94
  $state = $container->get( 'onboarding.state' );
95
 
116
  $settings
117
  );
118
  },
119
+ 'onboarding.state' => function( ContainerInterface $container ) : State {
120
  $environment = $container->get( 'onboarding.environment' );
121
  $settings = $container->get( 'wcgateway.settings' );
122
  return new State( $environment, $settings );
123
  },
124
+ 'onboarding.environment' => function( ContainerInterface $container ) : Environment {
125
  $settings = $container->get( 'wcgateway.settings' );
126
  return new Environment( $settings );
127
  },
128
 
129
+ 'onboarding.assets' => function( ContainerInterface $container ) : OnboardingAssets {
130
  $state = $container->get( 'onboarding.state' );
131
  $login_seller_endpoint = $container->get( 'onboarding.endpoint.login-seller' );
132
  return new OnboardingAssets(
136
  );
137
  },
138
 
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
 
146
+ 'api.endpoint.login-seller-production' => static function ( ContainerInterface $container ) : LoginSeller {
147
 
148
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
149
  return new LoginSeller(
153
  );
154
  },
155
 
156
+ 'api.endpoint.login-seller-sandbox' => static function ( ContainerInterface $container ) : LoginSeller {
157
 
158
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
159
  return new LoginSeller(
163
  );
164
  },
165
 
166
+ 'onboarding.endpoint.login-seller' => static function ( ContainerInterface $container ) : LoginSellerEndpoint {
167
 
168
  $request_data = $container->get( 'button.request-data' );
169
  $login_seller_production = $container->get( 'api.endpoint.login-seller-production' );
183
  $logger
184
  );
185
  },
186
+ 'api.endpoint.partner-referrals-sandbox' => static function ( ContainerInterface $container ) : PartnerReferrals {
187
 
188
  return new PartnerReferrals(
189
  CONNECT_WOO_SANDBOX_URL,
192
  $container->get( 'woocommerce.logger.woocommerce' )
193
  );
194
  },
195
+ 'api.endpoint.partner-referrals-production' => static function ( ContainerInterface $container ) : PartnerReferrals {
196
 
197
  return new PartnerReferrals(
198
  CONNECT_WOO_URL,
201
  $container->get( 'woocommerce.logger.woocommerce' )
202
  );
203
  },
204
+ 'onboarding.render' => static function ( ContainerInterface $container ) : OnboardingRenderer {
205
 
206
  $partner_referrals = $container->get( 'api.endpoint.partner-referrals-production' );
207
  $partner_referrals_sandbox = $container->get( 'api.endpoint.partner-referrals-sandbox' );
212
  $partner_referrals_sandbox
213
  );
214
  },
215
+ 'onboarding.rest' => static function( $container ) : OnboardingRESTController {
216
+ return new OnboardingRESTController( $container );
217
  },
218
  );
modules/ppcp-onboarding/src/Assets/{class-onboardingassets.php → OnboardingAssets.php} RENAMED
File without changes
modules/ppcp-onboarding/src/Endpoint/{class-loginsellerendpoint.php → LoginSellerEndpoint.php} RENAMED
File without changes
modules/ppcp-onboarding/src/{class-environment.php → Environment.php} RENAMED
File without changes
modules/ppcp-onboarding/src/{class-onboardingmodule.php → OnboardingModule.php} RENAMED
@@ -24,9 +24,7 @@ use Psr\Container\ContainerInterface;
24
  class OnboardingModule implements ModuleInterface {
25
 
26
  /**
27
- * Sets up the module.
28
- *
29
- * @return ServiceProviderInterface
30
  */
31
  public function setup(): ServiceProviderInterface {
32
  return new ServiceProvider(
@@ -36,13 +34,11 @@ class OnboardingModule implements ModuleInterface {
36
  }
37
 
38
  /**
39
- * Runs the module.
40
- *
41
- * @param ContainerInterface|null $container The container.
42
  */
43
- public function run( ContainerInterface $container ): void {
44
 
45
- $asset_loader = $container->get( 'onboarding.assets' );
46
  /**
47
  * The OnboardingAssets.
48
  *
@@ -65,11 +61,11 @@ class OnboardingModule implements ModuleInterface {
65
 
66
  add_filter(
67
  'woocommerce_form_field',
68
- static function ( $field, $key, $config ) use ( $container ) {
69
  if ( 'ppcp_onboarding' !== $config['type'] ) {
70
  return $field;
71
  }
72
- $renderer = $container->get( 'onboarding.render' );
73
  $is_production = 'production' === $config['env'];
74
 
75
  /**
@@ -89,8 +85,8 @@ class OnboardingModule implements ModuleInterface {
89
 
90
  add_action(
91
  'wc_ajax_' . LoginSellerEndpoint::ENDPOINT,
92
- static function () use ( $container ) {
93
- $endpoint = $container->get( 'onboarding.endpoint.login-seller' );
94
 
95
  /**
96
  * The ChangeCartEndpoint.
@@ -102,7 +98,7 @@ class OnboardingModule implements ModuleInterface {
102
  );
103
 
104
  // Initialize REST routes at the appropriate time.
105
- $rest_controller = $container->get( 'onboarding.rest' );
106
  add_action( 'rest_api_init', array( $rest_controller, 'register_routes' ) );
107
  }
108
 
24
  class OnboardingModule implements ModuleInterface {
25
 
26
  /**
27
+ * {@inheritDoc}
 
 
28
  */
29
  public function setup(): ServiceProviderInterface {
30
  return new ServiceProvider(
34
  }
35
 
36
  /**
37
+ * {@inheritDoc}
 
 
38
  */
39
+ public function run( ContainerInterface $c ): void {
40
 
41
+ $asset_loader = $c->get( 'onboarding.assets' );
42
  /**
43
  * The OnboardingAssets.
44
  *
61
 
62
  add_filter(
63
  'woocommerce_form_field',
64
+ static function ( $field, $key, $config ) use ( $c ) {
65
  if ( 'ppcp_onboarding' !== $config['type'] ) {
66
  return $field;
67
  }
68
+ $renderer = $c->get( 'onboarding.render' );
69
  $is_production = 'production' === $config['env'];
70
 
71
  /**
85
 
86
  add_action(
87
  'wc_ajax_' . LoginSellerEndpoint::ENDPOINT,
88
+ static function () use ( $c ) {
89
+ $endpoint = $c->get( 'onboarding.endpoint.login-seller' );
90
 
91
  /**
92
  * The ChangeCartEndpoint.
98
  );
99
 
100
  // Initialize REST routes at the appropriate time.
101
+ $rest_controller = $c->get( 'onboarding.rest' );
102
  add_action( 'rest_api_init', array( $rest_controller, 'register_routes' ) );
103
  }
104
 
modules/ppcp-onboarding/src/{class-onboarding-rest-controller.php → OnboardingRESTController.php} RENAMED
@@ -16,7 +16,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
16
  /**
17
  * Exposes and handles REST routes related to onboarding.
18
  */
19
- class Onboarding_REST_Controller {
20
 
21
  /**
22
  * REST namespace.
16
  /**
17
  * Exposes and handles REST routes related to onboarding.
18
  */
19
+ class OnboardingRESTController {
20
 
21
  /**
22
  * REST namespace.
modules/ppcp-onboarding/src/Render/{class-onboardingrenderer.php → OnboardingRenderer.php} RENAMED
File without changes
modules/ppcp-onboarding/src/{class-state.php → State.php} RENAMED
File without changes
modules/ppcp-session/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-session",
3
+ "type": "dhii-mod",
4
+ "description": "Session module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Session\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-session/services.php CHANGED
@@ -9,12 +9,12 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Session;
11
 
12
- use Dhii\Data\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\Session\Cancellation\CancelController;
14
  use WooCommerce\PayPalCommerce\Session\Cancellation\CancelView;
15
 
16
  return array(
17
- 'session.handler' => function ( $container ) : SessionHandler {
18
 
19
  if ( is_null( WC()->session ) ) {
20
  return new SessionHandler();
@@ -27,10 +27,10 @@ return array(
27
  WC()->session->set( SessionHandler::ID, $session_handler );
28
  return $session_handler;
29
  },
30
- 'session.cancellation.view' => function ( $container ) : CancelView {
31
  return new CancelView();
32
  },
33
- 'session.cancellation.controller' => function ( $container ) : CancelController {
34
  return new CancelController(
35
  $container->get( 'session.handler' ),
36
  $container->get( 'session.cancellation.view' )
9
 
10
  namespace WooCommerce\PayPalCommerce\Session;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\Session\Cancellation\CancelController;
14
  use WooCommerce\PayPalCommerce\Session\Cancellation\CancelView;
15
 
16
  return array(
17
+ 'session.handler' => function ( ContainerInterface $container ) : SessionHandler {
18
 
19
  if ( is_null( WC()->session ) ) {
20
  return new SessionHandler();
27
  WC()->session->set( SessionHandler::ID, $session_handler );
28
  return $session_handler;
29
  },
30
+ 'session.cancellation.view' => function ( ContainerInterface $container ) : CancelView {
31
  return new CancelView();
32
  },
33
+ 'session.cancellation.controller' => function ( ContainerInterface $container ) : CancelController {
34
  return new CancelController(
35
  $container->get( 'session.handler' ),
36
  $container->get( 'session.cancellation.view' )
modules/ppcp-session/src/Cancellation/{class-cancelcontroller.php → CancelController.php} RENAMED
File without changes
modules/ppcp-session/src/Cancellation/{class-cancelview.php → CancelView.php} RENAMED
File without changes
modules/ppcp-session/src/{class-sessionhandler.php → SessionHandler.php} RENAMED
File without changes
modules/ppcp-session/src/{class-sessionmodule.php → SessionModule.php} RENAMED
@@ -21,9 +21,7 @@ use Psr\Container\ContainerInterface;
21
  class SessionModule implements ModuleInterface {
22
 
23
  /**
24
- * Sets up the module.
25
- *
26
- * @return ServiceProviderInterface
27
  */
28
  public function setup(): ServiceProviderInterface {
29
  return new ServiceProvider(
@@ -33,15 +31,13 @@ class SessionModule implements ModuleInterface {
33
  }
34
 
35
  /**
36
- * Run the module.
37
- *
38
- * @param ContainerInterface|null $container The container.
39
  */
40
- public function run( ContainerInterface $container ): void {
41
  add_action(
42
  'woocommerce_init',
43
- function () use ( $container ) {
44
- $controller = $container->get( 'session.cancellation.controller' );
45
  /**
46
  * The Cancel controller.
47
  *
21
  class SessionModule implements ModuleInterface {
22
 
23
  /**
24
+ * {@inheritDoc}
 
 
25
  */
26
  public function setup(): ServiceProviderInterface {
27
  return new ServiceProvider(
31
  }
32
 
33
  /**
34
+ * {@inheritDoc}
 
 
35
  */
36
+ public function run( ContainerInterface $c ): void {
37
  add_action(
38
  'woocommerce_init',
39
+ function () use ( $c ) {
40
+ $controller = $c->get( 'session.cancellation.controller' );
41
  /**
42
  * The Cancel controller.
43
  *
modules/ppcp-status-report/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-status-report",
3
+ "type": "dhii-mod",
4
+ "description": "Status report module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\StatusReport\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-status-report/services.php CHANGED
@@ -10,7 +10,7 @@ declare(strict_types=1);
10
  namespace WooCommerce\PayPalCommerce\StatusReport;
11
 
12
  return array(
13
- 'status-report.renderer' => static function ( $container ): Renderer {
14
  return new Renderer();
15
  },
16
  );
10
  namespace WooCommerce\PayPalCommerce\StatusReport;
11
 
12
  return array(
13
+ 'status-report.renderer' => static function (): Renderer {
14
  return new Renderer();
15
  },
16
  );
modules/ppcp-status-report/src/{class-renderer.php → Renderer.php} RENAMED
File without changes
modules/ppcp-status-report/src/{class-statusreportmodule.php → StatusReportModule.php} RENAMED
@@ -38,27 +38,27 @@ class StatusReportModule implements ModuleInterface {
38
  /**
39
  * {@inheritDoc}
40
  *
41
- * @param ContainerInterface $container A services container instance.
42
  */
43
- public function run( ContainerInterface $container ): void {
44
  add_action(
45
  'woocommerce_system_status_report',
46
- function () use ( $container ) {
47
 
48
  /* @var State $state The state. */
49
- $state = $container->get( 'onboarding.state' );
50
 
51
  /* @var Bearer $bearer The bearer. */
52
- $bearer = $container->get( 'api.bearer' );
53
 
54
  /* @var DccApplies $dcc_applies The ddc applies. */
55
- $dcc_applies = $container->get( 'api.helpers.dccapplies' );
56
 
57
  /* @var MessagesApply $messages_apply The messages apply. */
58
- $messages_apply = $container->get( 'button.helper.messages-apply' );
59
 
60
  /* @var Renderer $renderer The renderer. */
61
- $renderer = $container->get( 'status-report.renderer' );
62
 
63
  $items = array(
64
  array(
38
  /**
39
  * {@inheritDoc}
40
  *
41
+ * @param ContainerInterface $c A services container instance.
42
  */
43
+ public function run( ContainerInterface $c ): void {
44
  add_action(
45
  'woocommerce_system_status_report',
46
+ function () use ( $c ) {
47
 
48
  /* @var State $state The state. */
49
+ $state = $c->get( 'onboarding.state' );
50
 
51
  /* @var Bearer $bearer The bearer. */
52
+ $bearer = $c->get( 'api.bearer' );
53
 
54
  /* @var DccApplies $dcc_applies The ddc applies. */
55
+ $dcc_applies = $c->get( 'api.helpers.dccapplies' );
56
 
57
  /* @var MessagesApply $messages_apply The messages apply. */
58
+ $messages_apply = $c->get( 'button.helper.messages-apply' );
59
 
60
  /* @var Renderer $renderer The renderer. */
61
+ $renderer = $c->get( 'status-report.renderer' );
62
 
63
  $items = array(
64
  array(
modules/ppcp-subscription/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-subscription",
3
+ "type": "dhii-mod",
4
+ "description": "Subscription module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Subscription\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-subscription/services.php CHANGED
@@ -10,12 +10,14 @@ declare(strict_types=1);
10
  namespace WooCommerce\PayPalCommerce\Subscription;
11
 
12
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
 
 
13
 
14
  return array(
15
- 'subscription.helper' => static function ( $container ): SubscriptionHelper {
16
  return new SubscriptionHelper();
17
  },
18
- 'subscription.renewal-handler' => static function ( $container ): RenewalHandler {
19
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
20
  $repository = $container->get( 'vaulting.repository.payment-token' );
21
  $endpoint = $container->get( 'api.endpoint.order' );
@@ -29,4 +31,9 @@ return array(
29
  $payer_factory
30
  );
31
  },
 
 
 
 
 
32
  );
10
  namespace WooCommerce\PayPalCommerce\Subscription;
11
 
12
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
13
+ use Psr\Container\ContainerInterface;
14
+ use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
15
 
16
  return array(
17
+ 'subscription.helper' => static function ( ContainerInterface $container ): SubscriptionHelper {
18
  return new SubscriptionHelper();
19
  },
20
+ 'subscription.renewal-handler' => static function ( ContainerInterface $container ): RenewalHandler {
21
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
22
  $repository = $container->get( 'vaulting.repository.payment-token' );
23
  $endpoint = $container->get( 'api.endpoint.order' );
31
  $payer_factory
32
  );
33
  },
34
+ 'subscription.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository {
35
+ $factory = $container->get( 'api.factory.payment-token' );
36
+ $endpoint = $container->get( 'api.endpoint.payment-token' );
37
+ return new PaymentTokenRepository( $factory, $endpoint );
38
+ },
39
  );
modules/ppcp-subscription/src/Helper/{class-subscriptionhelper.php → SubscriptionHelper.php} RENAMED
@@ -47,7 +47,7 @@ class SubscriptionHelper {
47
  if ( ! isset( $item['data'] ) || ! is_a( $item['data'], \WC_Product::class ) ) {
48
  continue;
49
  }
50
- if ( $item['data']->is_type( 'subscription' ) ) {
51
  return true;
52
  }
53
  }
47
  if ( ! isset( $item['data'] ) || ! is_a( $item['data'], \WC_Product::class ) ) {
48
  continue;
49
  }
50
+ if ( $item['data']->is_type( 'subscription' ) || $item['data']->is_type( 'subscription_variation' ) ) {
51
  return true;
52
  }
53
  }
modules/ppcp-subscription/src/{class-renewalhandler.php → RenewalHandler.php} RENAMED
@@ -18,6 +18,7 @@ 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
 
22
  /**
23
  * Class RenewalHandler
@@ -240,7 +241,7 @@ class RenewalHandler {
240
 
241
  if ( $order->intent() === 'AUTHORIZE' ) {
242
  $this->order_endpoint->authorize( $order );
243
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
244
  }
245
  }
246
  }
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
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
  }
modules/ppcp-subscription/src/{class-subscriptionmodule.php → SubscriptionModule.php} RENAMED
@@ -28,9 +28,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
28
  class SubscriptionModule implements ModuleInterface {
29
 
30
  /**
31
- * Setup the module.
32
- *
33
- * @return ServiceProviderInterface
34
  */
35
  public function setup(): ServiceProviderInterface {
36
  return new ServiceProvider(
@@ -40,15 +38,13 @@ class SubscriptionModule implements ModuleInterface {
40
  }
41
 
42
  /**
43
- * Runs the module.
44
- *
45
- * @param ContainerInterface|null $container The container.
46
  */
47
- public function run( ContainerInterface $container ): void {
48
  add_action(
49
  'woocommerce_scheduled_subscription_payment_' . PayPalGateway::ID,
50
- function ( $amount, $order ) use ( $container ) {
51
- $this->renew( $order, $container );
52
  },
53
  10,
54
  2
@@ -56,8 +52,8 @@ class SubscriptionModule implements ModuleInterface {
56
 
57
  add_action(
58
  'woocommerce_scheduled_subscription_payment_' . CreditCardGateway::ID,
59
- function ( $amount, $order ) use ( $container ) {
60
- $this->renew( $order, $container );
61
  },
62
  10,
63
  2
@@ -65,9 +61,9 @@ class SubscriptionModule implements ModuleInterface {
65
 
66
  add_action(
67
  'woocommerce_subscription_payment_complete',
68
- function ( $subscription ) use ( $container ) {
69
- $payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
70
- $logger = $container->get( 'woocommerce.logger.woocommerce' );
71
 
72
  $this->add_payment_token_id( $subscription, $payment_token_repository, $logger );
73
  }
@@ -75,10 +71,10 @@ class SubscriptionModule implements ModuleInterface {
75
 
76
  add_filter(
77
  'woocommerce_gateway_description',
78
- function ( $description, $id ) use ( $container ) {
79
- $payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
80
- $settings = $container->get( 'wcgateway.settings' );
81
- $subscription_helper = $container->get( 'subscription.helper' );
82
 
83
  return $this->display_saved_paypal_payments( $settings, (string) $id, $payment_token_repository, (string) $description, $subscription_helper );
84
  },
@@ -88,10 +84,10 @@ class SubscriptionModule implements ModuleInterface {
88
 
89
  add_filter(
90
  'woocommerce_credit_card_form_fields',
91
- function ( $default_fields, $id ) use ( $container ) {
92
- $payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
93
- $settings = $container->get( 'wcgateway.settings' );
94
- $subscription_helper = $container->get( 'subscription.helper' );
95
 
96
  return $this->display_saved_credit_cards( $settings, $id, $payment_token_repository, $default_fields, $subscription_helper );
97
  },
@@ -116,7 +112,7 @@ class SubscriptionModule implements ModuleInterface {
116
  * @return void
117
  */
118
  protected function renew( $order, $container ) {
119
- if ( ! is_a( $order, \WC_Order::class ) ) {
120
  return;
121
  }
122
 
28
  class SubscriptionModule implements ModuleInterface {
29
 
30
  /**
31
+ * {@inheritDoc}
 
 
32
  */
33
  public function setup(): ServiceProviderInterface {
34
  return new ServiceProvider(
38
  }
39
 
40
  /**
41
+ * {@inheritDoc}
 
 
42
  */
43
+ public function run( ContainerInterface $c ): void {
44
  add_action(
45
  'woocommerce_scheduled_subscription_payment_' . PayPalGateway::ID,
46
+ function ( $amount, $order ) use ( $c ) {
47
+ $this->renew( $order, $c );
48
  },
49
  10,
50
  2
52
 
53
  add_action(
54
  'woocommerce_scheduled_subscription_payment_' . CreditCardGateway::ID,
55
+ function ( $amount, $order ) use ( $c ) {
56
+ $this->renew( $order, $c );
57
  },
58
  10,
59
  2
61
 
62
  add_action(
63
  'woocommerce_subscription_payment_complete',
64
+ function ( $subscription ) use ( $c ) {
65
+ $payment_token_repository = $c->get( 'vaulting.repository.payment-token' );
66
+ $logger = $c->get( 'woocommerce.logger.woocommerce' );
67
 
68
  $this->add_payment_token_id( $subscription, $payment_token_repository, $logger );
69
  }
71
 
72
  add_filter(
73
  'woocommerce_gateway_description',
74
+ function ( $description, $id ) use ( $c ) {
75
+ $payment_token_repository = $c->get( 'vaulting.repository.payment-token' );
76
+ $settings = $c->get( 'wcgateway.settings' );
77
+ $subscription_helper = $c->get( 'subscription.helper' );
78
 
79
  return $this->display_saved_paypal_payments( $settings, (string) $id, $payment_token_repository, (string) $description, $subscription_helper );
80
  },
84
 
85
  add_filter(
86
  'woocommerce_credit_card_form_fields',
87
+ function ( $default_fields, $id ) use ( $c ) {
88
+ $payment_token_repository = $c->get( 'vaulting.repository.payment-token' );
89
+ $settings = $c->get( 'wcgateway.settings' );
90
+ $subscription_helper = $c->get( 'subscription.helper' );
91
 
92
  return $this->display_saved_credit_cards( $settings, $id, $payment_token_repository, $default_fields, $subscription_helper );
93
  },
112
  * @return void
113
  */
114
  protected function renew( $order, $container ) {
115
+ if ( ! ( $order instanceof \WC_Order ) ) {
116
  return;
117
  }
118
 
modules/ppcp-vaulting/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-vaulting",
3
+ "type": "dhii-mod",
4
+ "description": "Vaulting module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Vaulting\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-vaulting/services.php CHANGED
@@ -9,17 +9,18 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\Vaulting;
11
 
 
12
  use WooCommerce\PayPalCommerce\Vaulting\Assets\MyAccountPaymentsAssets;
13
  use WooCommerce\PayPalCommerce\Vaulting\Endpoint\DeletePaymentTokenEndpoint;
14
 
15
  return array(
16
- 'vaulting.module-url' => static function ( $container ): string {
17
  return plugins_url(
18
  '/modules/ppcp-vaulting/',
19
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
20
  );
21
  },
22
- 'vaulting.assets.myaccount-payments' => function( $container ) : MyAccountPaymentsAssets {
23
  return new MyAccountPaymentsAssets(
24
  $container->get( 'vaulting.module-url' )
25
  );
@@ -27,12 +28,12 @@ return array(
27
  'vaulting.payment-tokens-renderer' => static function (): PaymentTokensRenderer {
28
  return new PaymentTokensRenderer();
29
  },
30
- 'vaulting.repository.payment-token' => static function ( $container ): PaymentTokenRepository {
31
  $factory = $container->get( 'api.factory.payment-token' );
32
  $endpoint = $container->get( 'api.endpoint.payment-token' );
33
  return new PaymentTokenRepository( $factory, $endpoint );
34
  },
35
- 'vaulting.endpoint.delete' => function( $container ) : DeletePaymentTokenEndpoint {
36
  return new DeletePaymentTokenEndpoint(
37
  $container->get( 'vaulting.repository.payment-token' ),
38
  $container->get( 'button.request-data' ),
9
 
10
  namespace WooCommerce\PayPalCommerce\Vaulting;
11
 
12
+ use Psr\Container\ContainerInterface;
13
  use WooCommerce\PayPalCommerce\Vaulting\Assets\MyAccountPaymentsAssets;
14
  use WooCommerce\PayPalCommerce\Vaulting\Endpoint\DeletePaymentTokenEndpoint;
15
 
16
  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 {
24
  return new MyAccountPaymentsAssets(
25
  $container->get( 'vaulting.module-url' )
26
  );
28
  'vaulting.payment-tokens-renderer' => static function (): PaymentTokensRenderer {
29
  return new PaymentTokensRenderer();
30
  },
31
+ 'vaulting.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository {
32
  $factory = $container->get( 'api.factory.payment-token' );
33
  $endpoint = $container->get( 'api.endpoint.payment-token' );
34
  return new PaymentTokenRepository( $factory, $endpoint );
35
  },
36
+ 'vaulting.endpoint.delete' => function( ContainerInterface $container ) : DeletePaymentTokenEndpoint {
37
  return new DeletePaymentTokenEndpoint(
38
  $container->get( 'vaulting.repository.payment-token' ),
39
  $container->get( 'button.request-data' ),
modules/ppcp-vaulting/src/Assets/{class-myaccountpaymentsassets.php → MyAccountPaymentsAssets.php} RENAMED
@@ -24,7 +24,7 @@ class MyAccountPaymentsAssets {
24
  private $module_url;
25
 
26
  /**
27
- * WebhooksStatusPageAssets constructor.
28
  *
29
  * @param string $module_url The URL to the module.
30
  */
24
  private $module_url;
25
 
26
  /**
27
+ * MyAccountPaymentsAssets constructor.
28
  *
29
  * @param string $module_url The URL to the module.
30
  */
modules/ppcp-vaulting/src/Endpoint/{class-deletepaymenttokenendpoint.php → DeletePaymentTokenEndpoint.php} RENAMED
File without changes
modules/ppcp-vaulting/src/{class-paymenttokenrepository.php → PaymentTokenRepository.php} RENAMED
File without changes
modules/ppcp-vaulting/src/{class-paymenttokensrenderer.php → PaymentTokensRenderer.php} RENAMED
File without changes
modules/ppcp-vaulting/src/{class-vaultingmodule.php → VaultingModule.php} RENAMED
@@ -57,6 +57,27 @@ class VaultingModule implements ModuleInterface {
57
  }
58
  );
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  add_action(
61
  'woocommerce_account_ppcp-paypal-payment-tokens_endpoint',
62
  function () use ( $container ) {
57
  }
58
  );
59
 
60
+ add_action(
61
+ 'woocommerce_paypal_payments_gateway_migrate',
62
+ function () {
63
+ add_action(
64
+ 'init',
65
+ function () {
66
+ add_rewrite_endpoint( 'ppcp-paypal-payment-tokens', EP_PAGES );
67
+ flush_rewrite_rules();
68
+ }
69
+ );
70
+ }
71
+ );
72
+
73
+ add_action(
74
+ 'woocommerce_paypal_payments_gateway_activate',
75
+ function () {
76
+ add_rewrite_endpoint( 'ppcp-paypal-payment-tokens', EP_PAGES );
77
+ flush_rewrite_rules();
78
+ }
79
+ );
80
+
81
  add_action(
82
  'woocommerce_account_ppcp-paypal-payment-tokens_endpoint',
83
  function () use ( $container ) {
modules/ppcp-wc-gateway/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-wc-gateway",
3
+ "type": "dhii-mod",
4
+ "description": "WC gateway module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\WcGateway\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-wc-gateway/extensions.php CHANGED
@@ -20,15 +20,15 @@ use Psr\Log\LoggerInterface;
20
 
21
  return array(
22
 
23
- 'api.merchant_email' => static function ( $container ): string {
24
  $settings = $container->get( 'wcgateway.settings' );
25
  return $settings->has( 'merchant_email' ) ? (string) $settings->get( 'merchant_email' ) : '';
26
  },
27
- 'api.merchant_id' => static function ( $container ): string {
28
  $settings = $container->get( 'wcgateway.settings' );
29
  return $settings->has( 'merchant_id' ) ? (string) $settings->get( 'merchant_id' ) : '';
30
  },
31
- 'api.partner_merchant_id' => static function ( $container ): string {
32
  $environment = $container->get( 'onboarding.environment' );
33
 
34
  /**
@@ -39,20 +39,20 @@ return array(
39
  return $environment->current_environment_is( Environment::SANDBOX ) ?
40
  (string) $container->get( 'api.partner_merchant_id-sandbox' ) : (string) $container->get( 'api.partner_merchant_id-production' );
41
  },
42
- 'api.key' => static function ( $container ): string {
43
  $settings = $container->get( 'wcgateway.settings' );
44
  $key = $settings->has( 'client_id' ) ? (string) $settings->get( 'client_id' ) : '';
45
  return $key;
46
  },
47
- 'api.secret' => static function ( $container ): string {
48
  $settings = $container->get( 'wcgateway.settings' );
49
  return $settings->has( 'client_secret' ) ? (string) $settings->get( 'client_secret' ) : '';
50
  },
51
- 'api.prefix' => static function ( $container ): string {
52
  $settings = $container->get( 'wcgateway.settings' );
53
  return $settings->has( 'prefix' ) ? (string) $settings->get( 'prefix' ) : 'WC-';
54
  },
55
- 'api.endpoint.order' => static function ( $container ): OrderEndpoint {
56
  $order_factory = $container->get( 'api.factory.order' );
57
  $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
58
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
@@ -73,6 +73,7 @@ return array(
73
  $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
74
  $application_context_repository = $container->get( 'api.repository.application-context' );
75
  $pay_pal_request_id_repository = $container->get( 'api.repository.paypal-request-id' );
 
76
  return new OrderEndpoint(
77
  $container->get( 'api.host' ),
78
  $container->get( 'api.bearer' ),
@@ -82,10 +83,11 @@ return array(
82
  $logger,
83
  $application_context_repository,
84
  $pay_pal_request_id_repository,
 
85
  $bn_code
86
  );
87
  },
88
- 'woocommerce.logger.woocommerce' => function ( $container ): LoggerInterface {
89
  $settings = $container->get( 'wcgateway.settings' );
90
  if ( ! function_exists( 'wc_get_logger' ) || ! $settings->has( 'logging_enabled' ) || ! $settings->get( 'logging_enabled' ) ) {
91
  return new NullLogger();
20
 
21
  return array(
22
 
23
+ 'api.merchant_email' => static function ( ContainerInterface $container ): string {
24
  $settings = $container->get( 'wcgateway.settings' );
25
  return $settings->has( 'merchant_email' ) ? (string) $settings->get( 'merchant_email' ) : '';
26
  },
27
+ 'api.merchant_id' => static function ( ContainerInterface $container ): string {
28
  $settings = $container->get( 'wcgateway.settings' );
29
  return $settings->has( 'merchant_id' ) ? (string) $settings->get( 'merchant_id' ) : '';
30
  },
31
+ 'api.partner_merchant_id' => static function ( ContainerInterface $container ): string {
32
  $environment = $container->get( 'onboarding.environment' );
33
 
34
  /**
39
  return $environment->current_environment_is( Environment::SANDBOX ) ?
40
  (string) $container->get( 'api.partner_merchant_id-sandbox' ) : (string) $container->get( 'api.partner_merchant_id-production' );
41
  },
42
+ 'api.key' => static function ( ContainerInterface $container ): string {
43
  $settings = $container->get( 'wcgateway.settings' );
44
  $key = $settings->has( 'client_id' ) ? (string) $settings->get( 'client_id' ) : '';
45
  return $key;
46
  },
47
+ 'api.secret' => static function ( ContainerInterface $container ): string {
48
  $settings = $container->get( 'wcgateway.settings' );
49
  return $settings->has( 'client_secret' ) ? (string) $settings->get( 'client_secret' ) : '';
50
  },
51
+ 'api.prefix' => static function ( ContainerInterface $container ): string {
52
  $settings = $container->get( 'wcgateway.settings' );
53
  return $settings->has( 'prefix' ) ? (string) $settings->get( 'prefix' ) : 'WC-';
54
  },
55
+ 'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint {
56
  $order_factory = $container->get( 'api.factory.order' );
57
  $patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
58
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
73
  $intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
74
  $application_context_repository = $container->get( 'api.repository.application-context' );
75
  $pay_pal_request_id_repository = $container->get( 'api.repository.paypal-request-id' );
76
+ $subscription_helper = $container->get( 'subscription.helper' );
77
  return new OrderEndpoint(
78
  $container->get( 'api.host' ),
79
  $container->get( 'api.bearer' ),
83
  $logger,
84
  $application_context_repository,
85
  $pay_pal_request_id_repository,
86
+ $subscription_helper,
87
  $bn_code
88
  );
89
  },
90
+ 'woocommerce.logger.woocommerce' => function ( ContainerInterface $container ): LoggerInterface {
91
  $settings = $container->get( 'wcgateway.settings' );
92
  if ( ! function_exists( 'wc_get_logger' ) || ! $settings->has( 'logging_enabled' ) || ! $settings->get( 'logging_enabled' ) ) {
93
  return new NullLogger();
modules/ppcp-wc-gateway/module.php CHANGED
@@ -12,5 +12,5 @@ namespace WooCommerce\PayPalCommerce\WcGateway;
12
  use Dhii\Modular\Module\ModuleInterface;
13
 
14
  return static function (): ModuleInterface {
15
- return new WcGatewayModule();
16
  };
12
  use Dhii\Modular\Module\ModuleInterface;
13
 
14
  return static function (): ModuleInterface {
15
+ return new WCGatewayModule();
16
  };
modules/ppcp-wc-gateway/services.php CHANGED
@@ -11,6 +11,7 @@ declare(strict_types=1);
11
 
12
  namespace WooCommerce\PayPalCommerce\WcGateway;
13
 
 
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
15
  use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
16
  use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
@@ -26,8 +27,8 @@ use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
26
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
27
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
28
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\TransactionUrlProvider;
29
- use Woocommerce\PayPalCommerce\WcGateway\Helper\DccProductStatus;
30
- use Woocommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
31
  use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
32
  use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
33
  use WooCommerce\PayPalCommerce\WcGateway\Notice\DccWithoutPayPalAdminNotice;
@@ -41,11 +42,10 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
41
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
42
 
43
  return array(
44
- 'wcgateway.paypal-gateway' => static function ( $container ): PayPalGateway {
45
  $order_processor = $container->get( 'wcgateway.order-processor' );
46
  $settings_renderer = $container->get( 'wcgateway.settings.render' );
47
  $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
48
- $notice = $container->get( 'wcgateway.notice.authorize-order-action' );
49
  $settings = $container->get( 'wcgateway.settings' );
50
  $session_handler = $container->get( 'session.handler' );
51
  $refund_processor = $container->get( 'wcgateway.processor.refunds' );
@@ -53,12 +53,15 @@ return array(
53
  $transaction_url_provider = $container->get( 'wcgateway.transaction-url-provider' );
54
  $subscription_helper = $container->get( 'subscription.helper' );
55
  $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' );
 
 
 
56
  $environment = $container->get( 'onboarding.environment' );
 
57
  return new PayPalGateway(
58
  $settings_renderer,
59
  $order_processor,
60
  $authorized_payments,
61
- $notice,
62
  $settings,
63
  $session_handler,
64
  $refund_processor,
@@ -66,14 +69,17 @@ return array(
66
  $transaction_url_provider,
67
  $subscription_helper,
68
  $page_id,
69
- $environment
 
 
 
 
70
  );
71
  },
72
- 'wcgateway.credit-card-gateway' => static function ( $container ): CreditCardGateway {
73
  $order_processor = $container->get( 'wcgateway.order-processor' );
74
  $settings_renderer = $container->get( 'wcgateway.settings.render' );
75
  $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
76
- $notice = $container->get( 'wcgateway.notice.authorize-order-action' );
77
  $settings = $container->get( 'wcgateway.settings' );
78
  $module_url = $container->get( 'wcgateway.url' );
79
  $session_handler = $container->get( 'session.handler' );
@@ -85,13 +91,13 @@ return array(
85
  $payer_factory = $container->get( 'api.factory.payer' );
86
  $order_endpoint = $container->get( 'api.endpoint.order' );
87
  $subscription_helper = $container->get( 'subscription.helper' );
 
88
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
89
  $environment = $container->get( 'onboarding.environment' );
90
  return new CreditCardGateway(
91
  $settings_renderer,
92
  $order_processor,
93
  $authorized_payments,
94
- $notice,
95
  $settings,
96
  $module_url,
97
  $session_handler,
@@ -104,22 +110,23 @@ return array(
104
  $order_endpoint,
105
  $subscription_helper,
106
  $logger,
107
- $environment
 
108
  );
109
  },
110
- 'wcgateway.disabler' => static function ( $container ): DisableGateways {
111
  $session_handler = $container->get( 'session.handler' );
112
  $settings = $container->get( 'wcgateway.settings' );
113
- return new DisableGateways( $session_handler, $settings );
 
114
  },
115
-
116
- 'wcgateway.is-wc-payments-page' => static function ( $container ): bool {
117
  $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
118
  $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
119
  return 'wc-settings' === $page && 'checkout' === $tab;
120
  },
121
 
122
- 'wcgateway.is-ppcp-settings-page' => static function ( $container ): bool {
123
  if ( ! $container->get( 'wcgateway.is-wc-payments-page' ) ) {
124
  return false;
125
  }
@@ -128,7 +135,7 @@ return array(
128
  return in_array( $section, array( PayPalGateway::ID, CreditCardGateway::ID, WebhooksStatusPage::ID ), true );
129
  },
130
 
131
- 'wcgateway.current-ppcp-settings-page-id' => static function ( $container ): string {
132
  if ( ! $container->get( 'wcgateway.is-ppcp-settings-page' ) ) {
133
  return '';
134
  }
@@ -139,15 +146,15 @@ return array(
139
  return $ppcp_tab ? $ppcp_tab : $section;
140
  },
141
 
142
- 'wcgateway.settings' => static function ( $container ): Settings {
143
  return new Settings();
144
  },
145
- 'wcgateway.notice.connect' => static function ( $container ): ConnectAdminNotice {
146
  $state = $container->get( 'onboarding.state' );
147
  $settings = $container->get( 'wcgateway.settings' );
148
  return new ConnectAdminNotice( $state, $settings );
149
  },
150
- 'wcgateway.notice.dcc-without-paypal' => static function ( $container ): DccWithoutPayPalAdminNotice {
151
  $state = $container->get( 'onboarding.state' );
152
  $settings = $container->get( 'wcgateway.settings' );
153
  $is_payments_page = $container->get( 'wcgateway.is-wc-payments-page' );
@@ -155,17 +162,17 @@ return array(
155
  return new DccWithoutPayPalAdminNotice( $state, $settings, $is_payments_page, $is_ppcp_settings_page );
156
  },
157
  'wcgateway.notice.authorize-order-action' =>
158
- static function ( $container ): AuthorizeOrderActionNotice {
159
  return new AuthorizeOrderActionNotice();
160
  },
161
- 'wcgateway.settings.sections-renderer' => static function ( $container ): SectionsRenderer {
162
  return new SectionsRenderer( $container->get( 'wcgateway.current-ppcp-settings-page-id' ) );
163
  },
164
- 'wcgateway.settings.status' => static function ( $container ): SettingsStatus {
165
  $settings = $container->get( 'wcgateway.settings' );
166
  return new SettingsStatus( $settings );
167
  },
168
- 'wcgateway.settings.render' => static function ( $container ): SettingsRenderer {
169
  $settings = $container->get( 'wcgateway.settings' );
170
  $state = $container->get( 'onboarding.state' );
171
  $fields = $container->get( 'wcgateway.settings.fields' );
@@ -185,7 +192,7 @@ return array(
185
  $page_id
186
  );
187
  },
188
- 'wcgateway.settings.listener' => static function ( $container ): SettingsListener {
189
  $settings = $container->get( 'wcgateway.settings' );
190
  $fields = $container->get( 'wcgateway.settings.fields' );
191
  $webhook_registrar = $container->get( 'webhook.registrar' );
@@ -195,7 +202,7 @@ return array(
195
  $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' );
196
  return new SettingsListener( $settings, $fields, $webhook_registrar, $cache, $state, $bearer, $page_id );
197
  },
198
- 'wcgateway.order-processor' => static function ( $container ): OrderProcessor {
199
 
200
  $session_handler = $container->get( 'session.handler' );
201
  $order_endpoint = $container->get( 'api.endpoint.order' );
@@ -216,32 +223,33 @@ return array(
216
  $environment
217
  );
218
  },
219
- 'wcgateway.processor.refunds' => static function ( $container ): RefundProcessor {
220
  $order_endpoint = $container->get( 'api.endpoint.order' );
221
  $payments_endpoint = $container->get( 'api.endpoint.payments' );
222
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
223
  return new RefundProcessor( $order_endpoint, $payments_endpoint, $logger );
224
  },
225
- 'wcgateway.processor.authorized-payments' => static function ( $container ): AuthorizedPaymentsProcessor {
226
  $order_endpoint = $container->get( 'api.endpoint.order' );
227
  $payments_endpoint = $container->get( 'api.endpoint.payments' );
228
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
229
- return new AuthorizedPaymentsProcessor( $order_endpoint, $payments_endpoint, $logger );
 
230
  },
231
- 'wcgateway.admin.render-authorize-action' => static function ( $container ): RenderAuthorizeAction {
232
-
233
- return new RenderAuthorizeAction();
234
  },
235
- 'wcgateway.admin.order-payment-status' => static function ( $container ): PaymentStatusOrderDetail {
236
  $column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
237
  return new PaymentStatusOrderDetail( $column );
238
  },
239
- 'wcgateway.admin.orders-payment-status-column' => static function ( $container ): OrderTablePaymentStatusColumn {
240
  $settings = $container->get( 'wcgateway.settings' );
241
  return new OrderTablePaymentStatusColumn( $settings );
242
  },
243
 
244
- 'wcgateway.settings.fields' => static function ( $container ): array {
245
 
246
  $state = $container->get( 'onboarding.state' );
247
  $messages_disclaimers = $container->get( 'button.helper.messages-disclaimers' );
@@ -1961,28 +1969,28 @@ return array(
1961
  return $fields;
1962
  },
1963
 
1964
- 'wcgateway.checkout.address-preset' => static function( $container ): CheckoutPayPalAddressPreset {
1965
 
1966
  return new CheckoutPayPalAddressPreset(
1967
  $container->get( 'session.handler' )
1968
  );
1969
  },
1970
- 'wcgateway.url' => static function ( $container ): string {
1971
  return plugins_url(
1972
  $container->get( 'wcgateway.relative-path' ),
1973
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1974
  );
1975
  },
1976
- 'wcgateway.relative-path' => static function( $container ): string {
1977
  return 'modules/ppcp-wc-gateway/';
1978
  },
1979
- 'wcgateway.absolute-path' => static function( $container ): string {
1980
  return plugin_dir_path(
1981
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1982
  ) .
1983
  $container->get( 'wcgateway.relative-path' );
1984
  },
1985
- 'wcgateway.endpoint.return-url' => static function ( $container ) : ReturnUrlEndpoint {
1986
  $gateway = $container->get( 'wcgateway.paypal-gateway' );
1987
  $endpoint = $container->get( 'api.endpoint.order' );
1988
  $prefix = $container->get( 'api.prefix' );
@@ -1993,29 +2001,29 @@ return array(
1993
  );
1994
  },
1995
 
1996
- 'wcgateway.transaction-url-sandbox' => static function ( $container ): string {
1997
  return 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
1998
  },
1999
 
2000
- 'wcgateway.transaction-url-live' => static function ( $container ): string {
2001
  return 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
2002
  },
2003
 
2004
- 'wcgateway.transaction-url-provider' => static function ( $container ): TransactionUrlProvider {
2005
  $sandbox_url_base = $container->get( 'wcgateway.transaction-url-sandbox' );
2006
  $live_url_base = $container->get( 'wcgateway.transaction-url-live' );
2007
 
2008
  return new TransactionUrlProvider( $sandbox_url_base, $live_url_base );
2009
  },
2010
 
2011
- 'wcgateway.helper.dcc-product-status' => static function ( $container ) : DccProductStatus {
2012
 
2013
  $settings = $container->get( 'wcgateway.settings' );
2014
  $partner_endpoint = $container->get( 'api.endpoint.partners' );
2015
- return new DccProductStatus( $settings, $partner_endpoint );
2016
  },
2017
 
2018
- 'button.helper.messages-disclaimers' => static function ( $container ): MessagesDisclaimers {
2019
  return new MessagesDisclaimers();
2020
  },
2021
  );
11
 
12
  namespace WooCommerce\PayPalCommerce\WcGateway;
13
 
14
+ use Psr\Container\ContainerInterface;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
16
  use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
17
  use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
27
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
28
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
29
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\TransactionUrlProvider;
30
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus;
31
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
32
  use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
33
  use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
34
  use WooCommerce\PayPalCommerce\WcGateway\Notice\DccWithoutPayPalAdminNotice;
42
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
43
 
44
  return array(
45
+ 'wcgateway.paypal-gateway' => static function ( ContainerInterface $container ): PayPalGateway {
46
  $order_processor = $container->get( 'wcgateway.order-processor' );
47
  $settings_renderer = $container->get( 'wcgateway.settings.render' );
48
  $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
 
49
  $settings = $container->get( 'wcgateway.settings' );
50
  $session_handler = $container->get( 'session.handler' );
51
  $refund_processor = $container->get( 'wcgateway.processor.refunds' );
53
  $transaction_url_provider = $container->get( 'wcgateway.transaction-url-provider' );
54
  $subscription_helper = $container->get( 'subscription.helper' );
55
  $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' );
56
+ $payment_token_repository = $container->get( 'vaulting.repository.payment-token' );
57
+ $payments_endpoint = $container->get( 'api.endpoint.payments' );
58
+ $order_endpoint = $container->get( 'api.endpoint.order' );
59
  $environment = $container->get( 'onboarding.environment' );
60
+ $logger = $container->get( 'woocommerce.logger.woocommerce' );
61
  return new PayPalGateway(
62
  $settings_renderer,
63
  $order_processor,
64
  $authorized_payments,
 
65
  $settings,
66
  $session_handler,
67
  $refund_processor,
69
  $transaction_url_provider,
70
  $subscription_helper,
71
  $page_id,
72
+ $environment,
73
+ $payment_token_repository,
74
+ $logger,
75
+ $payments_endpoint,
76
+ $order_endpoint
77
  );
78
  },
79
+ 'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
80
  $order_processor = $container->get( 'wcgateway.order-processor' );
81
  $settings_renderer = $container->get( 'wcgateway.settings.render' );
82
  $authorized_payments = $container->get( 'wcgateway.processor.authorized-payments' );
 
83
  $settings = $container->get( 'wcgateway.settings' );
84
  $module_url = $container->get( 'wcgateway.url' );
85
  $session_handler = $container->get( 'session.handler' );
91
  $payer_factory = $container->get( 'api.factory.payer' );
92
  $order_endpoint = $container->get( 'api.endpoint.order' );
93
  $subscription_helper = $container->get( 'subscription.helper' );
94
+ $payments_endpoint = $container->get( 'api.endpoint.payments' );
95
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
96
  $environment = $container->get( 'onboarding.environment' );
97
  return new CreditCardGateway(
98
  $settings_renderer,
99
  $order_processor,
100
  $authorized_payments,
 
101
  $settings,
102
  $module_url,
103
  $session_handler,
110
  $order_endpoint,
111
  $subscription_helper,
112
  $logger,
113
+ $environment,
114
+ $payments_endpoint
115
  );
116
  },
117
+ 'wcgateway.disabler' => static function ( ContainerInterface $container ): DisableGateways {
118
  $session_handler = $container->get( 'session.handler' );
119
  $settings = $container->get( 'wcgateway.settings' );
120
+ $subscription_helper = $container->get( 'subscription.helper' );
121
+ return new DisableGateways( $session_handler, $settings, $subscription_helper );
122
  },
123
+ 'wcgateway.is-wc-payments-page' => static function ( ContainerInterface $container ): bool {
 
124
  $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
125
  $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
126
  return 'wc-settings' === $page && 'checkout' === $tab;
127
  },
128
 
129
+ 'wcgateway.is-ppcp-settings-page' => static function ( ContainerInterface $container ): bool {
130
  if ( ! $container->get( 'wcgateway.is-wc-payments-page' ) ) {
131
  return false;
132
  }
135
  return in_array( $section, array( PayPalGateway::ID, CreditCardGateway::ID, WebhooksStatusPage::ID ), true );
136
  },
137
 
138
+ 'wcgateway.current-ppcp-settings-page-id' => static function ( ContainerInterface $container ): string {
139
  if ( ! $container->get( 'wcgateway.is-ppcp-settings-page' ) ) {
140
  return '';
141
  }
146
  return $ppcp_tab ? $ppcp_tab : $section;
147
  },
148
 
149
+ 'wcgateway.settings' => static function ( ContainerInterface $container ): Settings {
150
  return new Settings();
151
  },
152
+ 'wcgateway.notice.connect' => static function ( ContainerInterface $container ): ConnectAdminNotice {
153
  $state = $container->get( 'onboarding.state' );
154
  $settings = $container->get( 'wcgateway.settings' );
155
  return new ConnectAdminNotice( $state, $settings );
156
  },
157
+ 'wcgateway.notice.dcc-without-paypal' => static function ( ContainerInterface $container ): DccWithoutPayPalAdminNotice {
158
  $state = $container->get( 'onboarding.state' );
159
  $settings = $container->get( 'wcgateway.settings' );
160
  $is_payments_page = $container->get( 'wcgateway.is-wc-payments-page' );
162
  return new DccWithoutPayPalAdminNotice( $state, $settings, $is_payments_page, $is_ppcp_settings_page );
163
  },
164
  'wcgateway.notice.authorize-order-action' =>
165
+ static function ( ContainerInterface $container ): AuthorizeOrderActionNotice {
166
  return new AuthorizeOrderActionNotice();
167
  },
168
+ 'wcgateway.settings.sections-renderer' => static function ( ContainerInterface $container ): SectionsRenderer {
169
  return new SectionsRenderer( $container->get( 'wcgateway.current-ppcp-settings-page-id' ) );
170
  },
171
+ 'wcgateway.settings.status' => static function ( ContainerInterface $container ): SettingsStatus {
172
  $settings = $container->get( 'wcgateway.settings' );
173
  return new SettingsStatus( $settings );
174
  },
175
+ 'wcgateway.settings.render' => static function ( ContainerInterface $container ): SettingsRenderer {
176
  $settings = $container->get( 'wcgateway.settings' );
177
  $state = $container->get( 'onboarding.state' );
178
  $fields = $container->get( 'wcgateway.settings.fields' );
192
  $page_id
193
  );
194
  },
195
+ 'wcgateway.settings.listener' => static function ( ContainerInterface $container ): SettingsListener {
196
  $settings = $container->get( 'wcgateway.settings' );
197
  $fields = $container->get( 'wcgateway.settings.fields' );
198
  $webhook_registrar = $container->get( 'webhook.registrar' );
202
  $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' );
203
  return new SettingsListener( $settings, $fields, $webhook_registrar, $cache, $state, $bearer, $page_id );
204
  },
205
+ 'wcgateway.order-processor' => static function ( ContainerInterface $container ): OrderProcessor {
206
 
207
  $session_handler = $container->get( 'session.handler' );
208
  $order_endpoint = $container->get( 'api.endpoint.order' );
223
  $environment
224
  );
225
  },
226
+ 'wcgateway.processor.refunds' => static function ( ContainerInterface $container ): RefundProcessor {
227
  $order_endpoint = $container->get( 'api.endpoint.order' );
228
  $payments_endpoint = $container->get( 'api.endpoint.payments' );
229
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
230
  return new RefundProcessor( $order_endpoint, $payments_endpoint, $logger );
231
  },
232
+ 'wcgateway.processor.authorized-payments' => static function ( ContainerInterface $container ): AuthorizedPaymentsProcessor {
233
  $order_endpoint = $container->get( 'api.endpoint.order' );
234
  $payments_endpoint = $container->get( 'api.endpoint.payments' );
235
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
236
+ $notice = $container->get( 'wcgateway.notice.authorize-order-action' );
237
+ return new AuthorizedPaymentsProcessor( $order_endpoint, $payments_endpoint, $logger, $notice );
238
  },
239
+ 'wcgateway.admin.render-authorize-action' => static function ( ContainerInterface $container ): RenderAuthorizeAction {
240
+ $column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
241
+ return new RenderAuthorizeAction( $column );
242
  },
243
+ 'wcgateway.admin.order-payment-status' => static function ( ContainerInterface $container ): PaymentStatusOrderDetail {
244
  $column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
245
  return new PaymentStatusOrderDetail( $column );
246
  },
247
+ 'wcgateway.admin.orders-payment-status-column' => static function ( ContainerInterface $container ): OrderTablePaymentStatusColumn {
248
  $settings = $container->get( 'wcgateway.settings' );
249
  return new OrderTablePaymentStatusColumn( $settings );
250
  },
251
 
252
+ 'wcgateway.settings.fields' => static function ( ContainerInterface $container ): array {
253
 
254
  $state = $container->get( 'onboarding.state' );
255
  $messages_disclaimers = $container->get( 'button.helper.messages-disclaimers' );
1969
  return $fields;
1970
  },
1971
 
1972
+ 'wcgateway.checkout.address-preset' => static function( ContainerInterface $container ): CheckoutPayPalAddressPreset {
1973
 
1974
  return new CheckoutPayPalAddressPreset(
1975
  $container->get( 'session.handler' )
1976
  );
1977
  },
1978
+ 'wcgateway.url' => static function ( ContainerInterface $container ): string {
1979
  return plugins_url(
1980
  $container->get( 'wcgateway.relative-path' ),
1981
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1982
  );
1983
  },
1984
+ 'wcgateway.relative-path' => static function( ContainerInterface $container ): string {
1985
  return 'modules/ppcp-wc-gateway/';
1986
  },
1987
+ 'wcgateway.absolute-path' => static function( ContainerInterface $container ): string {
1988
  return plugin_dir_path(
1989
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
1990
  ) .
1991
  $container->get( 'wcgateway.relative-path' );
1992
  },
1993
+ 'wcgateway.endpoint.return-url' => static function ( ContainerInterface $container ) : ReturnUrlEndpoint {
1994
  $gateway = $container->get( 'wcgateway.paypal-gateway' );
1995
  $endpoint = $container->get( 'api.endpoint.order' );
1996
  $prefix = $container->get( 'api.prefix' );
2001
  );
2002
  },
2003
 
2004
+ 'wcgateway.transaction-url-sandbox' => static function ( ContainerInterface $container ): string {
2005
  return 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
2006
  },
2007
 
2008
+ 'wcgateway.transaction-url-live' => static function ( ContainerInterface $container ): string {
2009
  return 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
2010
  },
2011
 
2012
+ 'wcgateway.transaction-url-provider' => static function ( ContainerInterface $container ): TransactionUrlProvider {
2013
  $sandbox_url_base = $container->get( 'wcgateway.transaction-url-sandbox' );
2014
  $live_url_base = $container->get( 'wcgateway.transaction-url-live' );
2015
 
2016
  return new TransactionUrlProvider( $sandbox_url_base, $live_url_base );
2017
  },
2018
 
2019
+ 'wcgateway.helper.dcc-product-status' => static function ( ContainerInterface $container ) : DCCProductStatus {
2020
 
2021
  $settings = $container->get( 'wcgateway.settings' );
2022
  $partner_endpoint = $container->get( 'api.endpoint.partners' );
2023
+ return new DCCProductStatus( $settings, $partner_endpoint );
2024
  },
2025
 
2026
+ 'button.helper.messages-disclaimers' => static function ( ContainerInterface $container ): MessagesDisclaimers {
2027
  return new MessagesDisclaimers();
2028
  },
2029
  );
modules/ppcp-wc-gateway/src/Admin/{class-ordertablepaymentstatuscolumn.php → OrderTablePaymentStatusColumn.php} RENAMED
@@ -11,6 +11,7 @@ declare(strict_types=1);
11
  namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
12
 
13
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
 
14
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
15
 
16
  /**
@@ -102,7 +103,7 @@ class OrderTablePaymentStatusColumn {
102
  */
103
  public function should_render_for_order( \WC_Order $order ): bool {
104
  $intent = $order->get_meta( PayPalGateway::INTENT_META_KEY );
105
- $captured = $order->get_meta( PayPalGateway::CAPTURED_META_KEY );
106
  $status = $order->get_status();
107
  $not_allowed_statuses = array( 'refunded' );
108
  return ! empty( $intent ) && strtoupper( self::INTENT ) === strtoupper( $intent ) &&
@@ -118,7 +119,7 @@ class OrderTablePaymentStatusColumn {
118
  * @return bool
119
  */
120
  public function is_captured( \WC_Order $wc_order ): bool {
121
- $captured = $wc_order->get_meta( PayPalGateway::CAPTURED_META_KEY );
122
  return wc_string_to_bool( $captured );
123
  }
124
 
11
  namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
12
 
13
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
15
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
16
 
17
  /**
103
  */
104
  public function should_render_for_order( \WC_Order $order ): bool {
105
  $intent = $order->get_meta( PayPalGateway::INTENT_META_KEY );
106
+ $captured = $order->get_meta( AuthorizedPaymentsProcessor::CAPTURED_META_KEY );
107
  $status = $order->get_status();
108
  $not_allowed_statuses = array( 'refunded' );
109
  return ! empty( $intent ) && strtoupper( self::INTENT ) === strtoupper( $intent ) &&
119
  * @return bool
120
  */
121
  public function is_captured( \WC_Order $wc_order ): bool {
122
+ $captured = $wc_order->get_meta( AuthorizedPaymentsProcessor::CAPTURED_META_KEY );
123
  return wc_string_to_bool( $captured );
124
  }
125
 
modules/ppcp-wc-gateway/src/Admin/{class-paymentstatusorderdetail.php → PaymentStatusOrderDetail.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Admin/{class-renderauthorizeaction.php → RenderAuthorizeAction.php} RENAMED
@@ -10,11 +10,27 @@ declare( strict_types=1 );
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
11
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
 
13
 
14
  /**
15
  * Class RenderAuthorizeAction
16
  */
17
  class RenderAuthorizeAction {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  /**
20
  * Renders the action into the $order_actions array based on the WooCommerce order.
@@ -45,7 +61,10 @@ class RenderAuthorizeAction {
45
  * @return bool
46
  */
47
  private function should_render_for_order( \WC_Order $order ) : bool {
48
- $data = $order->get_meta( PayPalGateway::CAPTURED_META_KEY );
49
- return in_array( $data, array( 'true', 'false' ), true );
 
 
 
50
  }
51
  }
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Admin;
11
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
13
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
14
 
15
  /**
16
  * Class RenderAuthorizeAction
17
  */
18
  class RenderAuthorizeAction {
19
+ /**
20
+ * The capture info column.
21
+ *
22
+ * @var OrderTablePaymentStatusColumn
23
+ */
24
+ private $column;
25
+
26
+ /**
27
+ * PaymentStatusOrderDetail constructor.
28
+ *
29
+ * @param OrderTablePaymentStatusColumn $column The capture info column.
30
+ */
31
+ public function __construct( OrderTablePaymentStatusColumn $column ) {
32
+ $this->column = $column;
33
+ }
34
 
35
  /**
36
  * Renders the action into the $order_actions array based on the WooCommerce order.
61
  * @return bool
62
  */
63
  private function should_render_for_order( \WC_Order $order ) : bool {
64
+ $status = $order->get_status();
65
+ $not_allowed_statuses = array( 'refunded', 'cancelled', 'failed' );
66
+ return $this->column->should_render_for_order( $order ) &&
67
+ ! $this->column->is_captured( $order ) &&
68
+ ! in_array( $status, $not_allowed_statuses, true );
69
  }
70
  }
modules/ppcp-wc-gateway/src/Assets/{class-settingspageassets.php → SettingsPageAssets.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Checkout/{class-checkoutpaypaladdresspreset.php → CheckoutPayPalAddressPreset.php} RENAMED
@@ -114,7 +114,6 @@ class CheckoutPayPalAddressPreset {
114
  array_key_exists( $field_id, $payer_phone_map )
115
  && $payer
116
  && $payer->phone()
117
- && $payer->phone()->phone()
118
  ) {
119
  return $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() ? $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() : null;
120
  }
114
  array_key_exists( $field_id, $payer_phone_map )
115
  && $payer
116
  && $payer->phone()
 
117
  ) {
118
  return $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() ? $payer->phone()->phone()->{$payer_phone_map[ $field_id ]}() : null;
119
  }
modules/ppcp-wc-gateway/src/Checkout/{class-disablegateways.php → DisableGateways.php} RENAMED
@@ -10,6 +10,7 @@ declare(strict_types=1);
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;
@@ -19,7 +20,6 @@ use Psr\Container\ContainerInterface;
19
  */
20
  class DisableGateways {
21
 
22
-
23
  /**
24
  * The Session Handler.
25
  *
@@ -34,19 +34,29 @@ class DisableGateways {
34
  */
35
  private $settings;
36
 
 
 
 
 
 
 
 
37
  /**
38
  * DisableGateways constructor.
39
  *
40
  * @param SessionHandler $session_handler The Session Handler.
41
  * @param ContainerInterface $settings The Settings.
 
42
  */
43
  public function __construct(
44
  SessionHandler $session_handler,
45
- ContainerInterface $settings
 
46
  ) {
47
 
48
- $this->session_handler = $session_handler;
49
- $this->settings = $settings;
 
50
  }
51
 
52
  /**
@@ -100,6 +110,10 @@ class DisableGateways {
100
  return true;
101
  }
102
 
 
 
 
 
103
  return false;
104
  }
105
 
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;
20
  */
21
  class DisableGateways {
22
 
 
23
  /**
24
  * The Session Handler.
25
  *
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
  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
 
modules/ppcp-wc-gateway/src/Endpoint/{class-returnurlendpoint.php → ReturnUrlEndpoint.php} RENAMED
@@ -61,9 +61,6 @@ class ReturnUrlEndpoint {
61
  $token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
62
  // phpcs:enable WordPress.Security.NonceVerification.Recommended
63
  $order = $this->order_endpoint->order( $token );
64
- if ( ! $order ) {
65
- exit();
66
- }
67
 
68
  $wc_order_id = $this->sanitize_custom_id( $order->purchase_units()[0]->custom_id() );
69
  if ( ! $wc_order_id ) {
61
  $token = sanitize_text_field( wp_unslash( $_GET['token'] ) );
62
  // phpcs:enable WordPress.Security.NonceVerification.Recommended
63
  $order = $this->order_endpoint->order( $token );
 
 
 
64
 
65
  $wc_order_id = $this->sanitize_custom_id( $order->purchase_units()[0]->custom_id() );
66
  if ( ! $wc_order_id ) {
modules/ppcp-wc-gateway/src/Exception/{class-notfoundexception.php → NotFoundException.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Gateway/{class-creditcardgateway.php → CreditCardGateway.php} RENAMED
@@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
12
  use Psr\Log\LoggerInterface;
13
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
 
14
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
15
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
16
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
@@ -18,7 +19,6 @@ use WooCommerce\PayPalCommerce\Onboarding\State;
18
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
19
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
20
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
21
- use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
22
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
23
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
24
  use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
@@ -35,25 +35,32 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
35
  const ID = 'ppcp-credit-card-gateway';
36
 
37
  /**
38
- * Service to get transaction url for an order.
39
  *
40
- * @var TransactionUrlProvider
41
  */
42
- protected $transaction_url_provider;
43
 
44
  /**
45
- * The subscription helper.
46
  *
47
- * @var SubscriptionHelper
48
  */
49
- protected $subscription_helper;
50
 
51
  /**
52
- * The logger.
53
  *
54
- * @var LoggerInterface
55
  */
56
- protected $logger;
 
 
 
 
 
 
 
57
 
58
  /**
59
  * The URL to the module.
@@ -62,6 +69,13 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
62
  */
63
  private $module_url;
64
 
 
 
 
 
 
 
 
65
  /**
66
  * The refund processor.
67
  *
@@ -69,6 +83,20 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
69
  */
70
  private $refund_processor;
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  /**
73
  * The payment token repository.
74
  *
@@ -97,6 +125,20 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
97
  */
98
  private $order_endpoint;
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  /**
101
  * The environment.
102
  *
@@ -104,13 +146,19 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
104
  */
105
  protected $environment;
106
 
 
 
 
 
 
 
 
107
  /**
108
  * CreditCardGateway constructor.
109
  *
110
  * @param SettingsRenderer $settings_renderer The Settings Renderer.
111
  * @param OrderProcessor $order_processor The Order processor.
112
  * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments processor.
113
- * @param AuthorizeOrderActionNotice $notice The Notices.
114
  * @param ContainerInterface $config The settings.
115
  * @param string $module_url The URL to the module.
116
  * @param SessionHandler $session_handler The Session Handler.
@@ -124,12 +172,12 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
124
  * @param SubscriptionHelper $subscription_helper The subscription helper.
125
  * @param LoggerInterface $logger The logger.
126
  * @param Environment $environment The environment.
 
127
  */
128
  public function __construct(
129
  SettingsRenderer $settings_renderer,
130
  OrderProcessor $order_processor,
131
  AuthorizedPaymentsProcessor $authorized_payments_processor,
132
- AuthorizeOrderActionNotice $notice,
133
  ContainerInterface $config,
134
  string $module_url,
135
  SessionHandler $session_handler,
@@ -142,18 +190,18 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
142
  OrderEndpoint $order_endpoint,
143
  SubscriptionHelper $subscription_helper,
144
  LoggerInterface $logger,
145
- Environment $environment
 
146
  ) {
147
 
148
- $this->id = self::ID;
149
- $this->order_processor = $order_processor;
150
- $this->authorized_payments = $authorized_payments_processor;
151
- $this->notice = $notice;
152
- $this->settings_renderer = $settings_renderer;
153
- $this->config = $config;
154
- $this->session_handler = $session_handler;
155
- $this->refund_processor = $refund_processor;
156
- $this->environment = $environment;
157
 
158
  if ( $state->current_state() === State::STATE_ONBOARDED ) {
159
  $this->supports = array( 'refunds' );
@@ -212,6 +260,8 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
212
  $this->transaction_url_provider = $transaction_url_provider;
213
  $this->subscription_helper = $subscription_helper;
214
  $this->logger = $logger;
 
 
215
  }
216
 
217
  /**
11
 
12
  use Psr\Log\LoggerInterface;
13
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
16
  use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
17
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
19
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
20
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
21
  use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
 
22
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
23
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
24
  use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
35
  const ID = 'ppcp-credit-card-gateway';
36
 
37
  /**
38
+ * The Settings Renderer.
39
  *
40
+ * @var SettingsRenderer
41
  */
42
+ protected $settings_renderer;
43
 
44
  /**
45
+ * The processor for orders.
46
  *
47
+ * @var OrderProcessor
48
  */
49
+ protected $order_processor;
50
 
51
  /**
52
+ * The processor for authorized payments.
53
  *
54
+ * @var AuthorizedPaymentsProcessor
55
  */
56
+ protected $authorized_payments_processor;
57
+
58
+ /**
59
+ * The settings.
60
+ *
61
+ * @var ContainerInterface
62
+ */
63
+ protected $config;
64
 
65
  /**
66
  * The URL to the module.
69
  */
70
  private $module_url;
71
 
72
+ /**
73
+ * The Session Handler.
74
+ *
75
+ * @var SessionHandler
76
+ */
77
+ protected $session_handler;
78
+
79
  /**
80
  * The refund processor.
81
  *
83
  */
84
  private $refund_processor;
85
 
86
+ /**
87
+ * The state.
88
+ *
89
+ * @var State
90
+ */
91
+ protected $state;
92
+
93
+ /**
94
+ * Service to get transaction url for an order.
95
+ *
96
+ * @var TransactionUrlProvider
97
+ */
98
+ protected $transaction_url_provider;
99
+
100
  /**
101
  * The payment token repository.
102
  *
125
  */
126
  private $order_endpoint;
127
 
128
+ /**
129
+ * The subscription helper.
130
+ *
131
+ * @var SubscriptionHelper
132
+ */
133
+ protected $subscription_helper;
134
+
135
+ /**
136
+ * The logger.
137
+ *
138
+ * @var LoggerInterface
139
+ */
140
+ protected $logger;
141
+
142
  /**
143
  * The environment.
144
  *
146
  */
147
  protected $environment;
148
 
149
+ /**
150
+ * The payments endpoint
151
+ *
152
+ * @var PaymentsEndpoint
153
+ */
154
+ protected $payments_endpoint;
155
+
156
  /**
157
  * CreditCardGateway constructor.
158
  *
159
  * @param SettingsRenderer $settings_renderer The Settings Renderer.
160
  * @param OrderProcessor $order_processor The Order processor.
161
  * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments processor.
 
162
  * @param ContainerInterface $config The settings.
163
  * @param string $module_url The URL to the module.
164
  * @param SessionHandler $session_handler The Session Handler.
172
  * @param SubscriptionHelper $subscription_helper The subscription helper.
173
  * @param LoggerInterface $logger The logger.
174
  * @param Environment $environment The environment.
175
+ * @param PaymentsEndpoint $payments_endpoint The payments endpoint.
176
  */
177
  public function __construct(
178
  SettingsRenderer $settings_renderer,
179
  OrderProcessor $order_processor,
180
  AuthorizedPaymentsProcessor $authorized_payments_processor,
 
181
  ContainerInterface $config,
182
  string $module_url,
183
  SessionHandler $session_handler,
190
  OrderEndpoint $order_endpoint,
191
  SubscriptionHelper $subscription_helper,
192
  LoggerInterface $logger,
193
+ Environment $environment,
194
+ PaymentsEndpoint $payments_endpoint
195
  ) {
196
 
197
+ $this->id = self::ID;
198
+ $this->order_processor = $order_processor;
199
+ $this->authorized_payments_processor = $authorized_payments_processor;
200
+ $this->settings_renderer = $settings_renderer;
201
+ $this->config = $config;
202
+ $this->session_handler = $session_handler;
203
+ $this->refund_processor = $refund_processor;
204
+ $this->environment = $environment;
 
205
 
206
  if ( $state->current_state() === State::STATE_ONBOARDED ) {
207
  $this->supports = array( 'refunds' );
260
  $this->transaction_url_provider = $transaction_url_provider;
261
  $this->subscription_helper = $subscription_helper;
262
  $this->logger = $logger;
263
+ $this->payments_endpoint = $payments_endpoint;
264
+ $this->state = $state;
265
  }
266
 
267
  /**
modules/ppcp-wc-gateway/src/Gateway/{class-paypalgateway.php → PayPalGateway.php} RENAMED
@@ -9,16 +9,18 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
 
 
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
13
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
14
  use WooCommerce\PayPalCommerce\Onboarding\State;
15
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
16
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
17
- use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
18
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
19
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
20
  use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
21
- use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
22
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
23
  use Psr\Container\ContainerInterface;
24
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
@@ -31,7 +33,6 @@ class PayPalGateway extends \WC_Payment_Gateway {
31
  use ProcessPaymentTrait;
32
 
33
  const ID = 'ppcp-gateway';
34
- const CAPTURED_META_KEY = '_ppcp_paypal_captured';
35
  const INTENT_META_KEY = '_ppcp_paypal_intent';
36
  const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
37
  const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
@@ -44,25 +45,18 @@ class PayPalGateway extends \WC_Payment_Gateway {
44
  protected $settings_renderer;
45
 
46
  /**
47
- * The processor for authorized payments.
48
- *
49
- * @var AuthorizedPaymentsProcessor
50
- */
51
- protected $authorized_payments;
52
-
53
- /**
54
- * The Authorized Order Action Notice.
55
  *
56
- * @var AuthorizeOrderActionNotice
57
  */
58
- protected $notice;
59
 
60
  /**
61
- * The processor for orders.
62
  *
63
- * @var OrderProcessor
64
  */
65
- protected $order_processor;
66
 
67
  /**
68
  * The settings.
@@ -78,6 +72,20 @@ class PayPalGateway extends \WC_Payment_Gateway {
78
  */
79
  protected $session_handler;
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  /**
82
  * Service able to provide transaction url for an order.
83
  *
@@ -93,11 +101,25 @@ class PayPalGateway extends \WC_Payment_Gateway {
93
  protected $subscription_helper;
94
 
95
  /**
96
- * The Refund Processor.
97
  *
98
- * @var RefundProcessor
99
  */
100
- private $refund_processor;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  /**
103
  * Whether the plugin is in onboarded state.
@@ -120,13 +142,19 @@ class PayPalGateway extends \WC_Payment_Gateway {
120
  */
121
  protected $environment;
122
 
 
 
 
 
 
 
 
123
  /**
124
  * PayPalGateway constructor.
125
  *
126
  * @param SettingsRenderer $settings_renderer The Settings Renderer.
127
  * @param OrderProcessor $order_processor The Order Processor.
128
  * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
129
- * @param AuthorizeOrderActionNotice $notice The Order Action Notice object.
130
  * @param ContainerInterface $config The settings.
131
  * @param SessionHandler $session_handler The Session Handler.
132
  * @param RefundProcessor $refund_processor The Refund Processor.
@@ -135,12 +163,15 @@ class PayPalGateway extends \WC_Payment_Gateway {
135
  * @param SubscriptionHelper $subscription_helper The subscription helper.
136
  * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
137
  * @param Environment $environment The environment.
 
 
 
 
138
  */
139
  public function __construct(
140
  SettingsRenderer $settings_renderer,
141
  OrderProcessor $order_processor,
142
  AuthorizedPaymentsProcessor $authorized_payments_processor,
143
- AuthorizeOrderActionNotice $notice,
144
  ContainerInterface $config,
145
  SessionHandler $session_handler,
146
  RefundProcessor $refund_processor,
@@ -148,21 +179,35 @@ class PayPalGateway extends \WC_Payment_Gateway {
148
  TransactionUrlProvider $transaction_url_provider,
149
  SubscriptionHelper $subscription_helper,
150
  string $page_id,
151
- Environment $environment
 
 
 
 
152
  ) {
153
 
154
- $this->id = self::ID;
155
- $this->order_processor = $order_processor;
156
- $this->authorized_payments = $authorized_payments_processor;
157
- $this->notice = $notice;
158
- $this->settings_renderer = $settings_renderer;
159
- $this->config = $config;
160
- $this->session_handler = $session_handler;
161
- $this->refund_processor = $refund_processor;
162
- $this->transaction_url_provider = $transaction_url_provider;
163
- $this->page_id = $page_id;
164
- $this->environment = $environment;
165
- $this->onboarded = $state->current_state() === State::STATE_ONBOARDED;
 
 
 
 
 
 
 
 
 
 
166
 
167
  if ( $this->onboarded ) {
168
  $this->supports = array( 'refunds' );
@@ -206,7 +251,12 @@ class PayPalGateway extends \WC_Payment_Gateway {
206
  'process_admin_options',
207
  )
208
  );
209
- $this->subscription_helper = $subscription_helper;
 
 
 
 
 
210
  }
211
 
212
  /**
@@ -243,73 +293,6 @@ class PayPalGateway extends \WC_Payment_Gateway {
243
  }
244
  }
245
 
246
- /**
247
- * Captures an authorized payment for an WooCommerce order.
248
- *
249
- * @param \WC_Order $wc_order The WooCommerce order.
250
- *
251
- * @return bool
252
- */
253
- public function capture_authorized_payment( \WC_Order $wc_order ): bool {
254
- $result_status = $this->authorized_payments->process( $wc_order );
255
- $this->render_authorization_message_for_status( $result_status );
256
-
257
- if ( AuthorizedPaymentsProcessor::ALREADY_CAPTURED === $result_status ) {
258
- if ( $wc_order->get_status() === 'on-hold' ) {
259
- $wc_order->add_order_note(
260
- __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
261
- );
262
- }
263
-
264
- $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
265
- $wc_order->save();
266
- $wc_order->payment_complete();
267
- return true;
268
- }
269
-
270
- $captures = $this->authorized_payments->captures();
271
- if ( empty( $captures ) ) {
272
- return false;
273
- }
274
-
275
- $capture = end( $captures );
276
-
277
- $this->handle_capture_status( $capture, $wc_order );
278
-
279
- if ( AuthorizedPaymentsProcessor::SUCCESSFUL === $result_status ) {
280
- if ( $capture->status()->is( CaptureStatus::COMPLETED ) ) {
281
- $wc_order->add_order_note(
282
- __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
283
- );
284
- }
285
- $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
286
- $wc_order->save();
287
- return true;
288
- }
289
-
290
- return false;
291
- }
292
-
293
- /**
294
- * Displays the notice for a status.
295
- *
296
- * @param string $status The status.
297
- */
298
- private function render_authorization_message_for_status( string $status ) {
299
-
300
- $message_mapping = array(
301
- AuthorizedPaymentsProcessor::SUCCESSFUL => AuthorizeOrderActionNotice::SUCCESS,
302
- AuthorizedPaymentsProcessor::ALREADY_CAPTURED => AuthorizeOrderActionNotice::ALREADY_CAPTURED,
303
- AuthorizedPaymentsProcessor::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
304
- AuthorizedPaymentsProcessor::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
305
- AuthorizedPaymentsProcessor::BAD_AUTHORIZATION => AuthorizeOrderActionNotice::BAD_AUTHORIZATION,
306
- );
307
- $display_message = ( isset( $message_mapping[ $status ] ) ) ?
308
- $message_mapping[ $status ]
309
- : AuthorizeOrderActionNotice::FAILED;
310
- $this->notice->display_message( $display_message );
311
- }
312
-
313
  /**
314
  * Renders the settings.
315
  *
9
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
12
+ use Psr\Log\LoggerInterface;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
16
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
17
  use WooCommerce\PayPalCommerce\Onboarding\State;
18
  use WooCommerce\PayPalCommerce\Session\SessionHandler;
19
  use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
20
+ use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
21
  use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
22
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
23
  use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
 
24
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
25
  use Psr\Container\ContainerInterface;
26
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
33
  use ProcessPaymentTrait;
34
 
35
  const ID = 'ppcp-gateway';
 
36
  const INTENT_META_KEY = '_ppcp_paypal_intent';
37
  const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
38
  const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
45
  protected $settings_renderer;
46
 
47
  /**
48
+ * The processor for orders.
 
 
 
 
 
 
 
49
  *
50
+ * @var OrderProcessor
51
  */
52
+ protected $order_processor;
53
 
54
  /**
55
+ * The processor for authorized payments.
56
  *
57
+ * @var AuthorizedPaymentsProcessor
58
  */
59
+ protected $authorized_payments_processor;
60
 
61
  /**
62
  * The settings.
72
  */
73
  protected $session_handler;
74
 
75
+ /**
76
+ * The Refund Processor.
77
+ *
78
+ * @var RefundProcessor
79
+ */
80
+ private $refund_processor;
81
+
82
+ /**
83
+ * The state.
84
+ *
85
+ * @var State
86
+ */
87
+ protected $state;
88
+
89
  /**
90
  * Service able to provide transaction url for an order.
91
  *
101
  protected $subscription_helper;
102
 
103
  /**
104
+ * The payment token repository.
105
  *
106
+ * @var PaymentTokenRepository
107
  */
108
+ protected $payment_token_repository;
109
+
110
+ /**
111
+ * The payments endpoint
112
+ *
113
+ * @var PaymentsEndpoint
114
+ */
115
+ protected $payments_endpoint;
116
+
117
+ /**
118
+ * The order endpoint.
119
+ *
120
+ * @var OrderEndpoint
121
+ */
122
+ protected $order_endpoint;
123
 
124
  /**
125
  * Whether the plugin is in onboarded state.
142
  */
143
  protected $environment;
144
 
145
+ /**
146
+ * The logger.
147
+ *
148
+ * @var LoggerInterface
149
+ */
150
+ private $logger;
151
+
152
  /**
153
  * PayPalGateway constructor.
154
  *
155
  * @param SettingsRenderer $settings_renderer The Settings Renderer.
156
  * @param OrderProcessor $order_processor The Order Processor.
157
  * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
 
158
  * @param ContainerInterface $config The settings.
159
  * @param SessionHandler $session_handler The Session Handler.
160
  * @param RefundProcessor $refund_processor The Refund Processor.
163
  * @param SubscriptionHelper $subscription_helper The subscription helper.
164
  * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
165
  * @param Environment $environment The environment.
166
+ * @param PaymentTokenRepository $payment_token_repository The payment token repository.
167
+ * @param LoggerInterface $logger The logger.
168
+ * @param PaymentsEndpoint $payments_endpoint The payments endpoint.
169
+ * @param OrderEndpoint $order_endpoint The order endpoint.
170
  */
171
  public function __construct(
172
  SettingsRenderer $settings_renderer,
173
  OrderProcessor $order_processor,
174
  AuthorizedPaymentsProcessor $authorized_payments_processor,
 
175
  ContainerInterface $config,
176
  SessionHandler $session_handler,
177
  RefundProcessor $refund_processor,
179
  TransactionUrlProvider $transaction_url_provider,
180
  SubscriptionHelper $subscription_helper,
181
  string $page_id,
182
+ Environment $environment,
183
+ PaymentTokenRepository $payment_token_repository,
184
+ LoggerInterface $logger,
185
+ PaymentsEndpoint $payments_endpoint,
186
+ OrderEndpoint $order_endpoint
187
  ) {
188
 
189
+ $this->id = self::ID;
190
+ $this->order_processor = $order_processor;
191
+ $this->authorized_payments_processor = $authorized_payments_processor;
192
+ $this->settings_renderer = $settings_renderer;
193
+ $this->config = $config;
194
+ $this->session_handler = $session_handler;
195
+ $this->refund_processor = $refund_processor;
196
+ $this->transaction_url_provider = $transaction_url_provider;
197
+ $this->page_id = $page_id;
198
+ $this->environment = $environment;
199
+ $this->onboarded = $state->current_state() === State::STATE_ONBOARDED;
200
+ $this->id = self::ID;
201
+ $this->order_processor = $order_processor;
202
+ $this->authorized_payments = $authorized_payments_processor;
203
+ $this->settings_renderer = $settings_renderer;
204
+ $this->config = $config;
205
+ $this->session_handler = $session_handler;
206
+ $this->refund_processor = $refund_processor;
207
+ $this->transaction_url_provider = $transaction_url_provider;
208
+ $this->page_id = $page_id;
209
+ $this->environment = $environment;
210
+ $this->logger = $logger;
211
 
212
  if ( $this->onboarded ) {
213
  $this->supports = array( 'refunds' );
251
  'process_admin_options',
252
  )
253
  );
254
+ $this->subscription_helper = $subscription_helper;
255
+ $this->payment_token_repository = $payment_token_repository;
256
+ $this->logger = $logger;
257
+ $this->payments_endpoint = $payments_endpoint;
258
+ $this->order_endpoint = $order_endpoint;
259
+ $this->state = $state;
260
  }
261
 
262
  /**
293
  }
294
  }
295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  /**
297
  * Renders the settings.
298
  *
modules/ppcp-wc-gateway/src/Gateway/{class-processpaymenttrait.php → ProcessPaymentTrait.php} RENAMED
@@ -10,19 +10,23 @@ declare( strict_types=1 );
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
12
  use Exception;
 
 
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
14
  use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
15
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
16
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
 
17
  use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait;
18
  use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
 
19
 
20
  /**
21
  * Trait ProcessPaymentTrait
22
  */
23
  trait ProcessPaymentTrait {
24
 
25
- use OrderMetaTrait, PaymentsStatusHandlingTrait;
26
 
27
  /**
28
  * Process a payment for an WooCommerce order.
@@ -30,6 +34,8 @@ trait ProcessPaymentTrait {
30
  * @param int $order_id The WooCommerce order id.
31
  *
32
  * @return array
 
 
33
  */
34
  public function process_payment( $order_id ) {
35
 
@@ -99,11 +105,20 @@ trait ProcessPaymentTrait {
99
  if ( $order->intent() === 'AUTHORIZE' ) {
100
  $order = $this->order_endpoint->authorize( $order );
101
 
102
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
 
 
 
 
 
103
  }
104
 
105
  $this->handle_new_order_status( $order, $wc_order );
106
 
 
 
 
 
107
  $this->session_handler->destroy_session_data();
108
  return array(
109
  'result' => 'success',
@@ -156,7 +171,101 @@ trait ProcessPaymentTrait {
156
 
157
  try {
158
  if ( $this->order_processor->process( $wc_order ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  $this->session_handler->destroy_session_data();
 
160
  return array(
161
  'result' => 'success',
162
  'redirect' => $this->get_return_url( $wc_order ),
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
11
 
12
  use Exception;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
16
  use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
17
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
18
  use WooCommerce\PayPalCommerce\Onboarding\Environment;
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
  * Trait ProcessPaymentTrait
26
  */
27
  trait ProcessPaymentTrait {
28
 
29
+ use OrderMetaTrait, PaymentsStatusHandlingTrait, TransactionIdHandlingTrait;
30
 
31
  /**
32
  * Process a payment for an WooCommerce order.
34
  * @param int $order_id The WooCommerce order id.
35
  *
36
  * @return array
37
+ *
38
+ * @throws RuntimeException When processing payment fails.
39
  */
40
  public function process_payment( $order_id ) {
41
 
105
  if ( $order->intent() === 'AUTHORIZE' ) {
106
  $order = $this->order_endpoint->authorize( $order );
107
 
108
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
109
+ }
110
+
111
+ $transaction_id = $this->get_paypal_order_transaction_id( $order );
112
+ if ( $transaction_id ) {
113
+ $this->update_transaction_id( $transaction_id, $wc_order );
114
  }
115
 
116
  $this->handle_new_order_status( $order, $wc_order );
117
 
118
+ if ( $this->config->has( 'intent' ) && strtoupper( (string) $this->config->get( 'intent' ) ) === 'CAPTURE' ) {
119
+ $this->authorized_payments_processor->capture_authorized_payment( $wc_order );
120
+ }
121
+
122
  $this->session_handler->destroy_session_data();
123
  return array(
124
  'result' => 'success',
171
 
172
  try {
173
  if ( $this->order_processor->process( $wc_order ) ) {
174
+
175
+ if ( $this->subscription_helper->has_subscription( $order_id ) ) {
176
+ $this->logger->info( "Trying to save payment for subscription parent order #{$order_id}." );
177
+
178
+ $tokens = $this->payment_token_repository->all_for_user_id( $wc_order->get_customer_id() );
179
+ if ( $tokens ) {
180
+ $this->logger->info( "Payment for subscription parent order #{$order_id} was saved correctly." );
181
+
182
+ if ( $this->config->has( 'intent' ) && strtoupper( (string) $this->config->get( 'intent' ) ) === 'CAPTURE' ) {
183
+ $this->authorized_payments_processor->capture_authorized_payment( $wc_order );
184
+ }
185
+
186
+ $this->session_handler->destroy_session_data();
187
+
188
+ return array(
189
+ 'result' => 'success',
190
+ 'redirect' => $this->get_return_url( $wc_order ),
191
+ );
192
+ }
193
+
194
+ $this->logger->error( "Payment for subscription parent order #{$order_id} was not saved." );
195
+
196
+ $paypal_order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
197
+ if ( ! $paypal_order_id ) {
198
+ throw new RuntimeException( 'PayPal order ID not found in meta.' );
199
+ }
200
+ $order = $this->order_endpoint->order( $paypal_order_id );
201
+
202
+ $purchase_units = $order->purchase_units();
203
+ if ( ! $purchase_units ) {
204
+ throw new RuntimeException( 'No purchase units.' );
205
+ }
206
+
207
+ $payments = $purchase_units[0]->payments();
208
+ if ( ! $payments ) {
209
+ throw new RuntimeException( 'No payments.' );
210
+ }
211
+
212
+ $this->logger->debug(
213
+ sprintf(
214
+ 'Trying to void order %1$s, payments: %2$s.',
215
+ $order->id(),
216
+ wp_json_encode( $payments->to_array() )
217
+ )
218
+ );
219
+
220
+ $voidable_authorizations = array_filter(
221
+ $payments->authorizations(),
222
+ function ( Authorization $authorization ): bool {
223
+ return $authorization->is_voidable();
224
+ }
225
+ );
226
+ if ( ! $voidable_authorizations ) {
227
+ throw new RuntimeException( 'No voidable authorizations.' );
228
+ }
229
+
230
+ foreach ( $voidable_authorizations as $authorization ) {
231
+ $this->payments_endpoint->void( $authorization );
232
+ }
233
+
234
+ $this->logger->debug(
235
+ sprintf(
236
+ 'Order %1$s voided successfully.',
237
+ $order->id()
238
+ )
239
+ );
240
+
241
+ $error_message = __( 'Could not process order because it was not possible to save the payment.', 'woocommerce-paypal-payments' );
242
+ $wc_order->update_status( 'failed', $error_message );
243
+
244
+ $subscriptions = wcs_get_subscriptions_for_order( $order_id );
245
+ foreach ( $subscriptions as $key => $subscription ) {
246
+ if ( $subscription->get_parent_id() === $order_id ) {
247
+ try {
248
+ $subscription->update_status( 'cancelled' );
249
+ break;
250
+ } catch ( Exception $exception ) {
251
+ $this->logger->error( "Could not update cancelled status on subscription #{$subscription->get_id()} " . $exception->getMessage() );
252
+ }
253
+ }
254
+ }
255
+
256
+ // Adds retry counter meta to avoid duplicate invoice id error on consequent tries.
257
+ $wc_order->update_meta_data( 'ppcp-retry', (int) $wc_order->get_meta( 'ppcp-retry' ) + 1 );
258
+ $wc_order->save_meta_data();
259
+
260
+ $this->session_handler->destroy_session_data();
261
+ wc_add_notice( $error_message, 'error' );
262
+
263
+ return $failure_data;
264
+ }
265
+
266
+ WC()->cart->empty_cart();
267
  $this->session_handler->destroy_session_data();
268
+
269
  return array(
270
  'result' => 'success',
271
  'redirect' => $this->get_return_url( $wc_order ),
modules/ppcp-wc-gateway/src/Gateway/{class-transactionurlprovider.php → TransactionUrlProvider.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Helper/{class-dccproductstatus.php → DCCProductStatus.php} RENAMED
@@ -2,12 +2,12 @@
2
  /**
3
  * Manage the Seller status.
4
  *
5
- * @package Woocommerce\PayPalCommerce\WcGateway\Helper
6
  */
7
 
8
  declare( strict_types=1 );
9
 
10
- namespace Woocommerce\PayPalCommerce\WcGateway\Helper;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
@@ -17,7 +17,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
17
  /**
18
  * Class DccProductStatus
19
  */
20
- class DccProductStatus {
21
 
22
  /**
23
  * Caches the status for the current load.
2
  /**
3
  * Manage the Seller status.
4
  *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Helper
6
  */
7
 
8
  declare( strict_types=1 );
9
 
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Helper;
11
 
12
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
17
  /**
18
  * Class DccProductStatus
19
  */
20
+ class DCCProductStatus {
21
 
22
  /**
23
  * Caches the status for the current load.
modules/ppcp-wc-gateway/src/Helper/{class-settingsstatus.php → SettingsStatus.php} RENAMED
@@ -2,12 +2,12 @@
2
  /**
3
  * Helper to get settings status.
4
  *
5
- * @package Woocommerce\PayPalCommerce\WcGateway\Helper
6
  */
7
 
8
  declare(strict_types=1);
9
 
10
- namespace Woocommerce\PayPalCommerce\WcGateway\Helper;
11
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
13
 
2
  /**
3
  * Helper to get settings status.
4
  *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Helper
6
  */
7
 
8
  declare(strict_types=1);
9
 
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Helper;
11
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
13
 
modules/ppcp-wc-gateway/src/Notice/{class-authorizeorderactionnotice.php → AuthorizeOrderActionNotice.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Notice/{class-connectadminnotice.php → ConnectAdminNotice.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Notice/{class-dccwithoutpaypaladminnotice.php → DccWithoutPayPalAdminNotice.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Processor/{class-authorizedpaymentsprocessor.php → AuthorizedPaymentsProcessor.php} RENAMED
@@ -15,9 +15,11 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
16
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
17
  use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
18
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
 
19
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
20
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
 
21
 
22
  /**
23
  * Class AuthorizedPaymentsProcessor
@@ -33,6 +35,8 @@ class AuthorizedPaymentsProcessor {
33
  const NOT_FOUND = 'NOT_FOUND';
34
  const BAD_AUTHORIZATION = 'BAD_AUTHORIZATION';
35
 
 
 
36
  /**
37
  * The Order endpoint.
38
  *
@@ -61,22 +65,32 @@ class AuthorizedPaymentsProcessor {
61
  */
62
  private $captures;
63
 
 
 
 
 
 
 
 
64
  /**
65
  * AuthorizedPaymentsProcessor constructor.
66
  *
67
- * @param OrderEndpoint $order_endpoint The Order endpoint.
68
- * @param PaymentsEndpoint $payments_endpoint The Payments endpoint.
69
- * @param LoggerInterface $logger The logger.
 
70
  */
71
  public function __construct(
72
  OrderEndpoint $order_endpoint,
73
  PaymentsEndpoint $payments_endpoint,
74
- LoggerInterface $logger
 
75
  ) {
76
 
77
  $this->order_endpoint = $order_endpoint;
78
  $this->payments_endpoint = $payments_endpoint;
79
  $this->logger = $logger;
 
80
  }
81
 
82
  /**
@@ -127,6 +141,73 @@ class AuthorizedPaymentsProcessor {
127
  return $this->captures;
128
  }
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  /**
131
  * Returns the PayPal order from a given WooCommerce order.
132
  *
15
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
16
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
17
  use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
18
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
19
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
20
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
21
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
22
+ use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
23
 
24
  /**
25
  * Class AuthorizedPaymentsProcessor
35
  const NOT_FOUND = 'NOT_FOUND';
36
  const BAD_AUTHORIZATION = 'BAD_AUTHORIZATION';
37
 
38
+ const CAPTURED_META_KEY = '_ppcp_paypal_captured';
39
+
40
  /**
41
  * The Order endpoint.
42
  *
65
  */
66
  private $captures;
67
 
68
+ /**
69
+ * The notice.
70
+ *
71
+ * @var AuthorizeOrderActionNotice
72
+ */
73
+ private $notice;
74
+
75
  /**
76
  * AuthorizedPaymentsProcessor constructor.
77
  *
78
+ * @param OrderEndpoint $order_endpoint The Order endpoint.
79
+ * @param PaymentsEndpoint $payments_endpoint The Payments endpoint.
80
+ * @param LoggerInterface $logger The logger.
81
+ * @param AuthorizeOrderActionNotice $notice The notice.
82
  */
83
  public function __construct(
84
  OrderEndpoint $order_endpoint,
85
  PaymentsEndpoint $payments_endpoint,
86
+ LoggerInterface $logger,
87
+ AuthorizeOrderActionNotice $notice
88
  ) {
89
 
90
  $this->order_endpoint = $order_endpoint;
91
  $this->payments_endpoint = $payments_endpoint;
92
  $this->logger = $logger;
93
+ $this->notice = $notice;
94
  }
95
 
96
  /**
141
  return $this->captures;
142
  }
143
 
144
+ /**
145
+ * Captures an authorized payment for an WooCommerce order.
146
+ *
147
+ * @param \WC_Order $wc_order The WooCommerce order.
148
+ *
149
+ * @return bool
150
+ */
151
+ public function capture_authorized_payment( \WC_Order $wc_order ): bool {
152
+ $result_status = $this->process( $wc_order );
153
+ $this->render_authorization_message_for_status( $result_status );
154
+
155
+ if ( self::ALREADY_CAPTURED === $result_status ) {
156
+ if ( $wc_order->get_status() === 'on-hold' ) {
157
+ $wc_order->add_order_note(
158
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
159
+ );
160
+ }
161
+
162
+ $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
163
+ $wc_order->save();
164
+ $wc_order->payment_complete();
165
+ return true;
166
+ }
167
+
168
+ $captures = $this->captures();
169
+ if ( empty( $captures ) ) {
170
+ return false;
171
+ }
172
+
173
+ $capture = end( $captures );
174
+
175
+ $this->handle_capture_status( $capture, $wc_order );
176
+
177
+ if ( self::SUCCESSFUL === $result_status ) {
178
+ if ( $capture->status()->is( CaptureStatus::COMPLETED ) ) {
179
+ $wc_order->add_order_note(
180
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
181
+ );
182
+ }
183
+ $wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
184
+ $wc_order->save();
185
+ return true;
186
+ }
187
+
188
+ return false;
189
+ }
190
+
191
+ /**
192
+ * Displays the notice for a status.
193
+ *
194
+ * @param string $status The status.
195
+ */
196
+ private function render_authorization_message_for_status( string $status ): void {
197
+
198
+ $message_mapping = array(
199
+ self::SUCCESSFUL => AuthorizeOrderActionNotice::SUCCESS,
200
+ self::ALREADY_CAPTURED => AuthorizeOrderActionNotice::ALREADY_CAPTURED,
201
+ self::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
202
+ self::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
203
+ self::BAD_AUTHORIZATION => AuthorizeOrderActionNotice::BAD_AUTHORIZATION,
204
+ );
205
+ $display_message = ( isset( $message_mapping[ $status ] ) ) ?
206
+ $message_mapping[ $status ]
207
+ : AuthorizeOrderActionNotice::FAILED;
208
+ $this->notice->display_message( $display_message );
209
+ }
210
+
211
  /**
212
  * Returns the PayPal order from a given WooCommerce order.
213
  *
modules/ppcp-wc-gateway/src/Processor/{class-ordermetatrait.php → OrderMetaTrait.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Processor/{class-orderprocessor.php → OrderProcessor.php} RENAMED
@@ -26,7 +26,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
26
  */
27
  class OrderProcessor {
28
 
29
- use OrderMetaTrait, PaymentsStatusHandlingTrait;
30
 
31
  /**
32
  * The environment.
@@ -171,13 +171,13 @@ class OrderProcessor {
171
  if ( $order->intent() === 'AUTHORIZE' ) {
172
  $order = $this->order_endpoint->authorize( $order );
173
 
174
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'false' );
175
  }
176
 
177
  $transaction_id = $this->get_paypal_order_transaction_id( $order );
178
 
179
- if ( '' !== $transaction_id ) {
180
- $this->set_order_transaction_id( $transaction_id, $wc_order );
181
  }
182
 
183
  $this->handle_new_order_status( $order, $wc_order );
@@ -186,64 +186,13 @@ class OrderProcessor {
186
  $wc_order->add_order_note(
187
  __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
188
  );
189
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
190
  $wc_order->update_status( 'processing' );
191
  }
192
- WC()->cart->empty_cart();
193
- $this->session_handler->destroy_session_data();
194
  $this->last_error = '';
195
  return true;
196
  }
197
 
198
- /**
199
- * Set transaction id to WC order meta data.
200
- *
201
- * @param string $transaction_id Transaction id to set.
202
- * @param \WC_Order $wc_order Order to set transaction ID to.
203
- */
204
- public function set_order_transaction_id( string $transaction_id, \WC_Order $wc_order ) {
205
- try {
206
- $wc_order->set_transaction_id( $transaction_id );
207
- } catch ( \WC_Data_Exception $exception ) {
208
- $this->logger->log(
209
- 'warning',
210
- sprintf(
211
- 'Failed to set transaction ID. Exception caught when tried: %1$s',
212
- $exception->getMessage()
213
- )
214
- );
215
- }
216
- }
217
-
218
- /**
219
- * Retrieve transaction id from PayPal order.
220
- *
221
- * @param Order $order Order to get transaction id from.
222
- *
223
- * @return string
224
- */
225
- private function get_paypal_order_transaction_id( Order $order ): string {
226
- $purchase_units = $order->purchase_units();
227
-
228
- if ( ! isset( $purchase_units[0] ) ) {
229
- return '';
230
- }
231
-
232
- $payments = $purchase_units[0]->payments();
233
-
234
- if ( null === $payments ) {
235
- return '';
236
- }
237
-
238
- $captures = $payments->captures();
239
-
240
- if ( isset( $captures[0] ) ) {
241
- return $captures[0]->id();
242
- }
243
-
244
- return '';
245
- }
246
-
247
  /**
248
  * Returns if an order should be captured immediately.
249
  *
26
  */
27
  class OrderProcessor {
28
 
29
+ use OrderMetaTrait, PaymentsStatusHandlingTrait, TransactionIdHandlingTrait;
30
 
31
  /**
32
  * The environment.
171
  if ( $order->intent() === 'AUTHORIZE' ) {
172
  $order = $this->order_endpoint->authorize( $order );
173
 
174
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
175
  }
176
 
177
  $transaction_id = $this->get_paypal_order_transaction_id( $order );
178
 
179
+ if ( $transaction_id ) {
180
+ $this->update_transaction_id( $transaction_id, $wc_order );
181
  }
182
 
183
  $this->handle_new_order_status( $order, $wc_order );
186
  $wc_order->add_order_note(
187
  __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
188
  );
189
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'true' );
190
  $wc_order->update_status( 'processing' );
191
  }
 
 
192
  $this->last_error = '';
193
  return true;
194
  }
195
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  /**
197
  * Returns if an order should be captured immediately.
198
  *
modules/ppcp-wc-gateway/src/Processor/{class-paymentstatushandlingtrait.php → PaymentsStatusHandlingTrait.php} RENAMED
@@ -12,7 +12,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
12
  use WC_Order;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
15
- use Woocommerce\PayPalCommerce\ApiClient\Entity\Capture;
16
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
17
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
18
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
@@ -55,8 +55,9 @@ trait PaymentsStatusHandlingTrait {
55
  ): void {
56
  $status = $capture->status();
57
 
58
- if ( $status->details() ) {
59
- $this->add_status_details_note( $wc_order, $status->name(), $status->details()->text() );
 
60
  }
61
 
62
  switch ( $status->name() ) {
@@ -95,8 +96,9 @@ trait PaymentsStatusHandlingTrait {
95
  ): void {
96
  $status = $authorization->status();
97
 
98
- if ( $status->details() ) {
99
- $this->add_status_details_note( $wc_order, $status->name(), $status->details()->text() );
 
100
  }
101
 
102
  switch ( $status->name() ) {
12
  use WC_Order;
13
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
14
  use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
16
  use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
17
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
18
  use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
55
  ): void {
56
  $status = $capture->status();
57
 
58
+ $details = $status->details();
59
+ if ( $details ) {
60
+ $this->add_status_details_note( $wc_order, $status->name(), $details->text() );
61
  }
62
 
63
  switch ( $status->name() ) {
96
  ): void {
97
  $status = $authorization->status();
98
 
99
+ $details = $status->details();
100
+ if ( $details ) {
101
+ $this->add_status_details_note( $wc_order, $status->name(), $details->text() );
102
  }
103
 
104
  switch ( $status->name() ) {
modules/ppcp-wc-gateway/src/Processor/{class-refundprocessor.php → RefundProcessor.php} RENAMED
@@ -127,7 +127,9 @@ class RefundProcessor {
127
  case self::REFUND_MODE_VOID:
128
  $voidable_authorizations = array_filter(
129
  $payments->authorizations(),
130
- array( $this, 'is_voidable_authorization' )
 
 
131
  );
132
  if ( ! $voidable_authorizations ) {
133
  throw new RuntimeException( 'No voidable authorizations.' );
@@ -163,7 +165,7 @@ class RefundProcessor {
163
  $authorizations = $payments->authorizations();
164
  if ( $authorizations ) {
165
  foreach ( $authorizations as $authorization ) {
166
- if ( $this->is_voidable_authorization( $authorization ) ) {
167
  return self::REFUND_MODE_VOID;
168
  }
169
  }
@@ -175,15 +177,4 @@ class RefundProcessor {
175
 
176
  return self::REFUND_MODE_UNKNOWN;
177
  }
178
-
179
- /**
180
- * Checks whether the authorization can be voided.
181
- *
182
- * @param Authorization $authorization The authorization to check.
183
- * @return bool
184
- */
185
- private function is_voidable_authorization( Authorization $authorization ): bool {
186
- return $authorization->status()->is( AuthorizationStatus::CREATED ) ||
187
- $authorization->status()->is( AuthorizationStatus::PENDING );
188
- }
189
  }
127
  case self::REFUND_MODE_VOID:
128
  $voidable_authorizations = array_filter(
129
  $payments->authorizations(),
130
+ function ( Authorization $authorization ): bool {
131
+ return $authorization->is_voidable();
132
+ }
133
  );
134
  if ( ! $voidable_authorizations ) {
135
  throw new RuntimeException( 'No voidable authorizations.' );
165
  $authorizations = $payments->authorizations();
166
  if ( $authorizations ) {
167
  foreach ( $authorizations as $authorization ) {
168
+ if ( $authorization->is_voidable() ) {
169
  return self::REFUND_MODE_VOID;
170
  }
171
  }
177
 
178
  return self::REFUND_MODE_UNKNOWN;
179
  }
 
 
 
 
 
 
 
 
 
 
 
180
  }
modules/ppcp-wc-gateway/src/Processor/TransactionIdHandlingTrait.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Functions for retrieving/saving order transaction ID.
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\WcGateway\Processor
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
11
+
12
+ use Exception;
13
+ use Psr\Log\LoggerInterface;
14
+ use WC_Order;
15
+ use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
16
+
17
+ /**
18
+ * Trait PaymentsStatusHandlingTrait.
19
+ */
20
+ trait TransactionIdHandlingTrait {
21
+
22
+ /**
23
+ * Sets transaction ID to the WC order.
24
+ *
25
+ * @param string $transaction_id The transaction ID to set.
26
+ * @param WC_Order $wc_order The order to set transaction ID to.
27
+ * @param LoggerInterface|null $logger The logger to log errors.
28
+ *
29
+ * @return bool
30
+ */
31
+ protected function update_transaction_id(
32
+ string $transaction_id,
33
+ WC_Order $wc_order,
34
+ LoggerInterface $logger = null
35
+ ): bool {
36
+ try {
37
+ $wc_order->set_transaction_id( $transaction_id );
38
+ $wc_order->save();
39
+ return true;
40
+ } catch ( Exception $exception ) {
41
+ if ( $logger ) {
42
+ $logger->warning(
43
+ sprintf(
44
+ 'Failed to set transaction ID %1$s. %2$s',
45
+ $transaction_id,
46
+ $exception->getMessage()
47
+ )
48
+ );
49
+ }
50
+ return false;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Retrieves transaction id from PayPal order.
56
+ *
57
+ * @param Order $order The order to get transaction id from.
58
+ *
59
+ * @return string|null
60
+ */
61
+ protected function get_paypal_order_transaction_id( Order $order ): ?string {
62
+ $purchase_unit = $order->purchase_units()[0] ?? null;
63
+ if ( ! $purchase_unit ) {
64
+ return null;
65
+ }
66
+
67
+ $payments = $purchase_unit->payments();
68
+ if ( null === $payments ) {
69
+ return null;
70
+ }
71
+
72
+ $capture = $payments->captures()[0] ?? null;
73
+ if ( $capture ) {
74
+ return $capture->id();
75
+ }
76
+
77
+ $authorization = $payments->authorizations()[0] ?? null;
78
+ if ( $authorization ) {
79
+ return $authorization->id();
80
+ }
81
+
82
+ return null;
83
+ }
84
+
85
+ }
modules/ppcp-wc-gateway/src/Settings/{class-pagematchertrait.php → PageMatcherTrait.php} RENAMED
@@ -9,15 +9,8 @@ declare(strict_types=1);
9
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
11
 
12
- use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
13
- use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
14
- use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
15
- use WooCommerce\PayPalCommerce\Onboarding\State;
16
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
17
- use Psr\Container\ContainerInterface;
18
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
19
- use Woocommerce\PayPalCommerce\WcGateway\Helper\DccProductStatus;
20
- use Woocommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
21
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
22
 
23
  /**
9
 
10
  namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
11
 
 
 
 
 
12
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
 
13
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
 
 
14
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
15
 
16
  /**
modules/ppcp-wc-gateway/src/Settings/{class-sectionsrenderer.php → SectionsRenderer.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Settings/{class-settings.php → Settings.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Settings/{class-settingslistener.php → SettingsListener.php} RENAMED
File without changes
modules/ppcp-wc-gateway/src/Settings/{class-settingsrenderer.php → SettingsRenderer.php} RENAMED
@@ -15,9 +15,9 @@ use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
15
  use WooCommerce\PayPalCommerce\Onboarding\State;
16
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
17
  use Psr\Container\ContainerInterface;
 
18
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
19
- use Woocommerce\PayPalCommerce\WcGateway\Helper\DccProductStatus;
20
- use Woocommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
21
 
22
  /**
23
  * Class SettingsRenderer
@@ -71,7 +71,7 @@ class SettingsRenderer {
71
  /**
72
  * The DCC Product Status.
73
  *
74
- * @var DccProductStatus
75
  */
76
  private $dcc_product_status;
77
 
@@ -90,7 +90,7 @@ class SettingsRenderer {
90
  * @param array $fields The setting fields.
91
  * @param DccApplies $dcc_applies Whether DCC gateway can be shown.
92
  * @param MessagesApply $messages_apply Whether messages can be shown.
93
- * @param DccProductStatus $dcc_product_status The product status.
94
  * @param SettingsStatus $settings_status The Settings status helper.
95
  * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
96
  */
@@ -100,7 +100,7 @@ class SettingsRenderer {
100
  array $fields,
101
  DccApplies $dcc_applies,
102
  MessagesApply $messages_apply,
103
- DccProductStatus $dcc_product_status,
104
  SettingsStatus $settings_status,
105
  string $page_id
106
  ) {
15
  use WooCommerce\PayPalCommerce\Onboarding\State;
16
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
17
  use Psr\Container\ContainerInterface;
18
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus;
19
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
20
+ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
 
21
 
22
  /**
23
  * Class SettingsRenderer
71
  /**
72
  * The DCC Product Status.
73
  *
74
+ * @var DCCProductStatus
75
  */
76
  private $dcc_product_status;
77
 
90
  * @param array $fields The setting fields.
91
  * @param DccApplies $dcc_applies Whether DCC gateway can be shown.
92
  * @param MessagesApply $messages_apply Whether messages can be shown.
93
+ * @param DCCProductStatus $dcc_product_status The product status.
94
  * @param SettingsStatus $settings_status The Settings status helper.
95
  * @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
96
  */
100
  array $fields,
101
  DccApplies $dcc_applies,
102
  MessagesApply $messages_apply,
103
+ DCCProductStatus $dcc_product_status,
104
  SettingsStatus $settings_status,
105
  string $page_id
106
  ) {
modules/ppcp-wc-gateway/src/{class-wcgatewaymodule.php → WCGatewayModule.php} RENAMED
@@ -25,6 +25,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
25
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
26
  use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
27
  use WooCommerce\PayPalCommerce\WcGateway\Notice\DccWithoutPayPalAdminNotice;
 
28
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
29
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
30
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener;
@@ -35,12 +36,10 @@ use Psr\Container\ContainerInterface;
35
  /**
36
  * Class WcGatewayModule
37
  */
38
- class WcGatewayModule implements ModuleInterface {
39
 
40
  /**
41
- * Setup the module.
42
- *
43
- * @return ServiceProviderInterface
44
  */
45
  public function setup(): ServiceProviderInterface {
46
  return new ServiceProvider(
@@ -50,20 +49,18 @@ class WcGatewayModule implements ModuleInterface {
50
  }
51
 
52
  /**
53
- * Runs the module.
54
- *
55
- * @param ContainerInterface|null $container The container.
56
  */
57
- public function run( ContainerInterface $container ): void {
58
- $this->register_payment_gateways( $container );
59
- $this->register_order_functionality( $container );
60
- $this->register_columns( $container );
61
- $this->register_checkout_paypal_address_preset( $container );
62
 
63
  add_action(
64
  'woocommerce_sections_checkout',
65
- function() use ( $container ) {
66
- $section_renderer = $container->get( 'wcgateway.settings.sections-renderer' );
67
  /**
68
  * The Section Renderer.
69
  *
@@ -73,39 +70,39 @@ class WcGatewayModule implements ModuleInterface {
73
  }
74
  );
75
 
76
- if ( $container->has( 'wcgateway.url' ) ) {
77
  $assets = new SettingsPageAssets(
78
- $container->get( 'wcgateway.url' ),
79
- $container->get( 'wcgateway.absolute-path' ),
80
- $container->get( 'api.bearer' )
81
  );
82
  $assets->register_assets();
83
  }
84
 
85
  add_filter(
86
  Repository::NOTICES_FILTER,
87
- static function ( $notices ) use ( $container ): array {
88
- $notice = $container->get( 'wcgateway.notice.connect' );
89
  assert( $notice instanceof ConnectAdminNotice );
90
  $connect_message = $notice->connect_message();
91
  if ( $connect_message ) {
92
  $notices[] = $connect_message;
93
  }
94
 
95
- $dcc_without_paypal_notice = $container->get( 'wcgateway.notice.dcc-without-paypal' );
96
  assert( $dcc_without_paypal_notice instanceof DccWithoutPayPalAdminNotice );
97
  $dcc_without_paypal_message = $dcc_without_paypal_notice->message();
98
  if ( $dcc_without_paypal_message ) {
99
  $notices[] = $dcc_without_paypal_message;
100
  }
101
 
102
- $authorize_order_action = $container->get( 'wcgateway.notice.authorize-order-action' );
103
  $authorized_message = $authorize_order_action->message();
104
  if ( $authorized_message ) {
105
  $notices[] = $authorized_message;
106
  }
107
 
108
- $settings_renderer = $container->get( 'wcgateway.settings.render' );
109
  assert( $settings_renderer instanceof SettingsRenderer );
110
  $messages = $settings_renderer->messages();
111
  $notices = array_merge( $notices, $messages );
@@ -115,7 +112,7 @@ class WcGatewayModule implements ModuleInterface {
115
  );
116
  add_action(
117
  'woocommerce_paypal_commerce_gateway_deactivate',
118
- static function () use ( $container ) {
119
  delete_option( Settings::KEY );
120
  delete_option( PayPalRequestIdRepository::KEY );
121
  delete_option( 'woocommerce_' . PayPalGateway::ID . '_settings' );
@@ -125,8 +122,8 @@ class WcGatewayModule implements ModuleInterface {
125
 
126
  add_action(
127
  'wc_ajax_' . ReturnUrlEndpoint::ENDPOINT,
128
- static function () use ( $container ) {
129
- $endpoint = $container->get( 'wcgateway.endpoint.return-url' );
130
  /**
131
  * The Endpoint.
132
  *
@@ -152,9 +149,9 @@ class WcGatewayModule implements ModuleInterface {
152
  /**
153
  * Registers the payment gateways.
154
  *
155
- * @param ContainerInterface|null $container The container.
156
  */
157
- private function register_payment_gateways( ContainerInterface $container = null ) {
158
 
159
  add_filter(
160
  'woocommerce_payment_gateways',
@@ -263,13 +260,14 @@ class WcGatewayModule implements ModuleInterface {
263
  add_action(
264
  'woocommerce_order_action_ppcp_authorize_order',
265
  static function ( \WC_Order $wc_order ) use ( $container ) {
 
266
  /**
267
- * The PayPal Gateway.
268
  *
269
- * @var PayPalGateway $gateway
270
  */
271
- $gateway = $container->get( 'wcgateway.paypal-gateway' );
272
- $gateway->capture_authorized_payment( $wc_order );
273
  }
274
  );
275
  }
25
  use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
26
  use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
27
  use WooCommerce\PayPalCommerce\WcGateway\Notice\DccWithoutPayPalAdminNotice;
28
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
29
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
30
  use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
31
  use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener;
36
  /**
37
  * Class WcGatewayModule
38
  */
39
+ class WCGatewayModule implements ModuleInterface {
40
 
41
  /**
42
+ * {@inheritDoc}
 
 
43
  */
44
  public function setup(): ServiceProviderInterface {
45
  return new ServiceProvider(
49
  }
50
 
51
  /**
52
+ * {@inheritDoc}
 
 
53
  */
54
+ public function run( ContainerInterface $c ): void {
55
+ $this->register_payment_gateways( $c );
56
+ $this->register_order_functionality( $c );
57
+ $this->register_columns( $c );
58
+ $this->register_checkout_paypal_address_preset( $c );
59
 
60
  add_action(
61
  'woocommerce_sections_checkout',
62
+ function() use ( $c ) {
63
+ $section_renderer = $c->get( 'wcgateway.settings.sections-renderer' );
64
  /**
65
  * The Section Renderer.
66
  *
70
  }
71
  );
72
 
73
+ if ( $c->has( 'wcgateway.url' ) ) {
74
  $assets = new SettingsPageAssets(
75
+ $c->get( 'wcgateway.url' ),
76
+ $c->get( 'wcgateway.absolute-path' ),
77
+ $c->get( 'api.bearer' )
78
  );
79
  $assets->register_assets();
80
  }
81
 
82
  add_filter(
83
  Repository::NOTICES_FILTER,
84
+ static function ( $notices ) use ( $c ): array {
85
+ $notice = $c->get( 'wcgateway.notice.connect' );
86
  assert( $notice instanceof ConnectAdminNotice );
87
  $connect_message = $notice->connect_message();
88
  if ( $connect_message ) {
89
  $notices[] = $connect_message;
90
  }
91
 
92
+ $dcc_without_paypal_notice = $c->get( 'wcgateway.notice.dcc-without-paypal' );
93
  assert( $dcc_without_paypal_notice instanceof DccWithoutPayPalAdminNotice );
94
  $dcc_without_paypal_message = $dcc_without_paypal_notice->message();
95
  if ( $dcc_without_paypal_message ) {
96
  $notices[] = $dcc_without_paypal_message;
97
  }
98
 
99
+ $authorize_order_action = $c->get( 'wcgateway.notice.authorize-order-action' );
100
  $authorized_message = $authorize_order_action->message();
101
  if ( $authorized_message ) {
102
  $notices[] = $authorized_message;
103
  }
104
 
105
+ $settings_renderer = $c->get( 'wcgateway.settings.render' );
106
  assert( $settings_renderer instanceof SettingsRenderer );
107
  $messages = $settings_renderer->messages();
108
  $notices = array_merge( $notices, $messages );
112
  );
113
  add_action(
114
  'woocommerce_paypal_commerce_gateway_deactivate',
115
+ static function () use ( $c ) {
116
  delete_option( Settings::KEY );
117
  delete_option( PayPalRequestIdRepository::KEY );
118
  delete_option( 'woocommerce_' . PayPalGateway::ID . '_settings' );
122
 
123
  add_action(
124
  'wc_ajax_' . ReturnUrlEndpoint::ENDPOINT,
125
+ static function () use ( $c ) {
126
+ $endpoint = $c->get( 'wcgateway.endpoint.return-url' );
127
  /**
128
  * The Endpoint.
129
  *
149
  /**
150
  * Registers the payment gateways.
151
  *
152
+ * @param ContainerInterface $container The container.
153
  */
154
+ private function register_payment_gateways( ContainerInterface $container ) {
155
 
156
  add_filter(
157
  'woocommerce_payment_gateways',
260
  add_action(
261
  'woocommerce_order_action_ppcp_authorize_order',
262
  static function ( \WC_Order $wc_order ) use ( $container ) {
263
+
264
  /**
265
+ * The authorized payments processor.
266
  *
267
+ * @var AuthorizedPaymentsProcessor $authorized_payments_processor
268
  */
269
+ $authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' );
270
+ $authorized_payments_processor->capture_authorized_payment( $wc_order );
271
  }
272
  );
273
  }
modules/ppcp-webhooks/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/ppcp-webhooks",
3
+ "type": "dhii-mod",
4
+ "description": "Webhooks module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\PayPalCommerce\\Webhooks\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/ppcp-webhooks/services.php CHANGED
@@ -14,7 +14,6 @@ use Psr\Log\LoggerInterface;
14
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
16
  use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookFactory;
17
- use WooCommerce\PayPalCommerce\WcGateway\Assets\WebhooksStatusPageAssets;
18
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
19
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
20
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
@@ -24,11 +23,12 @@ use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureCompleted;
24
  use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureRefunded;
25
  use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureReversed;
26
  use Psr\Container\ContainerInterface;
 
27
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhookSimulation;
28
 
29
  return array(
30
 
31
- 'webhook.registrar' => function( $container ) : WebhookRegistrar {
32
  $factory = $container->get( 'api.factory.webhook' );
33
  $endpoint = $container->get( 'api.endpoint.webhook' );
34
  $rest_endpoint = $container->get( 'webhook.endpoint.controller' );
@@ -40,7 +40,7 @@ return array(
40
  $logger
41
  );
42
  },
43
- 'webhook.endpoint.controller' => function( $container ) : IncomingWebhookEndpoint {
44
  $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
45
  $webhook = $container->get( 'webhook.current' );
46
  $handler = $container->get( 'webhook.endpoint.handler' );
@@ -59,7 +59,7 @@ return array(
59
  ... $handler
60
  );
61
  },
62
- 'webhook.endpoint.handler' => function( $container ) : array {
63
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
64
  $prefix = $container->get( 'api.prefix' );
65
  $order_endpoint = $container->get( 'api.endpoint.order' );
@@ -68,11 +68,11 @@ return array(
68
  new CheckoutOrderCompleted( $logger, $prefix ),
69
  new PaymentCaptureRefunded( $logger, $prefix ),
70
  new PaymentCaptureReversed( $logger, $prefix ),
71
- new PaymentCaptureCompleted( $logger, $prefix ),
72
  );
73
  },
74
 
75
- 'webhook.current' => function( $container ) : ?Webhook {
76
  $data = (array) get_option( WebhookRegistrar::KEY, array() );
77
  if ( empty( $data ) ) {
78
  return null;
@@ -91,18 +91,18 @@ return array(
91
  }
92
  },
93
 
94
- 'webhook.is-registered' => function( $container ) : bool {
95
  return $container->get( 'webhook.current' ) !== null;
96
  },
97
 
98
- 'webhook.status.registered-webhooks' => function( $container ) : array {
99
  $endpoint = $container->get( 'api.endpoint.webhook' );
100
  assert( $endpoint instanceof WebhookEndpoint );
101
 
102
  return $endpoint->list();
103
  },
104
 
105
- 'webhook.status.registered-webhooks-data' => function( $container ) : array {
106
  $empty_placeholder = __( 'No webhooks found.', 'woocommerce-paypal-payments' );
107
 
108
  $webhooks = array();
@@ -139,7 +139,7 @@ return array(
139
  );
140
  },
141
 
142
- 'webhook.status.simulation' => function( $container ) : WebhookSimulation {
143
  $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
144
  $webhook = $container->get( 'webhook.current' );
145
  return new WebhookSimulation(
@@ -150,13 +150,13 @@ return array(
150
  );
151
  },
152
 
153
- 'webhook.status.assets' => function( $container ) : WebhooksStatusPageAssets {
154
  return new WebhooksStatusPageAssets(
155
  $container->get( 'webhook.module-url' )
156
  );
157
  },
158
 
159
- 'webhook.endpoint.resubscribe' => static function ( $container ) : ResubscribeEndpoint {
160
  $registrar = $container->get( 'webhook.registrar' );
161
  $request_data = $container->get( 'button.request-data' );
162
 
@@ -166,7 +166,7 @@ return array(
166
  );
167
  },
168
 
169
- 'webhook.endpoint.simulate' => static function ( $container ) : SimulateEndpoint {
170
  $simulation = $container->get( 'webhook.status.simulation' );
171
  $request_data = $container->get( 'button.request-data' );
172
 
@@ -175,7 +175,7 @@ return array(
175
  $request_data
176
  );
177
  },
178
- 'webhook.endpoint.simulation-state' => static function ( $container ) : SimulationStateEndpoint {
179
  $simulation = $container->get( 'webhook.status.simulation' );
180
 
181
  return new SimulationStateEndpoint(
@@ -183,7 +183,7 @@ return array(
183
  );
184
  },
185
 
186
- 'webhook.module-url' => static function ( $container ): string {
187
  return plugins_url(
188
  '/modules/ppcp-webhooks/',
189
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
14
  use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
15
  use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
16
  use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookFactory;
 
17
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
18
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
19
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
23
  use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureRefunded;
24
  use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureReversed;
25
  use Psr\Container\ContainerInterface;
26
+ use WooCommerce\PayPalCommerce\Webhooks\Status\Assets\WebhooksStatusPageAssets;
27
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhookSimulation;
28
 
29
  return array(
30
 
31
+ 'webhook.registrar' => function( ContainerInterface $container ) : WebhookRegistrar {
32
  $factory = $container->get( 'api.factory.webhook' );
33
  $endpoint = $container->get( 'api.endpoint.webhook' );
34
  $rest_endpoint = $container->get( 'webhook.endpoint.controller' );
40
  $logger
41
  );
42
  },
43
+ 'webhook.endpoint.controller' => function( ContainerInterface $container ) : IncomingWebhookEndpoint {
44
  $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
45
  $webhook = $container->get( 'webhook.current' );
46
  $handler = $container->get( 'webhook.endpoint.handler' );
59
  ... $handler
60
  );
61
  },
62
+ 'webhook.endpoint.handler' => function( ContainerInterface $container ) : array {
63
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
64
  $prefix = $container->get( 'api.prefix' );
65
  $order_endpoint = $container->get( 'api.endpoint.order' );
68
  new CheckoutOrderCompleted( $logger, $prefix ),
69
  new PaymentCaptureRefunded( $logger, $prefix ),
70
  new PaymentCaptureReversed( $logger, $prefix ),
71
+ new PaymentCaptureCompleted( $logger, $prefix, $order_endpoint ),
72
  );
73
  },
74
 
75
+ 'webhook.current' => function( ContainerInterface $container ) : ?Webhook {
76
  $data = (array) get_option( WebhookRegistrar::KEY, array() );
77
  if ( empty( $data ) ) {
78
  return null;
91
  }
92
  },
93
 
94
+ 'webhook.is-registered' => function( ContainerInterface $container ) : bool {
95
  return $container->get( 'webhook.current' ) !== null;
96
  },
97
 
98
+ 'webhook.status.registered-webhooks' => function( ContainerInterface $container ) : array {
99
  $endpoint = $container->get( 'api.endpoint.webhook' );
100
  assert( $endpoint instanceof WebhookEndpoint );
101
 
102
  return $endpoint->list();
103
  },
104
 
105
+ 'webhook.status.registered-webhooks-data' => function( ContainerInterface $container ) : array {
106
  $empty_placeholder = __( 'No webhooks found.', 'woocommerce-paypal-payments' );
107
 
108
  $webhooks = array();
139
  );
140
  },
141
 
142
+ 'webhook.status.simulation' => function( ContainerInterface $container ) : WebhookSimulation {
143
  $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
144
  $webhook = $container->get( 'webhook.current' );
145
  return new WebhookSimulation(
150
  );
151
  },
152
 
153
+ 'webhook.status.assets' => function( ContainerInterface $container ) : WebhooksStatusPageAssets {
154
  return new WebhooksStatusPageAssets(
155
  $container->get( 'webhook.module-url' )
156
  );
157
  },
158
 
159
+ 'webhook.endpoint.resubscribe' => static function ( ContainerInterface $container ) : ResubscribeEndpoint {
160
  $registrar = $container->get( 'webhook.registrar' );
161
  $request_data = $container->get( 'button.request-data' );
162
 
166
  );
167
  },
168
 
169
+ 'webhook.endpoint.simulate' => static function ( ContainerInterface $container ) : SimulateEndpoint {
170
  $simulation = $container->get( 'webhook.status.simulation' );
171
  $request_data = $container->get( 'button.request-data' );
172
 
175
  $request_data
176
  );
177
  },
178
+ 'webhook.endpoint.simulation-state' => static function ( ContainerInterface $container ) : SimulationStateEndpoint {
179
  $simulation = $container->get( 'webhook.status.simulation' );
180
 
181
  return new SimulationStateEndpoint(
183
  );
184
  },
185
 
186
+ 'webhook.module-url' => static function ( ContainerInterface $container ): string {
187
  return plugins_url(
188
  '/modules/ppcp-webhooks/',
189
  dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
modules/ppcp-webhooks/src/Endpoint/{class-resubscribeendpoint.php → ResubscribeEndpoint.php} RENAMED
File without changes
modules/ppcp-webhooks/src/Endpoint/{class-simulateendpoint.php → SimulateEndpoint.php} RENAMED
File without changes
modules/ppcp-webhooks/src/Endpoint/{class-simulationstateendpoint.php → SimulationStateEndpoint.php} RENAMED
File without changes
modules/ppcp-webhooks/src/Handler/{class-checkoutorderapproved.php → CheckoutOrderApproved.php} RENAMED
@@ -50,7 +50,7 @@ class CheckoutOrderApproved implements RequestHandler {
50
  /**
51
  * The event types a handler handles.
52
  *
53
- * @return array
54
  */
55
  public function event_types(): array {
56
  return array(
50
  /**
51
  * The event types a handler handles.
52
  *
53
+ * @return string[]
54
  */
55
  public function event_types(): array {
56
  return array(
modules/ppcp-webhooks/src/Handler/{class-checkoutordercompleted.php → CheckoutOrderCompleted.php} RENAMED
@@ -39,7 +39,7 @@ class CheckoutOrderCompleted implements RequestHandler {
39
  /**
40
  * The event types a handler handles.
41
  *
42
- * @return array
43
  */
44
  public function event_types(): array {
45
  return array(
39
  /**
40
  * The event types a handler handles.
41
  *
42
+ * @return string[]
43
  */
44
  public function event_types(): array {
45
  return array(
modules/ppcp-webhooks/src/Handler/PaymentCaptureCompleted.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles the Webhook PAYMENT.CAPTURE.COMPLETED
4
+ *
5
+ * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
+ */
7
+
8
+ declare(strict_types=1);
9
+
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
+
12
+ use Exception;
13
+ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
14
+ use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
15
+ use Psr\Log\LoggerInterface;
16
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
17
+ use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
18
+ use WP_REST_Response;
19
+
20
+ /**
21
+ * Class PaymentCaptureCompleted
22
+ */
23
+ class PaymentCaptureCompleted implements RequestHandler {
24
+
25
+ use PrefixTrait, TransactionIdHandlingTrait;
26
+
27
+ /**
28
+ * The logger.
29
+ *
30
+ * @var LoggerInterface
31
+ */
32
+ private $logger;
33
+
34
+ /**
35
+ * The order endpoint.
36
+ *
37
+ * @var OrderEndpoint
38
+ */
39
+ private $order_endpoint;
40
+
41
+ /**
42
+ * PaymentCaptureCompleted constructor.
43
+ *
44
+ * @param LoggerInterface $logger The logger.
45
+ * @param string $prefix The prefix.
46
+ * @param OrderEndpoint $order_endpoint The order endpoint.
47
+ */
48
+ public function __construct(
49
+ LoggerInterface $logger,
50
+ string $prefix,
51
+ OrderEndpoint $order_endpoint
52
+ ) {
53
+ $this->logger = $logger;
54
+ $this->prefix = $prefix;
55
+ $this->order_endpoint = $order_endpoint;
56
+ }
57
+
58
+ /**
59
+ * The event types a handler handles.
60
+ *
61
+ * @return string[]
62
+ */
63
+ public function event_types(): array {
64
+ return array( 'PAYMENT.CAPTURE.COMPLETED' );
65
+ }
66
+
67
+ /**
68
+ * Whether a handler is responsible for a given request or not.
69
+ *
70
+ * @param \WP_REST_Request $request The request.
71
+ *
72
+ * @return bool
73
+ */
74
+ public function responsible_for_request( \WP_REST_Request $request ): bool {
75
+ return in_array( $request['event_type'], $this->event_types(), true );
76
+ }
77
+
78
+ /**
79
+ * Responsible for handling the request.
80
+ *
81
+ * @param \WP_REST_Request $request The request.
82
+ *
83
+ * @return WP_REST_Response
84
+ */
85
+ public function handle_request( \WP_REST_Request $request ): WP_REST_Response {
86
+ $response = array( 'success' => false );
87
+
88
+ $webhook_id = (string) ( $request['id'] ?? '' );
89
+
90
+ $resource = $request['resource'];
91
+ if ( ! is_array( $resource ) ) {
92
+ $message = 'Resource data not found in webhook request.';
93
+ $this->logger->warning( $message, array( 'request' => $request ) );
94
+ $response['message'] = $message;
95
+ return new WP_REST_Response( $response );
96
+ }
97
+
98
+ $wc_order_id = isset( $resource['custom_id'] ) ?
99
+ $this->sanitize_custom_id( (string) $resource['custom_id'] ) : 0;
100
+ if ( ! $wc_order_id ) {
101
+ $message = sprintf( 'No order for webhook event %s was found.', $webhook_id );
102
+ $this->logger->warning( $message, array( 'request' => $request ) );
103
+ $response['message'] = $message;
104
+ return new WP_REST_Response( $response );
105
+ }
106
+
107
+ $wc_order = wc_get_order( $wc_order_id );
108
+ if ( ! is_a( $wc_order, \WC_Order::class ) ) {
109
+ $message = sprintf( 'No order for webhook event %s was found.', $webhook_id );
110
+ $this->logger->warning( $message, array( 'request' => $request ) );
111
+ $response['message'] = $message;
112
+ return new WP_REST_Response( $response );
113
+ }
114
+
115
+ if ( $wc_order->get_status() !== 'on-hold' ) {
116
+ $response['success'] = true;
117
+ return new WP_REST_Response( $response );
118
+ }
119
+ $wc_order->add_order_note(
120
+ __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
121
+ );
122
+
123
+ $wc_order->payment_complete();
124
+ $wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'true' );
125
+ $wc_order->save();
126
+ $this->logger->log(
127
+ 'info',
128
+ sprintf(
129
+ // translators: %s is the order ID.
130
+ __(
131
+ 'Order %s has been updated through PayPal',
132
+ 'woocommerce-paypal-payments'
133
+ ),
134
+ (string) $wc_order->get_id()
135
+ ),
136
+ array(
137
+ 'request' => $request,
138
+ 'order' => $wc_order,
139
+ )
140
+ );
141
+
142
+ $order_id = $resource['supplementary_data']['related_ids']['order_id'] ?? null;
143
+
144
+ if ( $order_id ) {
145
+ try {
146
+ $order = $this->order_endpoint->order( (string) $order_id );
147
+
148
+ $transaction_id = $this->get_paypal_order_transaction_id( $order );
149
+ if ( $transaction_id ) {
150
+ $this->update_transaction_id( $transaction_id, $wc_order, $this->logger );
151
+ }
152
+ } catch ( Exception $exception ) {
153
+ $this->logger->warning( 'Failed to get transaction ID: ' . $exception->getMessage() );
154
+ }
155
+ }
156
+
157
+ $response['success'] = true;
158
+ return new WP_REST_Response( $response );
159
+ }
160
+ }
modules/ppcp-webhooks/src/Handler/{class-paymentcapturerefunded.php → PaymentCaptureRefunded.php} RENAMED
@@ -39,7 +39,7 @@ class PaymentCaptureRefunded implements RequestHandler {
39
  /**
40
  * The event types a handler handles.
41
  *
42
- * @return array
43
  */
44
  public function event_types(): array {
45
  return array( 'PAYMENT.CAPTURE.REFUNDED' );
39
  /**
40
  * The event types a handler handles.
41
  *
42
+ * @return string[]
43
  */
44
  public function event_types(): array {
45
  return array( 'PAYMENT.CAPTURE.REFUNDED' );
modules/ppcp-webhooks/src/Handler/{class-paymentcapturereversed.php → PaymentCaptureReversed.php} RENAMED
@@ -42,7 +42,7 @@ class PaymentCaptureReversed implements RequestHandler {
42
  /**
43
  * The event types a handler handles.
44
  *
45
- * @return array
46
  */
47
  public function event_types(): array {
48
  return array(
42
  /**
43
  * The event types a handler handles.
44
  *
45
+ * @return string[]
46
  */
47
  public function event_types(): array {
48
  return array(
modules/ppcp-webhooks/src/Handler/{class-prefixtrait.php → PrefixTrait.php} RENAMED
File without changes
modules/ppcp-webhooks/src/Handler/{class-requesthandler.php → RequestHandler.php} RENAMED
@@ -17,7 +17,7 @@ interface RequestHandler {
17
  /**
18
  * The event types a handler handles.
19
  *
20
- * @return array
21
  */
22
  public function event_types(): array;
23
 
17
  /**
18
  * The event types a handler handles.
19
  *
20
+ * @return string[]
21
  */
22
  public function event_types(): array;
23
 
modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php DELETED
@@ -1,141 +0,0 @@
1
- <?php
2
- /**
3
- * Handles the Webhook PAYMENT.CAPTURE.COMPLETED
4
- *
5
- * @package WooCommerce\PayPalCommerce\Webhooks\Handler
6
- */
7
-
8
- declare(strict_types=1);
9
-
10
- namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
11
-
12
- use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
13
- use Psr\Log\LoggerInterface;
14
-
15
- /**
16
- * Class PaymentCaptureCompleted
17
- */
18
- class PaymentCaptureCompleted implements RequestHandler {
19
-
20
- use PrefixTrait;
21
-
22
- /**
23
- * The logger.
24
- *
25
- * @var LoggerInterface
26
- */
27
- private $logger;
28
-
29
- /**
30
- * PaymentCaptureCompleted constructor.
31
- *
32
- * @param LoggerInterface $logger The logger.
33
- * @param string $prefix The prefix.
34
- */
35
- public function __construct( LoggerInterface $logger, string $prefix ) {
36
- $this->logger = $logger;
37
- $this->prefix = $prefix;
38
- }
39
-
40
- /**
41
- * The event types a handler handles.
42
- *
43
- * @return array
44
- */
45
- public function event_types(): array {
46
- return array( 'PAYMENT.CAPTURE.COMPLETED' );
47
- }
48
-
49
- /**
50
- * Whether a handler is responsible for a given request or not.
51
- *
52
- * @param \WP_REST_Request $request The request.
53
- *
54
- * @return bool
55
- */
56
- public function responsible_for_request( \WP_REST_Request $request ): bool {
57
- return in_array( $request['event_type'], $this->event_types(), true );
58
- }
59
-
60
- /**
61
- * Responsible for handling the request.
62
- *
63
- * @param \WP_REST_Request $request The request.
64
- *
65
- * @return \WP_REST_Response
66
- */
67
- public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
68
- $response = array( 'success' => false );
69
- $order_id = isset( $request['resource']['custom_id'] ) ?
70
- $this->sanitize_custom_id( $request['resource']['custom_id'] ) : 0;
71
- if ( ! $order_id ) {
72
- $message = sprintf(
73
- // translators: %s is the PayPal webhook Id.
74
- __(
75
- 'No order for webhook event %s was found.',
76
- 'woocommerce-paypal-payments'
77
- ),
78
- isset( $request['id'] ) ? $request['id'] : ''
79
- );
80
- $this->logger->log(
81
- 'warning',
82
- $message,
83
- array(
84
- 'request' => $request,
85
- )
86
- );
87
- $response['message'] = $message;
88
- return rest_ensure_response( $response );
89
- }
90
- $wc_order = wc_get_order( $order_id );
91
-
92
- if ( ! is_a( $wc_order, \WC_Order::class ) ) {
93
- $message = sprintf(
94
- // translators: %s is the PayPal webhook Id.
95
- __(
96
- 'No order for webhook event %s was found.',
97
- 'woocommerce-paypal-payments'
98
- ),
99
- isset( $request['id'] ) ? $request['id'] : ''
100
- );
101
- $this->logger->log(
102
- 'warning',
103
- $message,
104
- array(
105
- 'request' => $request,
106
- )
107
- );
108
- $response['message'] = $message;
109
- return rest_ensure_response( $response );
110
- }
111
-
112
- if ( $wc_order->get_status() !== 'on-hold' ) {
113
- $response['success'] = true;
114
- return rest_ensure_response( $response );
115
- }
116
- $wc_order->add_order_note(
117
- __( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
118
- );
119
-
120
- $wc_order->payment_complete();
121
- $wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
122
- $wc_order->save();
123
- $this->logger->log(
124
- 'info',
125
- sprintf(
126
- // translators: %s is the order ID.
127
- __(
128
- 'Order %s has been updated through PayPal',
129
- 'woocommerce-paypal-payments'
130
- ),
131
- (string) $wc_order->get_id()
132
- ),
133
- array(
134
- 'request' => $request,
135
- 'order' => $wc_order,
136
- )
137
- );
138
- $response['success'] = true;
139
- return rest_ensure_response( $response );
140
- }
141
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/ppcp-webhooks/src/{class-incomingwebhookendpoint.php → IncomingWebhookEndpoint.php} RENAMED
@@ -230,13 +230,25 @@ class IncomingWebhookEndpoint {
230
  * @return string
231
  */
232
  public function url(): string {
233
- return rest_url( self::NAMESPACE . '/' . self::ROUTE );
 
 
 
 
 
 
 
 
 
 
 
 
234
  }
235
 
236
  /**
237
  * Returns the event types, which are handled by the endpoint.
238
  *
239
- * @return array
240
  */
241
  public function handled_event_types(): array {
242
  $event_types = array();
230
  * @return string
231
  */
232
  public function url(): string {
233
+ $url = rest_url( self::NAMESPACE . '/' . self::ROUTE );
234
+
235
+ $url = str_replace( 'http://', 'https://', $url );
236
+
237
+ $ngrok_host = getenv( 'NGROK_HOST' );
238
+ if ( $ngrok_host ) {
239
+ $host = wp_parse_url( $url, PHP_URL_HOST );
240
+ if ( $host ) {
241
+ $url = str_replace( $host, $ngrok_host, $url );
242
+ }
243
+ }
244
+
245
+ return $url;
246
  }
247
 
248
  /**
249
  * Returns the event types, which are handled by the endpoint.
250
  *
251
+ * @return string[]
252
  */
253
  public function handled_event_types(): array {
254
  $event_types = array();
modules/ppcp-webhooks/src/Status/Assets/{class-webhooksstatuspageassets.php → WebhooksStatusPageAssets.php} RENAMED
@@ -7,10 +7,8 @@
7
 
8
  declare(strict_types=1);
9
 
10
- namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
11
 
12
- use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
13
- use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
14
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
15
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
16
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
@@ -49,14 +47,14 @@ class WebhooksStatusPageAssets {
49
  'ppcp-webhooks-status-page-style',
50
  $this->module_url . '/assets/css/status-page.css',
51
  array(),
52
- 1
53
  );
54
 
55
  wp_register_script(
56
  'ppcp-webhooks-status-page',
57
  $this->module_url . '/assets/js/status-page.js',
58
  array(),
59
- 1,
60
  true
61
  );
62
 
7
 
8
  declare(strict_types=1);
9
 
10
+ namespace WooCommerce\PayPalCommerce\Webhooks\Status\Assets;
11
 
 
 
12
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
13
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
14
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
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
59
  );
60
 
modules/ppcp-webhooks/src/Status/{class-webhooksimulation.php → WebhookSimulation.php} RENAMED
@@ -78,7 +78,7 @@ class WebhookSimulation {
78
  *
79
  * @throws Exception If failed to start simulation.
80
  */
81
- public function start() {
82
  if ( ! $this->webhook ) {
83
  throw new Exception( 'Webhooks not registered' );
84
  }
78
  *
79
  * @throws Exception If failed to start simulation.
80
  */
81
+ public function start(): void {
82
  if ( ! $this->webhook ) {
83
  throw new Exception( 'Webhooks not registered' );
84
  }
modules/ppcp-webhooks/src/Status/{class-webhooksstatuspage.php → WebhooksStatusPage.php} RENAMED
File without changes
modules/ppcp-webhooks/src/{class-webhookmodule.php → WebhookModule.php} RENAMED
@@ -15,10 +15,10 @@ use Exception;
15
  use Interop\Container\ServiceProviderInterface;
16
  use Psr\Container\ContainerInterface;
17
  use Psr\Log\LoggerInterface;
18
- use WooCommerce\PayPalCommerce\WcGateway\Assets\WebhooksStatusPageAssets;
19
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
20
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
21
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
 
22
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
23
 
24
  /**
@@ -27,9 +27,7 @@ use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
27
  class WebhookModule implements ModuleInterface {
28
 
29
  /**
30
- * Setup the Webhook module.
31
- *
32
- * @return ServiceProviderInterface
33
  */
34
  public function setup(): ServiceProviderInterface {
35
  return new ServiceProvider(
@@ -39,9 +37,7 @@ class WebhookModule implements ModuleInterface {
39
  }
40
 
41
  /**
42
- * Run the Webhook module.
43
- *
44
- * @param ContainerInterface|null $container The Container.
45
  */
46
  public function run( ContainerInterface $container ): void {
47
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
15
  use Interop\Container\ServiceProviderInterface;
16
  use Psr\Container\ContainerInterface;
17
  use Psr\Log\LoggerInterface;
 
18
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint;
19
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulateEndpoint;
20
  use WooCommerce\PayPalCommerce\Webhooks\Endpoint\SimulationStateEndpoint;
21
+ use WooCommerce\PayPalCommerce\Webhooks\Status\Assets\WebhooksStatusPageAssets;
22
  use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
23
 
24
  /**
27
  class WebhookModule implements ModuleInterface {
28
 
29
  /**
30
+ * {@inheritDoc}
 
 
31
  */
32
  public function setup(): ServiceProviderInterface {
33
  return new ServiceProvider(
37
  }
38
 
39
  /**
40
+ * {@inheritDoc}
 
 
41
  */
42
  public function run( ContainerInterface $container ): void {
43
  $logger = $container->get( 'woocommerce.logger.woocommerce' );
modules/ppcp-webhooks/src/{class-webhookregistrar.php → WebhookRegistrar.php} RENAMED
File without changes
modules/woocommerce-logging/composer.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "woocommerce/woocommerce-logging",
3
+ "type": "dhii-mod",
4
+ "description": "WC logging module for PPCP",
5
+ "license": "GPL-2.0",
6
+ "require": {
7
+ "php": "^7.1 | ^8.0",
8
+ "dhii/module-interface": "^0.3.0-alpha1"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "WooCommerce\\WooCommerce\\Logging\\": "src"
13
+ }
14
+ },
15
+ "minimum-stability": "dev",
16
+ "prefer-stable": true
17
+ }
modules/woocommerce-logging/src/Logger/{class-nulllogger.php → NullLogger.php} RENAMED
File without changes
modules/woocommerce-logging/src/Logger/{class-woocommercelogger.php → WooCommerceLogger.php} RENAMED
File without changes
modules/woocommerce-logging/src/{class-woocommerceloggingmodule.php → WooCommerceLoggingModule.php} RENAMED
@@ -20,9 +20,7 @@ use Psr\Container\ContainerInterface;
20
  class WooCommerceLoggingModule implements ModuleInterface {
21
 
22
  /**
23
- * Setup the module.
24
- *
25
- * @return ServiceProviderInterface
26
  */
27
  public function setup(): ServiceProviderInterface {
28
  return new ServiceProvider(
@@ -32,11 +30,9 @@ class WooCommerceLoggingModule implements ModuleInterface {
32
  }
33
 
34
  /**
35
- * Run the module.
36
- *
37
- * @param ContainerInterface $container The container.
38
  */
39
- public function run( ContainerInterface $container ): void {
40
  }
41
 
42
 
20
  class WooCommerceLoggingModule implements ModuleInterface {
21
 
22
  /**
23
+ * {@inheritDoc}
 
 
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider(
30
  }
31
 
32
  /**
33
+ * {@inheritDoc}
 
 
34
  */
35
+ public function run( ContainerInterface $c ): void {
36
  }
37
 
38
 
psalm-baseline.xml ADDED
@@ -0,0 +1,921 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <files psalm-version="4.11.2@6fba5eb554f9507b72932f9c75533d8af593688d">
3
+ <file src="modules/ppcp-api-client/services.php">
4
+ <UndefinedConstant occurrences="2">
5
+ <code>PAYPAL_API_URL</code>
6
+ <code>PAYPAL_API_URL</code>
7
+ </UndefinedConstant>
8
+ </file>
9
+ <file src="modules/ppcp-api-client/src/Authentication/PayPalBearer.php">
10
+ <UndefinedMethod occurrences="1">
11
+ <code>$response</code>
12
+ </UndefinedMethod>
13
+ </file>
14
+ <file src="modules/ppcp-api-client/src/Endpoint/IdentityToken.php">
15
+ <InvalidOperand occurrences="1">
16
+ <code>$customer_id</code>
17
+ </InvalidOperand>
18
+ <UndefinedMethod occurrences="1">
19
+ <code>$response</code>
20
+ </UndefinedMethod>
21
+ </file>
22
+ <file src="modules/ppcp-api-client/src/Endpoint/LoginSeller.php">
23
+ <UndefinedMethod occurrences="2">
24
+ <code>$response</code>
25
+ <code>$response</code>
26
+ </UndefinedMethod>
27
+ </file>
28
+ <file src="modules/ppcp-api-client/src/Endpoint/OrderEndpoint.php">
29
+ <PossiblyNullReference occurrences="2">
30
+ <code>authorizations</code>
31
+ <code>captures</code>
32
+ </PossiblyNullReference>
33
+ <RedundantCondition occurrences="2">
34
+ <code>$order-&gt;purchase_units()[0]-&gt;payments()-&gt;authorizations()[0]-&gt;status()</code>
35
+ <code>$order-&gt;purchase_units()[0]-&gt;payments()-&gt;captures()[0]-&gt;status()</code>
36
+ </RedundantCondition>
37
+ <TypeDoesNotContainNull occurrences="2">
38
+ <code>null</code>
39
+ <code>null</code>
40
+ </TypeDoesNotContainNull>
41
+ <UndefinedMethod occurrences="5">
42
+ <code>$response</code>
43
+ <code>$response</code>
44
+ <code>$response</code>
45
+ <code>$response</code>
46
+ <code>$response</code>
47
+ </UndefinedMethod>
48
+ </file>
49
+ <file src="modules/ppcp-api-client/src/Endpoint/PartnerReferrals.php">
50
+ <UndefinedMethod occurrences="1">
51
+ <code>$response</code>
52
+ </UndefinedMethod>
53
+ </file>
54
+ <file src="modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php">
55
+ <InvalidOperand occurrences="1">
56
+ <code>$id</code>
57
+ </InvalidOperand>
58
+ <UndefinedMethod occurrences="1">
59
+ <code>$response</code>
60
+ </UndefinedMethod>
61
+ </file>
62
+ <file src="modules/ppcp-api-client/src/Endpoint/PaymentsEndpoint.php">
63
+ <UndefinedMethod occurrences="3">
64
+ <code>$response</code>
65
+ <code>$response</code>
66
+ <code>$response</code>
67
+ </UndefinedMethod>
68
+ </file>
69
+ <file src="modules/ppcp-api-client/src/Endpoint/RequestTrait.php">
70
+ <PossiblyInvalidOperand occurrences="3">
71
+ <code>wc_print_r( $args['body'], true )</code>
72
+ <code>wc_print_r( $response['body'], true )</code>
73
+ <code>wc_print_r( $response['response'], true )</code>
74
+ </PossiblyInvalidOperand>
75
+ <TooManyArguments occurrences="1">
76
+ <code>apply_filters( 'ppcp_request_args', $args, $url )</code>
77
+ </TooManyArguments>
78
+ </file>
79
+ <file src="modules/ppcp-api-client/src/Endpoint/WebhookEndpoint.php">
80
+ <PossiblyFalseArgument occurrences="1">
81
+ <code>file_get_contents( 'php://input' )</code>
82
+ </PossiblyFalseArgument>
83
+ <UndefinedMethod occurrences="4">
84
+ <code>$response</code>
85
+ <code>$response</code>
86
+ <code>$response</code>
87
+ <code>$response</code>
88
+ </UndefinedMethod>
89
+ </file>
90
+ <file src="modules/ppcp-api-client/src/Entity/Amount.php">
91
+ <PossiblyNullPropertyAssignmentValue occurrences="1">
92
+ <code>$breakdown</code>
93
+ </PossiblyNullPropertyAssignmentValue>
94
+ <PossiblyNullReference occurrences="2">
95
+ <code>to_array</code>
96
+ <code>to_array</code>
97
+ </PossiblyNullReference>
98
+ </file>
99
+ <file src="modules/ppcp-api-client/src/Entity/Item.php">
100
+ <PossiblyNullReference occurrences="1">
101
+ <code>to_array</code>
102
+ </PossiblyNullReference>
103
+ </file>
104
+ <file src="modules/ppcp-api-client/src/Entity/Order.php">
105
+ <PossiblyNullReference occurrences="5">
106
+ <code>format</code>
107
+ <code>format</code>
108
+ <code>to_array</code>
109
+ <code>to_array</code>
110
+ <code>to_array</code>
111
+ </PossiblyNullReference>
112
+ <RedundantConditionGivenDocblockType occurrences="1">
113
+ <code>return is_a( $unit, PurchaseUnit::class );</code>
114
+ </RedundantConditionGivenDocblockType>
115
+ </file>
116
+ <file src="modules/ppcp-api-client/src/Entity/Payer.php">
117
+ <PossiblyNullPropertyAssignmentValue occurrences="1">
118
+ <code>$address</code>
119
+ </PossiblyNullPropertyAssignmentValue>
120
+ <PossiblyNullReference occurrences="4">
121
+ <code>country_code</code>
122
+ <code>format</code>
123
+ <code>to_array</code>
124
+ <code>to_array</code>
125
+ </PossiblyNullReference>
126
+ </file>
127
+ <file src="modules/ppcp-api-client/src/Entity/PaymentSource.php">
128
+ <PossiblyNullReference occurrences="2">
129
+ <code>to_array</code>
130
+ <code>to_array</code>
131
+ </PossiblyNullReference>
132
+ </file>
133
+ <file src="modules/ppcp-api-client/src/Entity/PaymentSourceCard.php">
134
+ <PossiblyNullReference occurrences="1">
135
+ <code>to_array</code>
136
+ </PossiblyNullReference>
137
+ </file>
138
+ <file src="modules/ppcp-api-client/src/Entity/PurchaseUnit.php">
139
+ <PossiblyNullReference occurrences="3">
140
+ <code>to_array</code>
141
+ <code>to_array</code>
142
+ <code>to_array</code>
143
+ </PossiblyNullReference>
144
+ </file>
145
+ <file src="modules/ppcp-api-client/src/Entity/Refund.php">
146
+ <PossiblyNullReference occurrences="1">
147
+ <code>to_array</code>
148
+ </PossiblyNullReference>
149
+ </file>
150
+ <file src="modules/ppcp-api-client/src/Entity/SellerStatus.php">
151
+ <RedundantConditionGivenDocblockType occurrences="1">
152
+ <code>is_a( $product, SellerStatusProduct::class )</code>
153
+ </RedundantConditionGivenDocblockType>
154
+ </file>
155
+ <file src="modules/ppcp-api-client/src/Entity/SellerStatusProduct.php">
156
+ <RedundantConditionGivenDocblockType occurrences="1">
157
+ <code>is_string( $capability )</code>
158
+ </RedundantConditionGivenDocblockType>
159
+ </file>
160
+ <file src="modules/ppcp-api-client/src/Entity/Token.php">
161
+ <FalsableReturnStatement occurrences="1">
162
+ <code>wp_json_encode( $this-&gt;json )</code>
163
+ </FalsableReturnStatement>
164
+ <InvalidFalsableReturnType occurrences="1">
165
+ <code>string</code>
166
+ </InvalidFalsableReturnType>
167
+ <LessSpecificReturnStatement occurrences="1">
168
+ <code>new Token( $json )</code>
169
+ </LessSpecificReturnStatement>
170
+ <MoreSpecificReturnType occurrences="1">
171
+ <code>static</code>
172
+ </MoreSpecificReturnType>
173
+ <PropertyNotSetInConstructor occurrences="1">
174
+ <code>$created</code>
175
+ </PropertyNotSetInConstructor>
176
+ </file>
177
+ <file src="modules/ppcp-api-client/src/Entity/Webhook.php">
178
+ <InvalidPropertyAssignmentValue occurrences="1">
179
+ <code>$event_types</code>
180
+ </InvalidPropertyAssignmentValue>
181
+ <InvalidPropertyFetch occurrences="1">
182
+ <code>$event-&gt;name</code>
183
+ </InvalidPropertyFetch>
184
+ <InvalidReturnStatement occurrences="1">
185
+ <code>$this-&gt;event_types</code>
186
+ </InvalidReturnStatement>
187
+ <InvalidReturnType occurrences="1">
188
+ <code>stdClass[]</code>
189
+ </InvalidReturnType>
190
+ </file>
191
+ <file src="modules/ppcp-api-client/src/Exception/PayPalApiException.php">
192
+ <PossiblyNullArgument occurrences="1">
193
+ <code>$this-&gt;status_code</code>
194
+ </PossiblyNullArgument>
195
+ <UninitializedProperty occurrences="1">
196
+ <code>$this-&gt;status_code</code>
197
+ </UninitializedProperty>
198
+ </file>
199
+ <file src="modules/ppcp-api-client/src/Factory/AmountFactory.php">
200
+ <InvalidOperand occurrences="4">
201
+ <code>$cart-&gt;get_cart_contents_total() + $cart-&gt;get_discount_total() + $total_fees_amount</code>
202
+ <code>$item-&gt;quantity() * $item-&gt;tax()-&gt;value()</code>
203
+ <code>$item-&gt;quantity() * $item-&gt;unit_amount()-&gt;value()</code>
204
+ <code>$total_fees_amount += (float) $fee-&gt;amount</code>
205
+ </InvalidOperand>
206
+ <PossiblyInvalidIterator occurrences="1">
207
+ <code>WC()-&gt;session-&gt;get( 'ppcp_fees' )</code>
208
+ </PossiblyInvalidIterator>
209
+ <PossiblyNullReference occurrences="1">
210
+ <code>value</code>
211
+ </PossiblyNullReference>
212
+ <RedundantCast occurrences="1">
213
+ <code>(float) $item_total</code>
214
+ </RedundantCast>
215
+ <RedundantCastGivenDocblockType occurrences="8">
216
+ <code>(float) $cart-&gt;get_cart_contents_tax()</code>
217
+ <code>(float) $cart-&gt;get_discount_tax()</code>
218
+ <code>(float) $cart-&gt;get_discount_total()</code>
219
+ <code>(float) $cart-&gt;get_shipping_total()</code>
220
+ <code>(float) $cart-&gt;get_total( 'numeric' )</code>
221
+ <code>(float) $order-&gt;get_total()</code>
222
+ <code>(float) $order-&gt;get_total_discount( false )</code>
223
+ <code>(float) $order-&gt;get_total_discount( false )</code>
224
+ </RedundantCastGivenDocblockType>
225
+ </file>
226
+ <file src="modules/ppcp-api-client/src/Factory/ItemFactory.php">
227
+ <ArgumentTypeCoercion occurrences="1"/>
228
+ <PossiblyInvalidArgument occurrences="1">
229
+ <code>$fees_from_session</code>
230
+ </PossiblyInvalidArgument>
231
+ <RedundantCastGivenDocblockType occurrences="3">
232
+ <code>(float) $order-&gt;get_item_subtotal( $item, false )</code>
233
+ <code>(float) $order-&gt;get_item_subtotal( $item, true )</code>
234
+ <code>(int) $item-&gt;get_quantity()</code>
235
+ </RedundantCastGivenDocblockType>
236
+ </file>
237
+ <file src="modules/ppcp-api-client/src/Factory/PayerFactory.php">
238
+ <PossiblyNullArgument occurrences="2">
239
+ <code>$national_number</code>
240
+ <code>$national_number</code>
241
+ </PossiblyNullArgument>
242
+ <TooManyArguments occurrences="1">
243
+ <code>from_wc_order</code>
244
+ </TooManyArguments>
245
+ </file>
246
+ <file src="modules/ppcp-api-client/src/Factory/PurchaseUnitFactory.php">
247
+ <RedundantConditionGivenDocblockType occurrences="1">
248
+ <code>$this-&gt;shipping_needed( ... array_values( $items ) ) &amp;&amp; is_a( $customer, \WC_Customer::class )</code>
249
+ </RedundantConditionGivenDocblockType>
250
+ <TooManyArguments occurrences="1"/>
251
+ </file>
252
+ <file src="modules/ppcp-api-client/src/Factory/WebhookEventFactory.php">
253
+ <RedundantCondition occurrences="5">
254
+ <code>(object) $data-&gt;resource</code>
255
+ <code>(string) $data-&gt;event_version</code>
256
+ <code>(string) $data-&gt;resource_type</code>
257
+ <code>(string) $data-&gt;resource_version</code>
258
+ <code>(string) $data-&gt;summary</code>
259
+ </RedundantCondition>
260
+ <TypeDoesNotContainNull occurrences="5">
261
+ <code>''</code>
262
+ <code>''</code>
263
+ <code>''</code>
264
+ <code>''</code>
265
+ <code>new stdClass()</code>
266
+ </TypeDoesNotContainNull>
267
+ </file>
268
+ <file src="modules/ppcp-api-client/src/Helper/Cache.php">
269
+ <MissingReturnType occurrences="1">
270
+ <code>delete</code>
271
+ </MissingReturnType>
272
+ <RedundantCastGivenDocblockType occurrences="1">
273
+ <code>(bool) set_transient( $this-&gt;prefix . $key, $value )</code>
274
+ </RedundantCastGivenDocblockType>
275
+ </file>
276
+ <file src="modules/ppcp-api-client/src/Repository/ApplicationContextRepository.php">
277
+ <PossiblyFalseArgument occurrences="1">
278
+ <code>strrpos( $locale, '-' )</code>
279
+ </PossiblyFalseArgument>
280
+ <RedundantCastGivenDocblockType occurrences="2">
281
+ <code>(string) home_url( \WC_AJAX::get_endpoint( ReturnUrlEndpoint::ENDPOINT ) )</code>
282
+ <code>(string) wc_get_checkout_url()</code>
283
+ </RedundantCastGivenDocblockType>
284
+ </file>
285
+ <file src="modules/ppcp-api-client/src/Repository/PayPalRequestIdRepository.php">
286
+ <UndefinedConstant occurrences="1">
287
+ <code>DAY_IN_SECONDS</code>
288
+ </UndefinedConstant>
289
+ </file>
290
+ <file src="modules/ppcp-button/services.php">
291
+ <UndefinedConstant occurrences="2">
292
+ <code>CONNECT_WOO_CLIENT_ID</code>
293
+ <code>CONNECT_WOO_SANDBOX_CLIENT_ID</code>
294
+ </UndefinedConstant>
295
+ </file>
296
+ <file src="modules/ppcp-button/src/Assets/SmartButton.php">
297
+ <InvalidScalarArgument occurrences="1">
298
+ <code>1</code>
299
+ </InvalidScalarArgument>
300
+ <MissingClosureParamType occurrences="2">
301
+ <code>$default_fields</code>
302
+ <code>$id</code>
303
+ </MissingClosureParamType>
304
+ <MissingClosureReturnType occurrences="1">
305
+ <code>function ( $default_fields, $id ) {</code>
306
+ </MissingClosureReturnType>
307
+ <MissingReturnType occurrences="3">
308
+ <code>button_renderer</code>
309
+ <code>dcc_renderer</code>
310
+ <code>message_renderer</code>
311
+ </MissingReturnType>
312
+ <UndefinedConstant occurrences="1">
313
+ <code>PAYPAL_INTEGRATION_DATE</code>
314
+ </UndefinedConstant>
315
+ </file>
316
+ <file src="modules/ppcp-button/src/ButtonModule.php">
317
+ <MissingClosureParamType occurrences="1">
318
+ <code>$value</code>
319
+ </MissingClosureParamType>
320
+ <MissingReturnType occurrences="1">
321
+ <code>register_ajax_endpoints</code>
322
+ </MissingReturnType>
323
+ </file>
324
+ <file src="modules/ppcp-button/src/Endpoint/ApproveOrderEndpoint.php">
325
+ <PossiblyNullReference occurrences="3">
326
+ <code>brand</code>
327
+ <code>card</code>
328
+ <code>card</code>
329
+ </PossiblyNullReference>
330
+ </file>
331
+ <file src="modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php">
332
+ <MissingReturnType occurrences="2">
333
+ <code>set_bn_code</code>
334
+ <code>validate_paynow_form</code>
335
+ </MissingReturnType>
336
+ <PossiblyFalseArgument occurrences="1">
337
+ <code>wp_json_encode( $data['payer'] )</code>
338
+ </PossiblyFalseArgument>
339
+ <PossiblyInvalidArgument occurrences="3">
340
+ <code>$wc_order</code>
341
+ <code>$wc_order</code>
342
+ <code>$wc_order</code>
343
+ </PossiblyInvalidArgument>
344
+ <PossiblyNullArgument occurrences="2">
345
+ <code>$number</code>
346
+ <code>$wc_order</code>
347
+ </PossiblyNullArgument>
348
+ <PropertyNotSetInConstructor occurrences="2">
349
+ <code>$parsed_request_data</code>
350
+ <code>$purchase_units</code>
351
+ </PropertyNotSetInConstructor>
352
+ </file>
353
+ <file src="modules/ppcp-button/src/Endpoint/RequestData.php">
354
+ <MissingReturnType occurrences="2">
355
+ <code>dequeue_nonce_fix</code>
356
+ <code>enqueue_nonce_fix</code>
357
+ </MissingReturnType>
358
+ <PossiblyFalseArgument occurrences="1">
359
+ <code>$stream</code>
360
+ </PossiblyFalseArgument>
361
+ <PossiblyInvalidArgument occurrences="1">
362
+ <code>$json</code>
363
+ </PossiblyInvalidArgument>
364
+ <RedundantCast occurrences="2">
365
+ <code>(array) $assoc_array</code>
366
+ <code>(string) $raw_key</code>
367
+ </RedundantCast>
368
+ </file>
369
+ <file src="modules/ppcp-button/src/Helper/EarlyOrderHandler.php">
370
+ <MissingClosureParamType occurrences="1">
371
+ <code>$order_id</code>
372
+ </MissingClosureParamType>
373
+ <PossiblyInvalidArgument occurrences="2">
374
+ <code>$wc_order</code>
375
+ <code>wp_unslash( $_REQUEST['ppcp-resume-order'] )</code>
376
+ </PossiblyInvalidArgument>
377
+ <PossiblyInvalidMethodCall occurrences="3">
378
+ <code>save_meta_data</code>
379
+ <code>update_meta_data</code>
380
+ <code>update_meta_data</code>
381
+ </PossiblyInvalidMethodCall>
382
+ <RedundantCast occurrences="1">
383
+ <code>(int) $this-&gt;sanitize_custom_id( $purchase_unit-&gt;custom_id() )</code>
384
+ </RedundantCast>
385
+ </file>
386
+ <file src="modules/ppcp-button/src/Helper/ThreeDSecure.php">
387
+ <PossiblyInvalidOperand occurrences="1">
388
+ <code>wc_print_r( $result-&gt;to_array(), true )</code>
389
+ </PossiblyInvalidOperand>
390
+ <PossiblyNullReference occurrences="6">
391
+ <code>authentication_result</code>
392
+ <code>authentication_result</code>
393
+ <code>card</code>
394
+ <code>card</code>
395
+ <code>card</code>
396
+ <code>to_array</code>
397
+ </PossiblyNullReference>
398
+ </file>
399
+ <file src="modules/ppcp-compat/services.php">
400
+ <MissingClosureParamType occurrences="2">
401
+ <code>$container</code>
402
+ <code>$container</code>
403
+ </MissingClosureParamType>
404
+ </file>
405
+ <file src="modules/ppcp-compat/src/CompatModule.php">
406
+ <PossiblyNullReference occurrences="1">
407
+ <code>get</code>
408
+ </PossiblyNullReference>
409
+ </file>
410
+ <file src="modules/ppcp-compat/src/PPEC/DeactivateNote.php">
411
+ <UndefinedTrait occurrences="1">
412
+ <code>NoteTraits</code>
413
+ </UndefinedTrait>
414
+ </file>
415
+ <file src="modules/ppcp-compat/src/PPEC/SettingsImporter.php">
416
+ <UndefinedFunction occurrences="1">
417
+ <code>wc_gateway_ppec()</code>
418
+ </UndefinedFunction>
419
+ </file>
420
+ <file src="modules/ppcp-compat/src/PPEC/SubscriptionsHandler.php">
421
+ <PossiblyInvalidMethodCall occurrences="1">
422
+ <code>get_payment_method</code>
423
+ </PossiblyInvalidMethodCall>
424
+ <PossiblyNullPropertyFetch occurrences="2">
425
+ <code>get_current_screen()-&gt;id</code>
426
+ <code>get_current_screen()-&gt;id</code>
427
+ </PossiblyNullPropertyFetch>
428
+ <PossiblyUndefinedMethod occurrences="1">
429
+ <code>get_payment_method</code>
430
+ </PossiblyUndefinedMethod>
431
+ <UndefinedFunction occurrences="5">
432
+ <code>wcs_get_subscription( absint( $_GET['subscription_id'] ) )</code>
433
+ <code>wcs_get_subscription( absint( get_query_var( 'order-pay' ) ) )</code>
434
+ <code>wcs_get_subscription( absint( get_query_var( 'view-subscription' ) ) )</code>
435
+ <code>wcs_is_view_subscription_page()</code>
436
+ <code>wcs_order_contains_renewal( $order )</code>
437
+ </UndefinedFunction>
438
+ </file>
439
+ <file src="modules/ppcp-onboarding/services.php">
440
+ <MissingClosureParamType occurrences="1">
441
+ <code>$container</code>
442
+ </MissingClosureParamType>
443
+ <UndefinedConstant occurrences="10">
444
+ <code>CONNECT_WOO_MERCHANT_ID</code>
445
+ <code>CONNECT_WOO_SANDBOX_MERCHANT_ID</code>
446
+ <code>CONNECT_WOO_SANDBOX_URL</code>
447
+ <code>CONNECT_WOO_SANDBOX_URL</code>
448
+ <code>CONNECT_WOO_URL</code>
449
+ <code>CONNECT_WOO_URL</code>
450
+ <code>PAYPAL_API_URL</code>
451
+ <code>PAYPAL_API_URL</code>
452
+ <code>PAYPAL_SANDBOX_API_URL</code>
453
+ <code>PAYPAL_SANDBOX_API_URL</code>
454
+ </UndefinedConstant>
455
+ </file>
456
+ <file src="modules/ppcp-onboarding/src/Assets/OnboardingAssets.php">
457
+ <InvalidScalarArgument occurrences="3">
458
+ <code>1</code>
459
+ <code>1</code>
460
+ <code>1</code>
461
+ </InvalidScalarArgument>
462
+ </file>
463
+ <file src="modules/ppcp-onboarding/src/OnboardingModule.php">
464
+ <MissingClosureParamType occurrences="3">
465
+ <code>$config</code>
466
+ <code>$field</code>
467
+ <code>$key</code>
468
+ </MissingClosureParamType>
469
+ </file>
470
+ <file src="modules/ppcp-onboarding/src/OnboardingRESTController.php">
471
+ <MissingReturnType occurrences="1">
472
+ <code>register_routes</code>
473
+ </MissingReturnType>
474
+ <PossiblyNullPropertyAssignmentValue occurrences="1">
475
+ <code>null</code>
476
+ </PossiblyNullPropertyAssignmentValue>
477
+ <RedundantConditionGivenDocblockType occurrences="2">
478
+ <code>! empty( $url_args ) &amp;&amp; is_array( $url_args )</code>
479
+ <code>is_array( $url_args )</code>
480
+ </RedundantConditionGivenDocblockType>
481
+ <UndefinedDocblockClass occurrences="5">
482
+ <code>WP_Error|array</code>
483
+ <code>WP_REST_Request</code>
484
+ <code>WP_REST_Request</code>
485
+ <code>WP_REST_Request</code>
486
+ <code>WP_REST_Request</code>
487
+ </UndefinedDocblockClass>
488
+ </file>
489
+ <file src="modules/ppcp-onboarding/src/Render/OnboardingRenderer.php">
490
+ <MissingReturnType occurrences="2">
491
+ <code>render</code>
492
+ <code>render_button</code>
493
+ </MissingReturnType>
494
+ </file>
495
+ <file src="modules/ppcp-session/services.php">
496
+ <TypeDoesNotContainType occurrences="1">
497
+ <code>is_a( $result, SessionHandler::class )</code>
498
+ </TypeDoesNotContainType>
499
+ </file>
500
+ <file src="modules/ppcp-session/src/Cancellation/CancelController.php">
501
+ <InvalidOperand occurrences="1">
502
+ <code>get_current_user_id()</code>
503
+ </InvalidOperand>
504
+ <MissingReturnType occurrences="1">
505
+ <code>run</code>
506
+ </MissingReturnType>
507
+ <PossiblyInvalidArgument occurrences="1">
508
+ <code>wp_unslash( $_GET[ $param_name ] )</code>
509
+ </PossiblyInvalidArgument>
510
+ </file>
511
+ <file src="modules/ppcp-session/src/Cancellation/CancelView.php">
512
+ <MissingReturnType occurrences="1">
513
+ <code>render_session_cancellation</code>
514
+ </MissingReturnType>
515
+ </file>
516
+ <file src="modules/ppcp-session/src/SessionHandler.php">
517
+ <MissingReturnType occurrences="1">
518
+ <code>store_session</code>
519
+ </MissingReturnType>
520
+ </file>
521
+ <file src="modules/ppcp-status-report/src/StatusReportModule.php">
522
+ <MissingReturnType occurrences="1">
523
+ <code>getKey</code>
524
+ </MissingReturnType>
525
+ </file>
526
+ <file src="modules/ppcp-subscription/src/Helper/SubscriptionHelper.php">
527
+ <UndefinedClass occurrences="1">
528
+ <code>\WC_Subscriptions_Admin</code>
529
+ </UndefinedClass>
530
+ </file>
531
+ <file src="modules/ppcp-subscription/src/RenewalHandler.php">
532
+ <FalsableReturnStatement occurrences="1">
533
+ <code>current( $tokens )</code>
534
+ </FalsableReturnStatement>
535
+ <MissingReturnType occurrences="3">
536
+ <code>capture_order</code>
537
+ <code>process_order</code>
538
+ <code>renew</code>
539
+ </MissingReturnType>
540
+ <RedundantCastGivenDocblockType occurrences="6">
541
+ <code>(int) $customer-&gt;get_id()</code>
542
+ <code>(int) $customer-&gt;get_id()</code>
543
+ <code>(int) $wc_order-&gt;get_customer_id()</code>
544
+ <code>(int) $wc_order-&gt;get_id()</code>
545
+ <code>(int) $wc_order-&gt;get_id()</code>
546
+ <code>(int) $wc_order-&gt;get_id()</code>
547
+ </RedundantCastGivenDocblockType>
548
+ <TooManyArguments occurrences="1">
549
+ <code>apply_filters( 'woocommerce_paypal_payments_subscriptions_get_token_for_customer', null, $customer, $wc_order )</code>
550
+ </TooManyArguments>
551
+ </file>
552
+ <file src="modules/ppcp-subscription/src/SubscriptionModule.php">
553
+ <MissingClosureParamType occurrences="9">
554
+ <code>$amount</code>
555
+ <code>$amount</code>
556
+ <code>$default_fields</code>
557
+ <code>$description</code>
558
+ <code>$id</code>
559
+ <code>$id</code>
560
+ <code>$order</code>
561
+ <code>$order</code>
562
+ <code>$subscription</code>
563
+ </MissingClosureParamType>
564
+ <MissingReturnType occurrences="1">
565
+ <code>add_payment_token_id</code>
566
+ </MissingReturnType>
567
+ <PossiblyNullReference occurrences="1">
568
+ <code>get</code>
569
+ </PossiblyNullReference>
570
+ <UndefinedClass occurrences="1">
571
+ <code>\WC_Subscription</code>
572
+ </UndefinedClass>
573
+ </file>
574
+ <file src="modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php">
575
+ <MissingReturnType occurrences="1">
576
+ <code>localize</code>
577
+ </MissingReturnType>
578
+ </file>
579
+ <file src="modules/ppcp-vaulting/src/Endpoint/DeletePaymentTokenEndpoint.php">
580
+ <MissingReturnType occurrences="1">
581
+ <code>handle_request</code>
582
+ </MissingReturnType>
583
+ </file>
584
+ <file src="modules/ppcp-vaulting/src/PaymentTokenRepository.php">
585
+ <PossiblyFalseReference occurrences="1">
586
+ <code>to_array</code>
587
+ </PossiblyFalseReference>
588
+ </file>
589
+ <file src="modules/ppcp-vaulting/src/PaymentTokensRenderer.php">
590
+ <RedundantCondition occurrences="1">
591
+ <code>$token-&gt;source()</code>
592
+ </RedundantCondition>
593
+ <TypeDoesNotContainNull occurrences="1">
594
+ <code>null</code>
595
+ </TypeDoesNotContainNull>
596
+ </file>
597
+ <file src="modules/ppcp-vaulting/src/VaultingModule.php">
598
+ <MissingClosureParamType occurrences="1">
599
+ <code>$menu_links</code>
600
+ </MissingClosureParamType>
601
+ <MissingReturnType occurrences="1">
602
+ <code>getKey</code>
603
+ </MissingReturnType>
604
+ </file>
605
+ <file src="modules/ppcp-wc-gateway/services.php">
606
+ <PossiblyInvalidArgument occurrences="5">
607
+ <code>wp_unslash( $_GET[ SectionsRenderer::KEY ] )</code>
608
+ <code>wp_unslash( $_GET['page'] )</code>
609
+ <code>wp_unslash( $_GET['section'] )</code>
610
+ <code>wp_unslash( $_GET['section'] )</code>
611
+ <code>wp_unslash( $_GET['tab'] )</code>
612
+ </PossiblyInvalidArgument>
613
+ <PossiblyNullArgument occurrences="1">
614
+ <code>$letters</code>
615
+ </PossiblyNullArgument>
616
+ </file>
617
+ <file src="modules/ppcp-wc-gateway/src/Admin/OrderTablePaymentStatusColumn.php">
618
+ <MissingReturnType occurrences="3">
619
+ <code>render</code>
620
+ <code>render_completed_status</code>
621
+ <code>render_incomplete_status</code>
622
+ </MissingReturnType>
623
+ </file>
624
+ <file src="modules/ppcp-wc-gateway/src/Admin/PaymentStatusOrderDetail.php">
625
+ <MissingReturnType occurrences="1">
626
+ <code>render</code>
627
+ </MissingReturnType>
628
+ </file>
629
+ <file src="modules/ppcp-wc-gateway/src/Assets/SettingsPageAssets.php">
630
+ <MissingReturnType occurrences="2">
631
+ <code>register_admin_assets</code>
632
+ <code>register_assets</code>
633
+ </MissingReturnType>
634
+ <PossiblyNullPropertyFetch occurrences="1">
635
+ <code>$screen-&gt;id</code>
636
+ </PossiblyNullPropertyFetch>
637
+ </file>
638
+ <file src="modules/ppcp-wc-gateway/src/Checkout/CheckoutPayPalAddressPreset.php">
639
+ <PossiblyNullReference occurrences="3">
640
+ <code>phone</code>
641
+ <code>phone</code>
642
+ <code>phone</code>
643
+ <code>purchase_units</code>
644
+ </PossiblyNullReference>
645
+ <RedundantCondition occurrences="5">
646
+ <code>null</code>
647
+ <code>null</code>
648
+ <code>null</code>
649
+ <code>null</code>
650
+ <code>null</code>
651
+ </RedundantCondition>
652
+ </file>
653
+ <file src="modules/ppcp-wc-gateway/src/Checkout/DisableGateways.php">
654
+ <PossiblyNullReference occurrences="1">
655
+ <code>card</code>
656
+ </PossiblyNullReference>
657
+ </file>
658
+ <file src="modules/ppcp-wc-gateway/src/Endpoint/ReturnUrlEndpoint.php">
659
+ <MissingClosureParamType occurrences="1">
660
+ <code>$allowed_hosts</code>
661
+ </MissingClosureParamType>
662
+ <MissingReturnType occurrences="1">
663
+ <code>handle_request</code>
664
+ </MissingReturnType>
665
+ <PossiblyInvalidArgument occurrences="1">
666
+ <code>wp_unslash( $_GET['token'] )</code>
667
+ </PossiblyInvalidArgument>
668
+ </file>
669
+ <file src="modules/ppcp-wc-gateway/src/Helper/DCCProductStatus.php">
670
+ <InvalidPropertyAssignmentValue occurrences="2">
671
+ <code>true</code>
672
+ <code>true</code>
673
+ </InvalidPropertyAssignmentValue>
674
+ <PossiblyFalsePropertyAssignmentValue occurrences="2">
675
+ <code>false</code>
676
+ <code>false</code>
677
+ </PossiblyFalsePropertyAssignmentValue>
678
+ </file>
679
+ <file src="modules/ppcp-wc-gateway/src/Notice/AuthorizeOrderActionNotice.php">
680
+ <MissingClosureParamType occurrences="1">
681
+ <code>$location</code>
682
+ </MissingClosureParamType>
683
+ <MissingReturnType occurrences="1">
684
+ <code>display_message</code>
685
+ </MissingReturnType>
686
+ <PossiblyUndefinedVariable occurrences="1">
687
+ <code>$messages</code>
688
+ </PossiblyUndefinedVariable>
689
+ </file>
690
+ <file src="modules/ppcp-wc-gateway/src/Processor/AuthorizedPaymentsProcessor.php">
691
+ <MissingReturnType occurrences="1">
692
+ <code>capture_authorizations</code>
693
+ </MissingReturnType>
694
+ <PossiblyNullReference occurrences="1">
695
+ <code>authorizations</code>
696
+ </PossiblyNullReference>
697
+ <PropertyNotSetInConstructor occurrences="1">
698
+ <code>$captures</code>
699
+ </PropertyNotSetInConstructor>
700
+ </file>
701
+ <file src="modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php">
702
+ <PossiblyNullReference occurrences="1">
703
+ <code>card</code>
704
+ </PossiblyNullReference>
705
+ <PropertyNotSetInConstructor occurrences="1">
706
+ <code>$payment_token_repository</code>
707
+ </PropertyNotSetInConstructor>
708
+ </file>
709
+ <file src="modules/ppcp-wc-gateway/src/Processor/PaymentsStatusHandlingTrait.php">
710
+ <PossiblyNullReference occurrences="2">
711
+ <code>authorizations</code>
712
+ <code>captures</code>
713
+ </PossiblyNullReference>
714
+ </file>
715
+ <file src="modules/ppcp-wc-gateway/src/Processor/RefundProcessor.php">
716
+ <PossiblyFalseArgument occurrences="1">
717
+ <code>wp_json_encode( $payments-&gt;to_array() )</code>
718
+ </PossiblyFalseArgument>
719
+ <PossiblyNullArgument occurrences="1">
720
+ <code>$amount</code>
721
+ </PossiblyNullArgument>
722
+ </file>
723
+ <file src="modules/ppcp-wc-gateway/src/Settings/SectionsRenderer.php">
724
+ <MissingReturnType occurrences="1">
725
+ <code>render</code>
726
+ </MissingReturnType>
727
+ </file>
728
+ <file src="modules/ppcp-wc-gateway/src/Settings/Settings.php">
729
+ <MissingReturnType occurrences="2">
730
+ <code>persist</code>
731
+ <code>set</code>
732
+ </MissingReturnType>
733
+ </file>
734
+ <file src="modules/ppcp-wc-gateway/src/Settings/SettingsListener.php">
735
+ <MissingReturnType occurrences="3">
736
+ <code>listen</code>
737
+ <code>listen_for_merchant_id</code>
738
+ <code>listen_for_vaulting_enabled</code>
739
+ </MissingReturnType>
740
+ <PossiblyInvalidArgument occurrences="3">
741
+ <code>wp_unslash( $_GET['merchantId'] )</code>
742
+ <code>wp_unslash( $_GET['merchantIdInPayPal'] )</code>
743
+ <code>wp_unslash( $_POST['ppcp-nonce'] )</code>
744
+ </PossiblyInvalidArgument>
745
+ </file>
746
+ <file src="modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php">
747
+ <InvalidArgument occurrences="1">
748
+ <code>$value</code>
749
+ </InvalidArgument>
750
+ <InvalidOperand occurrences="3">
751
+ <code>$field</code>
752
+ <code>$field</code>
753
+ <code>$field</code>
754
+ </InvalidOperand>
755
+ <MissingReturnType occurrences="5">
756
+ <code>render</code>
757
+ <code>render_dcc_does_not_apply_info</code>
758
+ <code>render_dcc_not_active_yet</code>
759
+ <code>render_dcc_onboarding_info</code>
760
+ <code>render_text</code>
761
+ </MissingReturnType>
762
+ <RedundantCast occurrences="1">
763
+ <code>(int) $colspan</code>
764
+ </RedundantCast>
765
+ </file>
766
+ <file src="modules/ppcp-wc-gateway/src/WCGatewayModule.php">
767
+ <MissingClosureParamType occurrences="15">
768
+ <code>$args</code>
769
+ <code>$args</code>
770
+ <code>$column</code>
771
+ <code>$columns</code>
772
+ <code>$field</code>
773
+ <code>$key</code>
774
+ <code>$methods</code>
775
+ <code>$methods</code>
776
+ <code>$notices</code>
777
+ <code>$order</code>
778
+ <code>$order_actions</code>
779
+ <code>$recipient</code>
780
+ <code>$value</code>
781
+ <code>$wc_order_id</code>
782
+ <code>$wc_order_id</code>
783
+ </MissingClosureParamType>
784
+ <MissingReturnType occurrences="4">
785
+ <code>register_checkout_paypal_address_preset</code>
786
+ <code>register_columns</code>
787
+ <code>register_order_functionality</code>
788
+ <code>register_payment_gateways</code>
789
+ </MissingReturnType>
790
+ </file>
791
+ <file src="modules/ppcp-webhooks/extensions.php">
792
+ <MissingClosureParamType occurrences="1">
793
+ <code>$container</code>
794
+ </MissingClosureParamType>
795
+ </file>
796
+ <file src="modules/ppcp-webhooks/src/Endpoint/ResubscribeEndpoint.php">
797
+ <MissingReturnType occurrences="1">
798
+ <code>handle_request</code>
799
+ </MissingReturnType>
800
+ </file>
801
+ <file src="modules/ppcp-webhooks/src/Endpoint/SimulateEndpoint.php">
802
+ <MissingReturnType occurrences="1">
803
+ <code>handle_request</code>
804
+ </MissingReturnType>
805
+ </file>
806
+ <file src="modules/ppcp-webhooks/src/Endpoint/SimulationStateEndpoint.php">
807
+ <MissingReturnType occurrences="1">
808
+ <code>handle_request</code>
809
+ </MissingReturnType>
810
+ </file>
811
+ <file src="modules/ppcp-webhooks/src/Handler/CheckoutOrderApproved.php">
812
+ <InvalidReturnStatement occurrences="5">
813
+ <code>rest_ensure_response( $response )</code>
814
+ <code>rest_ensure_response( $response )</code>
815
+ <code>rest_ensure_response( $response )</code>
816
+ <code>rest_ensure_response( $response )</code>
817
+ <code>rest_ensure_response( $response )</code>
818
+ </InvalidReturnStatement>
819
+ <InvalidReturnType occurrences="1">
820
+ <code>\WP_REST_Response</code>
821
+ </InvalidReturnType>
822
+ <PossibleRawObjectIteration occurrences="1">
823
+ <code>$wc_orders</code>
824
+ </PossibleRawObjectIteration>
825
+ <PossiblyNullArgument occurrences="5">
826
+ <code>$request['resource']['id']</code>
827
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
828
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
829
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
830
+ <code>isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''</code>
831
+ </PossiblyNullArgument>
832
+ <PossiblyNullArrayAccess occurrences="3">
833
+ <code>$request['resource']['id']</code>
834
+ <code>$request['resource']['id']</code>
835
+ <code>$request['resource']['purchase_units']</code>
836
+ </PossiblyNullArrayAccess>
837
+ </file>
838
+ <file src="modules/ppcp-webhooks/src/Handler/CheckoutOrderCompleted.php">
839
+ <InvalidReturnStatement occurrences="3">
840
+ <code>rest_ensure_response( $response )</code>
841
+ <code>rest_ensure_response( $response )</code>
842
+ <code>rest_ensure_response( $response )</code>
843
+ </InvalidReturnStatement>
844
+ <InvalidReturnType occurrences="1">
845
+ <code>\WP_REST_Response</code>
846
+ </InvalidReturnType>
847
+ <PossibleRawObjectIteration occurrences="1">
848
+ <code>$wc_orders</code>
849
+ </PossibleRawObjectIteration>
850
+ <PossiblyNullArgument occurrences="2">
851
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
852
+ <code>isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''</code>
853
+ </PossiblyNullArgument>
854
+ <PossiblyNullArrayAccess occurrences="2">
855
+ <code>$request['resource']['id']</code>
856
+ <code>$request['resource']['purchase_units']</code>
857
+ </PossiblyNullArrayAccess>
858
+ </file>
859
+ <file src="modules/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php">
860
+ <InvalidReturnStatement occurrences="4">
861
+ <code>rest_ensure_response( $response )</code>
862
+ <code>rest_ensure_response( $response )</code>
863
+ <code>rest_ensure_response( $response )</code>
864
+ <code>rest_ensure_response( $response )</code>
865
+ </InvalidReturnStatement>
866
+ <InvalidReturnType occurrences="1">
867
+ <code>\WP_REST_Response</code>
868
+ </InvalidReturnType>
869
+ <PossiblyNullArgument occurrences="3">
870
+ <code>$request['resource']['custom_id']</code>
871
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
872
+ <code>isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''</code>
873
+ </PossiblyNullArgument>
874
+ <PossiblyNullArrayAccess occurrences="3">
875
+ <code>$request['resource']['amount']</code>
876
+ <code>$request['resource']['custom_id']</code>
877
+ <code>$request['resource']['id']</code>
878
+ </PossiblyNullArrayAccess>
879
+ <PossiblyUndefinedMethod occurrences="2">
880
+ <code>get_amount</code>
881
+ <code>get_error_message</code>
882
+ </PossiblyUndefinedMethod>
883
+ </file>
884
+ <file src="modules/ppcp-webhooks/src/Handler/PaymentCaptureReversed.php">
885
+ <InvalidReturnStatement occurrences="3">
886
+ <code>rest_ensure_response( $response )</code>
887
+ <code>rest_ensure_response( $response )</code>
888
+ <code>rest_ensure_response( $response )</code>
889
+ </InvalidReturnStatement>
890
+ <InvalidReturnType occurrences="1">
891
+ <code>\WP_REST_Response</code>
892
+ </InvalidReturnType>
893
+ <PossiblyNullArgument occurrences="3">
894
+ <code>$request['resource']['custom_id']</code>
895
+ <code>isset( $request['id'] ) ? $request['id'] : ''</code>
896
+ <code>isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''</code>
897
+ </PossiblyNullArgument>
898
+ <PossiblyNullArrayAccess occurrences="2">
899
+ <code>$request['resource']['custom_id']</code>
900
+ <code>$request['resource']['id']</code>
901
+ </PossiblyNullArrayAccess>
902
+ <RedundantCastGivenDocblockType occurrences="1">
903
+ <code>(bool) $wc_order-&gt;update_status( 'cancelled' )</code>
904
+ </RedundantCastGivenDocblockType>
905
+ </file>
906
+ <file src="modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php">
907
+ <InvalidReturnStatement occurrences="2">
908
+ <code>rest_ensure_response( $response )</code>
909
+ </InvalidReturnStatement>
910
+ <InvalidReturnType occurrences="1">
911
+ <code>\WP_REST_Response</code>
912
+ </InvalidReturnType>
913
+ <PossiblyFalseArgument occurrences="1">
914
+ <code>( $handler-&gt;event_types() ) ? current( $handler-&gt;event_types() ) : ''</code>
915
+ </PossiblyFalseArgument>
916
+ <PossiblyNullArgument occurrences="1">
917
+ <code>$request['event_type']</code>
918
+ </PossiblyNullArgument>
919
+ <RedundantCastGivenDocblockType occurrences="1"/>
920
+ </file>
921
+ </files>
psalm.xml.dist ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <psalm
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xmlns="https://getpsalm.org/schema/config"
5
+ xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
6
+ xmlns:xi="http://www.w3.org/2001/XInclude"
7
+ totallyTyped="false"
8
+ useDocblockTypes="true"
9
+ usePhpDocMethodsWithoutMagicCall="false"
10
+ strictBinaryOperands="true"
11
+ rememberPropertyAssignmentsAfterCall="true"
12
+ allowPhpStormGenerics="true"
13
+ allowStringToStandInForClass="false"
14
+ memoizeMethodCallResults="false"
15
+ hoistConstants="false"
16
+ addParamDefaultToDocblockType="false"
17
+ checkForThrowsDocblock="true"
18
+ checkForThrowsInGlobalScope="false"
19
+ ignoreInternalFunctionFalseReturn="false"
20
+ ignoreInternalFunctionNullReturn="false"
21
+ throwExceptionOnError="false"
22
+ hideExternalErrors="true"
23
+ allowFileIncludes="true"
24
+ errorBaseline="psalm-baseline.xml"
25
+ >
26
+ <projectFiles>
27
+ <directory name="src"/>
28
+ <directory name="modules" />
29
+ </projectFiles>
30
+
31
+ <stubs>
32
+ <file name=".psalm/stubs.php"/>
33
+ <file name="vendor/php-stubs/wordpress-stubs/wordpress-stubs.php"/>
34
+ <file name="vendor/php-stubs/woocommerce-stubs/woocommerce-stubs.php"/>
35
+ </stubs>
36
+
37
+
38
+ <issueHandlers>
39
+ <ConflictingReferenceConstraint errorLevel="error"/>
40
+ <ContinueOutsideLoop errorLevel="error"/>
41
+ <DuplicateArrayKey errorLevel="error"/>
42
+ <DuplicateClass errorLevel="error"/>
43
+ <DuplicateFunction errorLevel="error"/>
44
+ <DuplicateMethod errorLevel="error"/>
45
+ <DuplicateParam errorLevel="error"/>
46
+ <EmptyArrayAccess errorLevel="error"/>
47
+ <FalsableReturnStatement errorLevel="error"/>
48
+ <FalseOperand errorLevel="error"/>
49
+ <ForbiddenCode errorLevel="error"/>
50
+ <ForbiddenEcho errorLevel="error"/>
51
+ <InaccessibleClassConstant errorLevel="error"/>
52
+ <InaccessibleMethod errorLevel="error"/>
53
+ <InterfaceInstantiation errorLevel="error"/>
54
+ <InaccessibleProperty errorLevel="error"/>
55
+ <InternalClass errorLevel="error"/>
56
+ <InternalMethod errorLevel="error"/>
57
+ <InternalProperty errorLevel="error"/>
58
+ <InvalidArgument errorLevel="error"/>
59
+ <InvalidArrayAccess errorLevel="error"/>
60
+ <InvalidArrayAssignment errorLevel="error"/>
61
+ <InvalidArrayOffset errorLevel="error"/>
62
+ <InvalidCast errorLevel="error"/>
63
+ <InvalidCatch errorLevel="error"/>
64
+ <InvalidClass errorLevel="error"/>
65
+ <InvalidClone errorLevel="error"/>
66
+ <InvalidFalsableReturnType errorLevel="error"/>
67
+ <InvalidThrow errorLevel="error"/>
68
+ <InvalidToString errorLevel="error"/>
69
+ <LoopInvalidation errorLevel="error"/>
70
+ <InvalidNullableReturnType errorLevel="error"/>
71
+ <LessSpecificReturnType errorLevel="error"/>
72
+ <InvalidGlobal errorLevel="error"/>
73
+ <InvalidIterator errorLevel="error"/>
74
+ <InvalidMethodCall errorLevel="error"/>
75
+ <InvalidFunctionCall errorLevel="error"/>
76
+ <ImplicitToStringCast errorLevel="error"/>
77
+ <ImplementedReturnTypeMismatch errorLevel="error"/>
78
+ <InvalidParamDefault errorLevel="error"/>
79
+ <InvalidPassByReference errorLevel="error"/>
80
+ <InvalidPropertyAssignment errorLevel="error"/>
81
+ <InvalidPropertyAssignmentValue errorLevel="error"/>
82
+ <InvalidPropertyFetch errorLevel="error"/>
83
+ <InvalidReturnStatement errorLevel="error"/>
84
+ <InvalidReturnType errorLevel="error"/>
85
+ <InvalidScalarArgument errorLevel="error"/>
86
+ <InvalidScope errorLevel="error"/>
87
+ <InvalidStaticInvocation errorLevel="error"/>
88
+ <MissingConstructor errorLevel="error"/>
89
+ <MissingDependency errorLevel="error"/>
90
+ <MissingFile errorLevel="error"/>
91
+ <MixedArgument errorLevel="error"/>
92
+ <MoreSpecificImplementedParamType errorLevel="error"/>
93
+ <MoreSpecificReturnType errorLevel="error"/>
94
+ <NoValue errorLevel="error"/>
95
+ <NoInterfaceProperties errorLevel="error"/>
96
+ <NonStaticSelfCall errorLevel="error"/>
97
+ <NullableReturnStatement errorLevel="error"/>
98
+ <NullArgument errorLevel="error"/>
99
+ <NullArrayAccess errorLevel="error"/>
100
+ <NullArrayOffset errorLevel="error"/>
101
+ <NullFunctionCall errorLevel="error"/>
102
+ <NullIterator errorLevel="error"/>
103
+ <NullOperand errorLevel="error"/>
104
+ <NullPropertyAssignment errorLevel="error"/>
105
+ <NullPropertyFetch errorLevel="error"/>
106
+ <NullReference errorLevel="error"/>
107
+ <OverriddenMethodAccess errorLevel="error"/>
108
+ <OverriddenPropertyAccess errorLevel="error"/>
109
+ <ParadoxicalCondition errorLevel="error"/>
110
+ <ParentNotFound errorLevel="error"/>
111
+ <LessSpecificImplementedReturnType errorLevel="error"/>
112
+ <MissingParamType errorLevel="error"/>
113
+ <MissingClosureParamType errorLevel="error"/>
114
+ <MissingClosureReturnType errorLevel="error"/>
115
+ <MissingPropertyType errorLevel="error"/>
116
+ <UndefinedConstant errorLevel="error"/>
117
+
118
+ <AssignmentToVoid errorLevel="info"/>
119
+ <DeprecatedClass errorLevel="info"/>
120
+ <DeprecatedConstant errorLevel="info"/>
121
+ <DeprecatedTrait errorLevel="info"/>
122
+ <DocblockTypeContradiction errorLevel="info"/>
123
+ <InvalidDocblock errorLevel="info"/>
124
+ <InvalidDocblockParamName errorLevel="info"/>
125
+ <InvalidTemplateParam errorLevel="info"/>
126
+ <DeprecatedInterface errorLevel="info"/>
127
+ <DeprecatedMethod errorLevel="info"/>
128
+ <DeprecatedProperty errorLevel="info"/>
129
+ <MethodSignatureMustOmitReturnType errorLevel="info"/>
130
+ <MismatchingDocblockParamType errorLevel="info"/>
131
+ <MismatchingDocblockReturnType errorLevel="info"/>
132
+ <MissingDocblockType errorLevel="info"/>
133
+ <MissingParamType errorLevel="info"/>
134
+ <MissingTemplateParam errorLevel="info"/>
135
+ <MissingThrowsDocblock errorLevel="info"/>
136
+ <MixedArgumentTypeCoercion errorLevel="info"/>
137
+ <MixedArrayAccess errorLevel="info"/>
138
+ <MixedArrayAssignment errorLevel="info"/>
139
+ <MixedArrayOffset errorLevel="info"/>
140
+ <MixedArrayTypeCoercion errorLevel="info"/>
141
+ <MixedAssignment errorLevel="info"/>
142
+ <MixedFunctionCall errorLevel="info"/>
143
+ <MixedInferredReturnType errorLevel="info"/>
144
+ <MixedMethodCall errorLevel="info"/>
145
+ <MixedOperand errorLevel="info"/>
146
+ <MixedPropertyAssignment errorLevel="info"/>
147
+ <MixedPropertyFetch errorLevel="info"/>
148
+ <MixedPropertyTypeCoercion errorLevel="info"/>
149
+ <MixedReturnStatement errorLevel="info"/>
150
+ <MixedReturnTypeCoercion errorLevel="info"/>
151
+ <MixedStringOffsetAssignment errorLevel="info"/>
152
+ <ParamNameMismatch errorLevel="info"/>
153
+ </issueHandlers>
154
+ </psalm>
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.1
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -81,6 +81,23 @@ Follow the steps below to connect the plugin to your PayPal account:
81
 
82
  == Changelog ==
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  = 1.6.1 =
85
  * Fix - Handle authorization capture failures #312
86
  * Fix - Handle denied payment authorization #302
4
  Requires at least: 5.3
5
  Tested up to: 5.8
6
  Requires PHP: 7.1
7
+ Stable tag: 1.6.2
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
81
 
82
  == Changelog ==
83
 
84
+ = 1.6.2 =
85
+ * Fix - Order of WooCommerce checkout actions causing incompatibility with AvaTax address validation #335
86
+ * Fix - Can't checkout to certain countries with optional postcode #330
87
+ * Fix - Prevent subscription from being purchased when saving payment fails #308
88
+ * Fix - Guest users must checkout twice for subscriptions, no smart buttons loaded #342
89
+ * Fix - Failed PayPal API request causing strange error #347
90
+ * Fix - PayPal payments page empty after switching packages #350
91
+ * Fix - Could Not Validate Nonce Error #239
92
+ * Fix - Refund via PayPal dashboard does not set the WooCommerce order to "Refunded" #241
93
+ * Fix - Uncaught TypeError: round() #344
94
+ * Fix - Broken multi-level (nested) associative array values after getting submitted from checkout page #307
95
+ * Fix - Transaction id missing in some cases #328
96
+ * Fix - Payment not possible in pay for order form because of terms checkbox missing #294
97
+ * Fix - "Save your Credit Card" shouldn't be optional when paying for a subscription #368
98
+ * Fix - When paying for a subscription and vaulting fails, cart is cleared #367
99
+ * Fix - Fatal error when activating PayPal Checkout plugin #363
100
+
101
  = 1.6.1 =
102
  * Fix - Handle authorization capture failures #312
103
  * Fix - Handle denied payment authorization #302
src/{class-pluginmodule.php → PluginModule.php} RENAMED
@@ -20,18 +20,16 @@ use Psr\Container\ContainerInterface;
20
  class PluginModule implements ModuleInterface {
21
 
22
  /**
23
- * Sets the module up.
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider( array(), array() );
27
  }
28
 
29
  /**
30
- * Runs the module.
31
- *
32
- * @param ContainerInterface|null $container The Container.
33
  */
34
- public function run( ContainerInterface $container ): void {
35
  }
36
 
37
  /**
20
  class PluginModule implements ModuleInterface {
21
 
22
  /**
23
+ * {@inheritDoc}
24
  */
25
  public function setup(): ServiceProviderInterface {
26
  return new ServiceProvider( array(), array() );
27
  }
28
 
29
  /**
30
+ * {@inheritDoc}
 
 
31
  */
32
+ public function run( ContainerInterface $c ): void {
33
  }
34
 
35
  /**
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -37,80 +37,26 @@ namespace Composer\Autoload;
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
- * @see https://www.php-fig.org/psr/psr-0/
41
- * @see https://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
45
- /** @var ?string */
46
- private $vendorDir;
47
-
48
  // PSR-4
49
- /**
50
- * @var array[]
51
- * @psalm-var array<string, array<string, int>>
52
- */
53
  private $prefixLengthsPsr4 = array();
54
- /**
55
- * @var array[]
56
- * @psalm-var array<string, array<int, string>>
57
- */
58
  private $prefixDirsPsr4 = array();
59
- /**
60
- * @var array[]
61
- * @psalm-var array<string, string>
62
- */
63
  private $fallbackDirsPsr4 = array();
64
 
65
  // PSR-0
66
- /**
67
- * @var array[]
68
- * @psalm-var array<string, array<string, string[]>>
69
- */
70
  private $prefixesPsr0 = array();
71
- /**
72
- * @var array[]
73
- * @psalm-var array<string, string>
74
- */
75
  private $fallbackDirsPsr0 = array();
76
 
77
- /** @var bool */
78
  private $useIncludePath = false;
79
-
80
- /**
81
- * @var string[]
82
- * @psalm-var array<string, string>
83
- */
84
  private $classMap = array();
85
-
86
- /** @var bool */
87
  private $classMapAuthoritative = false;
88
-
89
- /**
90
- * @var bool[]
91
- * @psalm-var array<string, bool>
92
- */
93
  private $missingClasses = array();
94
-
95
- /** @var ?string */
96
  private $apcuPrefix;
97
 
98
- /**
99
- * @var self[]
100
- */
101
- private static $registeredLoaders = array();
102
-
103
- /**
104
- * @param ?string $vendorDir
105
- */
106
- public function __construct($vendorDir = null)
107
- {
108
- $this->vendorDir = $vendorDir;
109
- }
110
-
111
- /**
112
- * @return string[]
113
- */
114
  public function getPrefixes()
115
  {
116
  if (!empty($this->prefixesPsr0)) {
@@ -120,47 +66,28 @@ class ClassLoader
120
  return array();
121
  }
122
 
123
- /**
124
- * @return array[]
125
- * @psalm-return array<string, array<int, string>>
126
- */
127
  public function getPrefixesPsr4()
128
  {
129
  return $this->prefixDirsPsr4;
130
  }
131
 
132
- /**
133
- * @return array[]
134
- * @psalm-return array<string, string>
135
- */
136
  public function getFallbackDirs()
137
  {
138
  return $this->fallbackDirsPsr0;
139
  }
140
 
141
- /**
142
- * @return array[]
143
- * @psalm-return array<string, string>
144
- */
145
  public function getFallbackDirsPsr4()
146
  {
147
  return $this->fallbackDirsPsr4;
148
  }
149
 
150
- /**
151
- * @return string[] Array of classname => path
152
- * @psalm-var array<string, string>
153
- */
154
  public function getClassMap()
155
  {
156
  return $this->classMap;
157
  }
158
 
159
  /**
160
- * @param string[] $classMap Class to filename map
161
- * @psalm-param array<string, string> $classMap
162
- *
163
- * @return void
164
  */
165
  public function addClassMap(array $classMap)
166
  {
@@ -175,11 +102,9 @@ class ClassLoader
175
  * Registers a set of PSR-0 directories for a given prefix, either
176
  * appending or prepending to the ones previously set for this prefix.
177
  *
178
- * @param string $prefix The prefix
179
- * @param string[]|string $paths The PSR-0 root directories
180
- * @param bool $prepend Whether to prepend the directories
181
- *
182
- * @return void
183
  */
184
  public function add($prefix, $paths, $prepend = false)
185
  {
@@ -222,13 +147,11 @@ class ClassLoader
222
  * Registers a set of PSR-4 directories for a given namespace, either
223
  * appending or prepending to the ones previously set for this namespace.
224
  *
225
- * @param string $prefix The prefix/namespace, with trailing '\\'
226
- * @param string[]|string $paths The PSR-4 base directories
227
- * @param bool $prepend Whether to prepend the directories
228
  *
229
  * @throws \InvalidArgumentException
230
- *
231
- * @return void
232
  */
233
  public function addPsr4($prefix, $paths, $prepend = false)
234
  {
@@ -272,10 +195,8 @@ class ClassLoader
272
  * Registers a set of PSR-0 directories for a given prefix,
273
  * replacing any others previously set for this prefix.
274
  *
275
- * @param string $prefix The prefix
276
- * @param string[]|string $paths The PSR-0 base directories
277
- *
278
- * @return void
279
  */
280
  public function set($prefix, $paths)
281
  {
@@ -290,12 +211,10 @@ class ClassLoader
290
  * Registers a set of PSR-4 directories for a given namespace,
291
  * replacing any others previously set for this namespace.
292
  *
293
- * @param string $prefix The prefix/namespace, with trailing '\\'
294
- * @param string[]|string $paths The PSR-4 base directories
295
  *
296
  * @throws \InvalidArgumentException
297
- *
298
- * @return void
299
  */
300
  public function setPsr4($prefix, $paths)
301
  {
@@ -315,8 +234,6 @@ class ClassLoader
315
  * Turns on searching the include path for class files.
316
  *
317
  * @param bool $useIncludePath
318
- *
319
- * @return void
320
  */
321
  public function setUseIncludePath($useIncludePath)
322
  {
@@ -339,8 +256,6 @@ class ClassLoader
339
  * that have not been registered with the class map.
340
  *
341
  * @param bool $classMapAuthoritative
342
- *
343
- * @return void
344
  */
345
  public function setClassMapAuthoritative($classMapAuthoritative)
346
  {
@@ -361,8 +276,6 @@ class ClassLoader
361
  * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
362
  *
363
  * @param string|null $apcuPrefix
364
- *
365
- * @return void
366
  */
367
  public function setApcuPrefix($apcuPrefix)
368
  {
@@ -383,44 +296,25 @@ class ClassLoader
383
  * Registers this instance as an autoloader.
384
  *
385
  * @param bool $prepend Whether to prepend the autoloader or not
386
- *
387
- * @return void
388
  */
389
  public function register($prepend = false)
390
  {
391
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
392
-
393
- if (null === $this->vendorDir) {
394
- return;
395
- }
396
-
397
- if ($prepend) {
398
- self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
399
- } else {
400
- unset(self::$registeredLoaders[$this->vendorDir]);
401
- self::$registeredLoaders[$this->vendorDir] = $this;
402
- }
403
  }
404
 
405
  /**
406
  * Unregisters this instance as an autoloader.
407
- *
408
- * @return void
409
  */
410
  public function unregister()
411
  {
412
  spl_autoload_unregister(array($this, 'loadClass'));
413
-
414
- if (null !== $this->vendorDir) {
415
- unset(self::$registeredLoaders[$this->vendorDir]);
416
- }
417
  }
418
 
419
  /**
420
  * Loads the given class or interface.
421
  *
422
  * @param string $class The name of the class
423
- * @return true|null True if loaded, null otherwise
424
  */
425
  public function loadClass($class)
426
  {
@@ -429,8 +323,6 @@ class ClassLoader
429
 
430
  return true;
431
  }
432
-
433
- return null;
434
  }
435
 
436
  /**
@@ -475,21 +367,6 @@ class ClassLoader
475
  return $file;
476
  }
477
 
478
- /**
479
- * Returns the currently registered loaders indexed by their corresponding vendor directories.
480
- *
481
- * @return self[]
482
- */
483
- public static function getRegisteredLoaders()
484
- {
485
- return self::$registeredLoaders;
486
- }
487
-
488
- /**
489
- * @param string $class
490
- * @param string $ext
491
- * @return string|false
492
- */
493
  private function findFileWithExtension($class, $ext)
494
  {
495
  // PSR-4 lookup
@@ -561,10 +438,6 @@ class ClassLoader
561
  * Scope isolated include.
562
  *
563
  * Prevents access to $this/self from included files.
564
- *
565
- * @param string $file
566
- * @return void
567
- * @private
568
  */
569
  function includeFile($file)
570
  {
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
 
 
 
45
  // PSR-4
 
 
 
 
46
  private $prefixLengthsPsr4 = array();
 
 
 
 
47
  private $prefixDirsPsr4 = array();
 
 
 
 
48
  private $fallbackDirsPsr4 = array();
49
 
50
  // PSR-0
 
 
 
 
51
  private $prefixesPsr0 = array();
 
 
 
 
52
  private $fallbackDirsPsr0 = array();
53
 
 
54
  private $useIncludePath = false;
 
 
 
 
 
55
  private $classMap = array();
 
 
56
  private $classMapAuthoritative = false;
 
 
 
 
 
57
  private $missingClasses = array();
 
 
58
  private $apcuPrefix;
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  public function getPrefixes()
61
  {
62
  if (!empty($this->prefixesPsr0)) {
66
  return array();
67
  }
68
 
 
 
 
 
69
  public function getPrefixesPsr4()
70
  {
71
  return $this->prefixDirsPsr4;
72
  }
73
 
 
 
 
 
74
  public function getFallbackDirs()
75
  {
76
  return $this->fallbackDirsPsr0;
77
  }
78
 
 
 
 
 
79
  public function getFallbackDirsPsr4()
80
  {
81
  return $this->fallbackDirsPsr4;
82
  }
83
 
 
 
 
 
84
  public function getClassMap()
85
  {
86
  return $this->classMap;
87
  }
88
 
89
  /**
90
+ * @param array $classMap Class to filename map
 
 
 
91
  */
92
  public function addClassMap(array $classMap)
93
  {
102
  * Registers a set of PSR-0 directories for a given prefix, either
103
  * appending or prepending to the ones previously set for this prefix.
104
  *
105
+ * @param string $prefix The prefix
106
+ * @param array|string $paths The PSR-0 root directories
107
+ * @param bool $prepend Whether to prepend the directories
 
 
108
  */
109
  public function add($prefix, $paths, $prepend = false)
110
  {
147
  * Registers a set of PSR-4 directories for a given namespace, either
148
  * appending or prepending to the ones previously set for this namespace.
149
  *
150
+ * @param string $prefix The prefix/namespace, with trailing '\\'
151
+ * @param array|string $paths The PSR-4 base directories
152
+ * @param bool $prepend Whether to prepend the directories
153
  *
154
  * @throws \InvalidArgumentException
 
 
155
  */
156
  public function addPsr4($prefix, $paths, $prepend = false)
157
  {
195
  * Registers a set of PSR-0 directories for a given prefix,
196
  * replacing any others previously set for this prefix.
197
  *
198
+ * @param string $prefix The prefix
199
+ * @param array|string $paths The PSR-0 base directories
 
 
200
  */
201
  public function set($prefix, $paths)
202
  {
211
  * Registers a set of PSR-4 directories for a given namespace,
212
  * replacing any others previously set for this namespace.
213
  *
214
+ * @param string $prefix The prefix/namespace, with trailing '\\'
215
+ * @param array|string $paths The PSR-4 base directories
216
  *
217
  * @throws \InvalidArgumentException
 
 
218
  */
219
  public function setPsr4($prefix, $paths)
220
  {
234
  * Turns on searching the include path for class files.
235
  *
236
  * @param bool $useIncludePath
 
 
237
  */
238
  public function setUseIncludePath($useIncludePath)
239
  {
256
  * that have not been registered with the class map.
257
  *
258
  * @param bool $classMapAuthoritative
 
 
259
  */
260
  public function setClassMapAuthoritative($classMapAuthoritative)
261
  {
276
  * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277
  *
278
  * @param string|null $apcuPrefix
 
 
279
  */
280
  public function setApcuPrefix($apcuPrefix)
281
  {
296
  * Registers this instance as an autoloader.
297
  *
298
  * @param bool $prepend Whether to prepend the autoloader or not
 
 
299
  */
300
  public function register($prepend = false)
301
  {
302
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
 
 
 
 
 
 
 
 
 
 
 
303
  }
304
 
305
  /**
306
  * Unregisters this instance as an autoloader.
 
 
307
  */
308
  public function unregister()
309
  {
310
  spl_autoload_unregister(array($this, 'loadClass'));
 
 
 
 
311
  }
312
 
313
  /**
314
  * Loads the given class or interface.
315
  *
316
  * @param string $class The name of the class
317
+ * @return bool|null True if loaded, null otherwise
318
  */
319
  public function loadClass($class)
320
  {
323
 
324
  return true;
325
  }
 
 
326
  }
327
 
328
  /**
367
  return $file;
368
  }
369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  private function findFileWithExtension($class, $ext)
371
  {
372
  // PSR-4 lookup
438
  * Scope isolated include.
439
  *
440
  * Prevents access to $this/self from included files.
 
 
 
 
441
  */
442
  function includeFile($file)
443
  {
vendor/composer/InstalledVersions.php DELETED
@@ -1,337 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Composer.
5
- *
6
- * (c) Nils Adermann <naderman@naderman.de>
7
- * Jordi Boggiano <j.boggiano@seld.be>
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
-
13
- namespace Composer;
14
-
15
- use Composer\Autoload\ClassLoader;
16
- use Composer\Semver\VersionParser;
17
-
18
- /**
19
- * This class is copied in every Composer installed project and available to all
20
- *
21
- * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
22
- *
23
- * To require its presence, you can require `composer-runtime-api ^2.0`
24
- */
25
- class InstalledVersions
26
- {
27
- private static $installed;
28
- private static $canGetVendors;
29
- private static $installedByVendor = array();
30
-
31
- /**
32
- * Returns a list of all package names which are present, either by being installed, replaced or provided
33
- *
34
- * @return string[]
35
- * @psalm-return list<string>
36
- */
37
- public static function getInstalledPackages()
38
- {
39
- $packages = array();
40
- foreach (self::getInstalled() as $installed) {
41
- $packages[] = array_keys($installed['versions']);
42
- }
43
-
44
- if (1 === \count($packages)) {
45
- return $packages[0];
46
- }
47
-
48
- return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
49
- }
50
-
51
- /**
52
- * Returns a list of all package names with a specific type e.g. 'library'
53
- *
54
- * @param string $type
55
- * @return string[]
56
- * @psalm-return list<string>
57
- */
58
- public static function getInstalledPackagesByType($type)
59
- {
60
- $packagesByType = array();
61
-
62
- foreach (self::getInstalled() as $installed) {
63
- foreach ($installed['versions'] as $name => $package) {
64
- if (isset($package['type']) && $package['type'] === $type) {
65
- $packagesByType[] = $name;
66
- }
67
- }
68
- }
69
-
70
- return $packagesByType;
71
- }
72
-
73
- /**
74
- * Checks whether the given package is installed
75
- *
76
- * This also returns true if the package name is provided or replaced by another package
77
- *
78
- * @param string $packageName
79
- * @param bool $includeDevRequirements
80
- * @return bool
81
- */
82
- public static function isInstalled($packageName, $includeDevRequirements = true)
83
- {
84
- foreach (self::getInstalled() as $installed) {
85
- if (isset($installed['versions'][$packageName])) {
86
- return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
87
- }
88
- }
89
-
90
- return false;
91
- }
92
-
93
- /**
94
- * Checks whether the given package satisfies a version constraint
95
- *
96
- * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
97
- *
98
- * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
99
- *
100
- * @param VersionParser $parser Install composer/semver to have access to this class and functionality
101
- * @param string $packageName
102
- * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
103
- * @return bool
104
- */
105
- public static function satisfies(VersionParser $parser, $packageName, $constraint)
106
- {
107
- $constraint = $parser->parseConstraints($constraint);
108
- $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
109
-
110
- return $provided->matches($constraint);
111
- }
112
-
113
- /**
114
- * Returns a version constraint representing all the range(s) which are installed for a given package
115
- *
116
- * It is easier to use this via isInstalled() with the $constraint argument if you need to check
117
- * whether a given version of a package is installed, and not just whether it exists
118
- *
119
- * @param string $packageName
120
- * @return string Version constraint usable with composer/semver
121
- */
122
- public static function getVersionRanges($packageName)
123
- {
124
- foreach (self::getInstalled() as $installed) {
125
- if (!isset($installed['versions'][$packageName])) {
126
- continue;
127
- }
128
-
129
- $ranges = array();
130
- if (isset($installed['versions'][$packageName]['pretty_version'])) {
131
- $ranges[] = $installed['versions'][$packageName]['pretty_version'];
132
- }
133
- if (array_key_exists('aliases', $installed['versions'][$packageName])) {
134
- $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
135
- }
136
- if (array_key_exists('replaced', $installed['versions'][$packageName])) {
137
- $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
138
- }
139
- if (array_key_exists('provided', $installed['versions'][$packageName])) {
140
- $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
141
- }
142
-
143
- return implode(' || ', $ranges);
144
- }
145
-
146
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
147
- }
148
-
149
- /**
150
- * @param string $packageName
151
- * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
152
- */
153
- public static function getVersion($packageName)
154
- {
155
- foreach (self::getInstalled() as $installed) {
156
- if (!isset($installed['versions'][$packageName])) {
157
- continue;
158
- }
159
-
160
- if (!isset($installed['versions'][$packageName]['version'])) {
161
- return null;
162
- }
163
-
164
- return $installed['versions'][$packageName]['version'];
165
- }
166
-
167
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
168
- }
169
-
170
- /**
171
- * @param string $packageName
172
- * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
173
- */
174
- public static function getPrettyVersion($packageName)
175
- {
176
- foreach (self::getInstalled() as $installed) {
177
- if (!isset($installed['versions'][$packageName])) {
178
- continue;
179
- }
180
-
181
- if (!isset($installed['versions'][$packageName]['pretty_version'])) {
182
- return null;
183
- }
184
-
185
- return $installed['versions'][$packageName]['pretty_version'];
186
- }
187
-
188
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
189
- }
190
-
191
- /**
192
- * @param string $packageName
193
- * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
194
- */
195
- public static function getReference($packageName)
196
- {
197
- foreach (self::getInstalled() as $installed) {
198
- if (!isset($installed['versions'][$packageName])) {
199
- continue;
200
- }
201
-
202
- if (!isset($installed['versions'][$packageName]['reference'])) {
203
- return null;
204
- }
205
-
206
- return $installed['versions'][$packageName]['reference'];
207
- }
208
-
209
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
210
- }
211
-
212
- /**
213
- * @param string $packageName
214
- * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
215
- */
216
- public static function getInstallPath($packageName)
217
- {
218
- foreach (self::getInstalled() as $installed) {
219
- if (!isset($installed['versions'][$packageName])) {
220
- continue;
221
- }
222
-
223
- return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
224
- }
225
-
226
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
227
- }
228
-
229
- /**
230
- * @return array
231
- * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
232
- */
233
- public static function getRootPackage()
234
- {
235
- $installed = self::getInstalled();
236
-
237
- return $installed[0]['root'];
238
- }
239
-
240
- /**
241
- * Returns the raw installed.php data for custom implementations
242
- *
243
- * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
244
- * @return array[]
245
- * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
246
- */
247
- public static function getRawData()
248
- {
249
- @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
250
-
251
- if (null === self::$installed) {
252
- // only require the installed.php file if this file is loaded from its dumped location,
253
- // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
254
- if (substr(__DIR__, -8, 1) !== 'C') {
255
- self::$installed = include __DIR__ . '/installed.php';
256
- } else {
257
- self::$installed = array();
258
- }
259
- }
260
-
261
- return self::$installed;
262
- }
263
-
264
- /**
265
- * Returns the raw data of all installed.php which are currently loaded for custom implementations
266
- *
267
- * @return array[]
268
- * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
269
- */
270
- public static function getAllRawData()
271
- {
272
- return self::getInstalled();
273
- }
274
-
275
- /**
276
- * Lets you reload the static array from another file
277
- *
278
- * This is only useful for complex integrations in which a project needs to use
279
- * this class but then also needs to execute another project's autoloader in process,
280
- * and wants to ensure both projects have access to their version of installed.php.
281
- *
282
- * A typical case would be PHPUnit, where it would need to make sure it reads all
283
- * the data it needs from this class, then call reload() with
284
- * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
285
- * the project in which it runs can then also use this class safely, without
286
- * interference between PHPUnit's dependencies and the project's dependencies.
287
- *
288
- * @param array[] $data A vendor/composer/installed.php data set
289
- * @return void
290
- *
291
- * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
292
- */
293
- public static function reload($data)
294
- {
295
- self::$installed = $data;
296
- self::$installedByVendor = array();
297
- }
298
-
299
- /**
300
- * @return array[]
301
- * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
302
- */
303
- private static function getInstalled()
304
- {
305
- if (null === self::$canGetVendors) {
306
- self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
307
- }
308
-
309
- $installed = array();
310
-
311
- if (self::$canGetVendors) {
312
- foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
313
- if (isset(self::$installedByVendor[$vendorDir])) {
314
- $installed[] = self::$installedByVendor[$vendorDir];
315
- } elseif (is_file($vendorDir.'/composer/installed.php')) {
316
- $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
317
- if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
318
- self::$installed = $installed[count($installed) - 1];
319
- }
320
- }
321
- }
322
- }
323
-
324
- if (null === self::$installed) {
325
- // only require the installed.php file if this file is loaded from its dumped location,
326
- // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
327
- if (substr(__DIR__, -8, 1) !== 'C') {
328
- self::$installed = require __DIR__ . '/installed.php';
329
- } else {
330
- self::$installed = array();
331
- }
332
- }
333
- $installed[] = self::$installed;
334
-
335
- return $installed;
336
- }
337
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/autoload_classmap.php CHANGED
@@ -6,181 +6,4 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
- 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\AdminNotices' => $baseDir . '/modules/ppcp-admin-notices/src/class-adminnotices.php',
11
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Entity\\Message' => $baseDir . '/modules/ppcp-admin-notices/src/Entity/class-message.php',
12
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\Renderer' => $baseDir . '/modules/ppcp-admin-notices/src/Renderer/class-renderer.php',
13
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\RendererInterface' => $baseDir . '/modules/ppcp-admin-notices/src/Renderer/class-rendererinterface.php',
14
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\Repository' => $baseDir . '/modules/ppcp-admin-notices/src/Repository/class-repository.php',
15
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\RepositoryInterface' => $baseDir . '/modules/ppcp-admin-notices/src/Repository/class-repositoryinterface.php',
16
- 'WooCommerce\\PayPalCommerce\\ApiClient\\ApiModule' => $baseDir . '/modules/ppcp-api-client/src/class-apimodule.php',
17
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\Bearer' => $baseDir . '/modules/ppcp-api-client/src/Authentication/class-bearer.php',
18
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\ConnectBearer' => $baseDir . '/modules/ppcp-api-client/src/Authentication/class-connectbearer.php',
19
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\PayPalBearer' => $baseDir . '/modules/ppcp-api-client/src/Authentication/class-paypalbearer.php',
20
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\IdentityToken' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-identitytoken.php',
21
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\LoginSeller' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-loginseller.php',
22
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\OrderEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php',
23
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnerReferrals' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-partnerreferrals.php',
24
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnersEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-partnersendpoint.php',
25
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentTokenEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-paymenttokenendpoint.php',
26
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentsEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-paymentsendpoint.php',
27
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\RequestTrait' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-requesttrait.php',
28
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\WebhookEndpoint' => $baseDir . '/modules/ppcp-api-client/src/Endpoint/class-webhookendpoint.php',
29
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Address' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-address.php',
30
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Amount' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-amount.php',
31
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AmountBreakdown' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-amountbreakdown.php',
32
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\ApplicationContext' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-applicationcontext.php',
33
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Authorization' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-authorization.php',
34
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-authorizationstatus.php',
35
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatusDetails' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-authorizationstatusdetails.php',
36
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CaptureStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-capturestatus.php',
37
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CaptureStatusDetails' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-capturestatusdetails.php',
38
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CardAuthenticationResult' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-cardauthenticationresult.php',
39
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Item' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-item.php',
40
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Money' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-money.php',
41
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Order' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-order.php',
42
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\OrderStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-orderstatus.php',
43
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Patch' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-patch.php',
44
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PatchCollection' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-patchcollection.php',
45
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payee' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payee.php',
46
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payer' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payer.php',
47
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerName' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payername.php',
48
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerTaxInfo' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payertaxinfo.php',
49
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentMethod' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentmethod.php',
50
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSource' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentsource.php',
51
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceCard' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentsourcecard.php',
52
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceWallet' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymentsourcewallet.php',
53
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentToken' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-paymenttoken.php',
54
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payments' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-payments.php',
55
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Phone' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-phone.php',
56
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PhoneWithType' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-phonewithtype.php',
57
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PurchaseUnit' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-purchaseunit.php',
58
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Refund' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-refund.php',
59
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatus' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-sellerstatus.php',
60
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatusProduct' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-sellerstatusproduct.php',
61
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Shipping' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-shipping.php',
62
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Token' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-token.php',
63
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Webhook' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-webhook.php',
64
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\WebhookEvent' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-webhookevent.php',
65
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\NotFoundException' => $baseDir . '/modules/ppcp-api-client/src/Exception/class-notfoundexception.php',
66
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\PayPalApiException' => $baseDir . '/modules/ppcp-api-client/src/Exception/class-paypalapiexception.php',
67
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\RuntimeException' => $baseDir . '/modules/ppcp-api-client/src/Exception/class-runtimeexception.php',
68
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AddressFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-addressfactory.php',
69
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AmountFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-amountfactory.php',
70
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ApplicationContextFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-applicationcontextfactory.php',
71
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AuthorizationFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-authorizationfactory.php',
72
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\CaptureFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-capturefactory.php',
73
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ItemFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-itemfactory.php',
74
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\OrderFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-orderfactory.php',
75
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PatchCollectionFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-patchcollectionfactory.php',
76
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayeeFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-payeefactory.php',
77
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayerFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-payerfactory.php',
78
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentSourceFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-paymentsourcefactory.php',
79
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentTokenFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-paymenttokenfactory.php',
80
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentsFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-paymentsfactory.php',
81
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PurchaseUnitFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-purchaseunitfactory.php',
82
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\SellerStatusFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-sellerstatusfactory.php',
83
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ShippingFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-shippingfactory.php',
84
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookEventFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-webhookeventfactory.php',
85
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookFactory' => $baseDir . '/modules/ppcp-api-client/src/Factory/class-webhookfactory.php',
86
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\Cache' => $baseDir . '/modules/ppcp-api-client/src/Helper/class-cache.php',
87
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\DccApplies' => $baseDir . '/modules/ppcp-api-client/src/Helper/class-dccapplies.php',
88
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\ErrorResponse' => $baseDir . '/modules/ppcp-api-client/src/Helper/class-errorresponse.php',
89
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\ApplicationContextRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-applicationcontextrepository.php',
90
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\CartRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-cartrepository.php',
91
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PartnerReferralsData' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-partnerreferralsdata.php',
92
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayPalRequestIdRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-paypalrequestidrepository.php',
93
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayeeRepository' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-payeerepository.php',
94
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PurchaseUnitRepositoryInterface' => $baseDir . '/modules/ppcp-api-client/src/Repository/class-purchaseunitrepositoryinterface.php',
95
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\DisabledSmartButton' => $baseDir . '/modules/ppcp-button/src/Assets/class-disabledsmartbutton.php',
96
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButton' => $baseDir . '/modules/ppcp-button/src/Assets/class-smartbutton.php',
97
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButtonInterface' => $baseDir . '/modules/ppcp-button/src/Assets/class-smartbuttoninterface.php',
98
- 'WooCommerce\\PayPalCommerce\\Button\\ButtonModule' => $baseDir . '/modules/ppcp-button/src/class-buttonmodule.php',
99
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ApproveOrderEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-approveorderendpoint.php',
100
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ChangeCartEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-changecartendpoint.php',
101
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\CreateOrderEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-createorderendpoint.php',
102
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\DataClientIdEndpoint' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-dataclientidendpoint.php',
103
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\EndpointInterface' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-endpointinterface.php',
104
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\RequestData' => $baseDir . '/modules/ppcp-button/src/Endpoint/class-requestdata.php',
105
- 'WooCommerce\\PayPalCommerce\\Button\\Exception\\RuntimeException' => $baseDir . '/modules/ppcp-button/src/Exception/class-runtimeexception.php',
106
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\EarlyOrderHandler' => $baseDir . '/modules/ppcp-button/src/Helper/class-earlyorderhandler.php',
107
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesApply' => $baseDir . '/modules/ppcp-button/src/Helper/class-messagesapply.php',
108
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesDisclaimers' => $baseDir . '/modules/ppcp-button/src/Helper/class-messagesdisclaimers.php',
109
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\ThreeDSecure' => $baseDir . '/modules/ppcp-button/src/Helper/class-threedsecure.php',
110
- 'WooCommerce\\PayPalCommerce\\Compat\\CompatModule' => $baseDir . '/modules/ppcp-compat/src/class-compatmodule.php',
111
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\DeactivateNote' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-deactivatenote.php',
112
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\MockGateway' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-mockgateway.php',
113
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\PPECHelper' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-ppechelper.php',
114
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\SettingsImporter' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-settingsimporter.php',
115
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\SubscriptionsHandler' => $baseDir . '/modules/ppcp-compat/src/PPEC/class-subscriptionshandler.php',
116
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Assets\\OnboardingAssets' => $baseDir . '/modules/ppcp-onboarding/src/Assets/class-onboardingassets.php',
117
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Endpoint\\LoginSellerEndpoint' => $baseDir . '/modules/ppcp-onboarding/src/Endpoint/class-loginsellerendpoint.php',
118
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Environment' => $baseDir . '/modules/ppcp-onboarding/src/class-environment.php',
119
- 'WooCommerce\\PayPalCommerce\\Onboarding\\OnboardingModule' => $baseDir . '/modules/ppcp-onboarding/src/class-onboardingmodule.php',
120
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Onboarding_REST_Controller' => $baseDir . '/modules/ppcp-onboarding/src/class-onboarding-rest-controller.php',
121
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Render\\OnboardingRenderer' => $baseDir . '/modules/ppcp-onboarding/src/Render/class-onboardingrenderer.php',
122
- 'WooCommerce\\PayPalCommerce\\Onboarding\\State' => $baseDir . '/modules/ppcp-onboarding/src/class-state.php',
123
- 'WooCommerce\\PayPalCommerce\\PluginModule' => $baseDir . '/src/class-pluginmodule.php',
124
- 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelController' => $baseDir . '/modules/ppcp-session/src/Cancellation/class-cancelcontroller.php',
125
- 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelView' => $baseDir . '/modules/ppcp-session/src/Cancellation/class-cancelview.php',
126
- 'WooCommerce\\PayPalCommerce\\Session\\SessionHandler' => $baseDir . '/modules/ppcp-session/src/class-sessionhandler.php',
127
- 'WooCommerce\\PayPalCommerce\\Session\\SessionModule' => $baseDir . '/modules/ppcp-session/src/class-sessionmodule.php',
128
- 'WooCommerce\\PayPalCommerce\\StatusReport\\Renderer' => $baseDir . '/modules/ppcp-status-report/src/class-renderer.php',
129
- 'WooCommerce\\PayPalCommerce\\StatusReport\\StatusReportModule' => $baseDir . '/modules/ppcp-status-report/src/class-statusreportmodule.php',
130
- 'WooCommerce\\PayPalCommerce\\Subscription\\Helper\\SubscriptionHelper' => $baseDir . '/modules/ppcp-subscription/src/Helper/class-subscriptionhelper.php',
131
- 'WooCommerce\\PayPalCommerce\\Subscription\\RenewalHandler' => $baseDir . '/modules/ppcp-subscription/src/class-renewalhandler.php',
132
- 'WooCommerce\\PayPalCommerce\\Subscription\\SubscriptionModule' => $baseDir . '/modules/ppcp-subscription/src/class-subscriptionmodule.php',
133
- 'WooCommerce\\PayPalCommerce\\Vaulting\\Assets\\MyAccountPaymentsAssets' => $baseDir . '/modules/ppcp-vaulting/src/Assets/class-myaccountpaymentsassets.php',
134
- 'WooCommerce\\PayPalCommerce\\Vaulting\\Endpoint\\DeletePaymentTokenEndpoint' => $baseDir . '/modules/ppcp-vaulting/src/Endpoint/class-deletepaymenttokenendpoint.php',
135
- 'WooCommerce\\PayPalCommerce\\Vaulting\\PaymentTokenRepository' => $baseDir . '/modules/ppcp-vaulting/src/class-paymenttokenrepository.php',
136
- 'WooCommerce\\PayPalCommerce\\Vaulting\\PaymentTokensRenderer' => $baseDir . '/modules/ppcp-vaulting/src/class-paymenttokensrenderer.php',
137
- 'WooCommerce\\PayPalCommerce\\Vaulting\\VaultingModule' => $baseDir . '/modules/ppcp-vaulting/src/class-vaultingmodule.php',
138
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\OrderTablePaymentStatusColumn' => $baseDir . '/modules/ppcp-wc-gateway/src/Admin/class-ordertablepaymentstatuscolumn.php',
139
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\PaymentStatusOrderDetail' => $baseDir . '/modules/ppcp-wc-gateway/src/Admin/class-paymentstatusorderdetail.php',
140
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\RenderAuthorizeAction' => $baseDir . '/modules/ppcp-wc-gateway/src/Admin/class-renderauthorizeaction.php',
141
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Assets\\SettingsPageAssets' => $baseDir . '/modules/ppcp-wc-gateway/src/Assets/class-settingspageassets.php',
142
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Assets\\WebhooksStatusPageAssets' => $baseDir . '/modules/ppcp-webhooks/src/Status/Assets/class-webhooksstatuspageassets.php',
143
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\CheckoutPayPalAddressPreset' => $baseDir . '/modules/ppcp-wc-gateway/src/Checkout/class-checkoutpaypaladdresspreset.php',
144
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\DisableGateways' => $baseDir . '/modules/ppcp-wc-gateway/src/Checkout/class-disablegateways.php',
145
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Endpoint\\ReturnUrlEndpoint' => $baseDir . '/modules/ppcp-wc-gateway/src/Endpoint/class-returnurlendpoint.php',
146
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Exception\\NotFoundException' => $baseDir . '/modules/ppcp-wc-gateway/src/Exception/class-notfoundexception.php',
147
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\CreditCardGateway' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-creditcardgateway.php',
148
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\PayPalGateway' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php',
149
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\ProcessPaymentTrait' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-processpaymenttrait.php',
150
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\TransactionUrlProvider' => $baseDir . '/modules/ppcp-wc-gateway/src/Gateway/class-transactionurlprovider.php',
151
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\AuthorizeOrderActionNotice' => $baseDir . '/modules/ppcp-wc-gateway/src/Notice/class-authorizeorderactionnotice.php',
152
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\ConnectAdminNotice' => $baseDir . '/modules/ppcp-wc-gateway/src/Notice/class-connectadminnotice.php',
153
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\DccWithoutPayPalAdminNotice' => $baseDir . '/modules/ppcp-wc-gateway/src/Notice/class-dccwithoutpaypaladminnotice.php',
154
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\AuthorizedPaymentsProcessor' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-authorizedpaymentsprocessor.php',
155
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderMetaTrait' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-ordermetatrait.php',
156
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderProcessor' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-orderprocessor.php',
157
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\PaymentsStatusHandlingTrait' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-paymentstatushandlingtrait.php',
158
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\RefundProcessor' => $baseDir . '/modules/ppcp-wc-gateway/src/Processor/class-refundprocessor.php',
159
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\PageMatcherTrait' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-pagematchertrait.php',
160
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SectionsRenderer' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-sectionsrenderer.php',
161
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\Settings' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-settings.php',
162
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsListener' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-settingslistener.php',
163
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsRenderer' => $baseDir . '/modules/ppcp-wc-gateway/src/Settings/class-settingsrenderer.php',
164
- 'WooCommerce\\PayPalCommerce\\WcGateway\\WcGatewayModule' => $baseDir . '/modules/ppcp-wc-gateway/src/class-wcgatewaymodule.php',
165
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\ResubscribeEndpoint' => $baseDir . '/modules/ppcp-webhooks/src/Endpoint/class-resubscribeendpoint.php',
166
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\SimulateEndpoint' => $baseDir . '/modules/ppcp-webhooks/src/Endpoint/class-simulateendpoint.php',
167
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\SimulationStateEndpoint' => $baseDir . '/modules/ppcp-webhooks/src/Endpoint/class-simulationstateendpoint.php',
168
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderApproved' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-checkoutorderapproved.php',
169
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderCompleted' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-checkoutordercompleted.php',
170
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureCompleted' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php',
171
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureRefunded' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturerefunded.php',
172
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureReversed' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturereversed.php',
173
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PrefixTrait' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-prefixtrait.php',
174
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\RequestHandler' => $baseDir . '/modules/ppcp-webhooks/src/Handler/class-requesthandler.php',
175
- 'WooCommerce\\PayPalCommerce\\Webhooks\\IncomingWebhookEndpoint' => $baseDir . '/modules/ppcp-webhooks/src/class-incomingwebhookendpoint.php',
176
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Status\\WebhookSimulation' => $baseDir . '/modules/ppcp-webhooks/src/Status/class-webhooksimulation.php',
177
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Status\\WebhooksStatusPage' => $baseDir . '/modules/ppcp-webhooks/src/Status/class-webhooksstatuspage.php',
178
- 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookModule' => $baseDir . '/modules/ppcp-webhooks/src/class-webhookmodule.php',
179
- 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookRegistrar' => $baseDir . '/modules/ppcp-webhooks/src/class-webhookregistrar.php',
180
- 'WooCommerce\\WooCommerce\\Logging\\Logger\\NullLogger' => $baseDir . '/modules/woocommerce-logging/src/Logger/class-nulllogger.php',
181
- 'WooCommerce\\WooCommerce\\Logging\\Logger\\WooCommerceLogger' => $baseDir . '/modules/woocommerce-logging/src/Logger/class-woocommercelogger.php',
182
- 'WooCommerce\\WooCommerce\\Logging\\WooCommerceLoggingModule' => $baseDir . '/modules/woocommerce-logging/src/class-woocommerceloggingmodule.php',
183
- 'Woocommerce\\PayPalCommerce\\ApiClient\\Entity\\Capture' => $baseDir . '/modules/ppcp-api-client/src/Entity/class-capture.php',
184
- 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\DccProductStatus' => $baseDir . '/modules/ppcp-wc-gateway/src/Helper/class-dccproductstatus.php',
185
- 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\SettingsStatus' => $baseDir . '/modules/ppcp-wc-gateway/src/Helper/class-settingsstatus.php',
186
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  );
vendor/composer/autoload_psr4.php CHANGED
@@ -6,15 +6,24 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
10
  'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
11
  'Interop\\Container\\' => array($vendorDir . '/container-interop/service-provider/src'),
12
- 'Dhii\\Wp\\Containers\\' => array($vendorDir . '/dhii/wp-containers/src'),
13
- 'Dhii\\Util\\String\\' => array($vendorDir . '/dhii/stringable-interface/src'),
14
  'Dhii\\Modular\\Module\\' => array($vendorDir . '/dhii/module-interface/src'),
15
- 'Dhii\\Factory\\' => array($vendorDir . '/dhii/factory-interface/src'),
16
- 'Dhii\\Exception\\' => array($vendorDir . '/dhii/exception-interface/src'),
17
- 'Dhii\\Data\\Container\\' => array($vendorDir . '/dhii/data-container-interface/src'),
18
  'Dhii\\Container\\' => array($vendorDir . '/dhii/containers/src'),
19
  'Dhii\\Collection\\' => array($vendorDir . '/dhii/collections-interface/src'),
20
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'WooCommerce\\WooCommerce\\Logging\\' => array($baseDir . '/modules/woocommerce-logging/src'),
10
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\' => array($baseDir . '/modules/ppcp-webhooks/src'),
11
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\' => array($baseDir . '/modules/ppcp-wc-gateway/src'),
12
+ 'WooCommerce\\PayPalCommerce\\Vaulting\\' => array($baseDir . '/modules/ppcp-vaulting/src'),
13
+ 'WooCommerce\\PayPalCommerce\\Subscription\\' => array($baseDir . '/modules/ppcp-subscription/src'),
14
+ 'WooCommerce\\PayPalCommerce\\StatusReport\\' => array($baseDir . '/modules/ppcp-status-report/src'),
15
+ 'WooCommerce\\PayPalCommerce\\Session\\' => array($baseDir . '/modules/ppcp-session/src'),
16
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\' => array($baseDir . '/modules/ppcp-onboarding/src'),
17
+ 'WooCommerce\\PayPalCommerce\\Compat\\' => array($baseDir . '/modules/ppcp-compat/src'),
18
+ 'WooCommerce\\PayPalCommerce\\Button\\' => array($baseDir . '/modules/ppcp-button/src'),
19
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\' => array($baseDir . '/modules/ppcp-api-client/src'),
20
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\' => array($baseDir . '/modules/ppcp-admin-notices/src'),
21
+ 'WooCommerce\\PayPalCommerce\\' => array($baseDir . '/src'),
22
+ 'Wikimedia\\Composer\\' => array($vendorDir . '/wikimedia/composer-merge-plugin/src'),
23
  'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
24
  'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
25
  'Interop\\Container\\' => array($vendorDir . '/container-interop/service-provider/src'),
 
 
26
  'Dhii\\Modular\\Module\\' => array($vendorDir . '/dhii/module-interface/src'),
 
 
 
27
  'Dhii\\Container\\' => array($vendorDir . '/dhii/containers/src'),
28
  'Dhii\\Collection\\' => array($vendorDir . '/dhii/collections-interface/src'),
29
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b
6
  {
7
  private static $loader;
8
 
@@ -22,17 +22,15 @@ class ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b
22
  return self::$loader;
23
  }
24
 
25
- require __DIR__ . '/platform_check.php';
26
-
27
- spl_autoload_register(array('ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b', 'loadClassLoader'), true, true);
28
- self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
29
- spl_autoload_unregister(array('ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b', 'loadClassLoader'));
30
 
31
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
32
  if ($useStaticLoader) {
33
- require __DIR__ . '/autoload_static.php';
34
 
35
- call_user_func(\Composer\Autoload\ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::getInitializer($loader));
36
  } else {
37
  $map = require __DIR__ . '/autoload_namespaces.php';
38
  foreach ($map as $namespace => $path) {
@@ -53,19 +51,19 @@ class ComposerAutoloaderInit4607be6ea28f9ff73f3cf09747918e4b
53
  $loader->register(true);
54
 
55
  if ($useStaticLoader) {
56
- $includeFiles = Composer\Autoload\ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::$files;
57
  } else {
58
  $includeFiles = require __DIR__ . '/autoload_files.php';
59
  }
60
  foreach ($includeFiles as $fileIdentifier => $file) {
61
- composerRequire4607be6ea28f9ff73f3cf09747918e4b($fileIdentifier, $file);
62
  }
63
 
64
  return $loader;
65
  }
66
  }
67
 
68
- function composerRequire4607be6ea28f9ff73f3cf09747918e4b($fileIdentifier, $file)
69
  {
70
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
71
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c', 'loadClassLoader'), true, true);
26
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit3acb3642cf46c3f8b0d913579e285e9c', '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\ComposerStaticInit3acb3642cf46c3f8b0d913579e285e9c::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\ComposerStaticInit3acb3642cf46c3f8b0d913579e285e9c::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequire3acb3642cf46c3f8b0d913579e285e9c($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
+ function composerRequire3acb3642cf46c3f8b0d913579e285e9c($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,13 +4,30 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b
8
  {
9
  public static $files = array (
10
  '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
11
  );
12
 
13
  public static $prefixLengthsPsr4 = array (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  'P' =>
15
  array (
16
  'Psr\\Log\\' => 8,
@@ -22,53 +39,84 @@ class ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b
22
  ),
23
  'D' =>
24
  array (
25
- 'Dhii\\Wp\\Containers\\' => 19,
26
- 'Dhii\\Util\\String\\' => 17,
27
  'Dhii\\Modular\\Module\\' => 20,
28
- 'Dhii\\Factory\\' => 13,
29
- 'Dhii\\Exception\\' => 15,
30
- 'Dhii\\Data\\Container\\' => 20,
31
  'Dhii\\Container\\' => 15,
32
  'Dhii\\Collection\\' => 16,
33
  ),
34
  );
35
 
36
  public static $prefixDirsPsr4 = array (
37
- 'Psr\\Log\\' =>
38
  array (
39
- 0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
40
  ),
41
- 'Psr\\Container\\' =>
42
  array (
43
- 0 => __DIR__ . '/..' . '/psr/container/src',
44
  ),
45
- 'Interop\\Container\\' =>
46
  array (
47
- 0 => __DIR__ . '/..' . '/container-interop/service-provider/src',
48
  ),
49
- 'Dhii\\Wp\\Containers\\' =>
50
  array (
51
- 0 => __DIR__ . '/..' . '/dhii/wp-containers/src',
52
  ),
53
- 'Dhii\\Util\\String\\' =>
54
  array (
55
- 0 => __DIR__ . '/..' . '/dhii/stringable-interface/src',
56
  ),
57
- 'Dhii\\Modular\\Module\\' =>
58
  array (
59
- 0 => __DIR__ . '/..' . '/dhii/module-interface/src',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  ),
61
- 'Dhii\\Factory\\' =>
62
  array (
63
- 0 => __DIR__ . '/..' . '/dhii/factory-interface/src',
64
  ),
65
- 'Dhii\\Exception\\' =>
66
  array (
67
- 0 => __DIR__ . '/..' . '/dhii/exception-interface/src',
68
  ),
69
- 'Dhii\\Data\\Container\\' =>
70
  array (
71
- 0 => __DIR__ . '/..' . '/dhii/data-container-interface/src',
 
 
 
 
 
 
 
 
72
  ),
73
  'Dhii\\Container\\' =>
74
  array (
@@ -80,192 +128,11 @@ class ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b
80
  ),
81
  );
82
 
83
- public static $classMap = array (
84
- 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
85
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\AdminNotices' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/class-adminnotices.php',
86
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Entity\\Message' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Entity/class-message.php',
87
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\Renderer' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Renderer/class-renderer.php',
88
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Renderer\\RendererInterface' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Renderer/class-rendererinterface.php',
89
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\Repository' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Repository/class-repository.php',
90
- 'WooCommerce\\PayPalCommerce\\AdminNotices\\Repository\\RepositoryInterface' => __DIR__ . '/../..' . '/modules/ppcp-admin-notices/src/Repository/class-repositoryinterface.php',
91
- 'WooCommerce\\PayPalCommerce\\ApiClient\\ApiModule' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/class-apimodule.php',
92
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\Bearer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Authentication/class-bearer.php',
93
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\ConnectBearer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Authentication/class-connectbearer.php',
94
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Authentication\\PayPalBearer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Authentication/class-paypalbearer.php',
95
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\IdentityToken' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-identitytoken.php',
96
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\LoginSeller' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-loginseller.php',
97
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\OrderEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-orderendpoint.php',
98
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnerReferrals' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-partnerreferrals.php',
99
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PartnersEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-partnersendpoint.php',
100
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentTokenEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-paymenttokenendpoint.php',
101
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\PaymentsEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-paymentsendpoint.php',
102
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\RequestTrait' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-requesttrait.php',
103
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Endpoint\\WebhookEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Endpoint/class-webhookendpoint.php',
104
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Address' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-address.php',
105
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Amount' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-amount.php',
106
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AmountBreakdown' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-amountbreakdown.php',
107
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\ApplicationContext' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-applicationcontext.php',
108
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Authorization' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-authorization.php',
109
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-authorizationstatus.php',
110
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\AuthorizationStatusDetails' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-authorizationstatusdetails.php',
111
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CaptureStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-capturestatus.php',
112
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CaptureStatusDetails' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-capturestatusdetails.php',
113
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\CardAuthenticationResult' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-cardauthenticationresult.php',
114
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Item' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-item.php',
115
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Money' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-money.php',
116
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Order' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-order.php',
117
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\OrderStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-orderstatus.php',
118
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Patch' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-patch.php',
119
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PatchCollection' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-patchcollection.php',
120
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payee' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payee.php',
121
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payer' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payer.php',
122
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerName' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payername.php',
123
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PayerTaxInfo' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payertaxinfo.php',
124
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentMethod' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentmethod.php',
125
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSource' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentsource.php',
126
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceCard' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentsourcecard.php',
127
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentSourceWallet' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymentsourcewallet.php',
128
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PaymentToken' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-paymenttoken.php',
129
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Payments' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-payments.php',
130
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Phone' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-phone.php',
131
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PhoneWithType' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-phonewithtype.php',
132
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\PurchaseUnit' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-purchaseunit.php',
133
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Refund' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-refund.php',
134
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatus' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-sellerstatus.php',
135
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\SellerStatusProduct' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-sellerstatusproduct.php',
136
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Shipping' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-shipping.php',
137
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Token' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-token.php',
138
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\Webhook' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-webhook.php',
139
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Entity\\WebhookEvent' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-webhookevent.php',
140
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\NotFoundException' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Exception/class-notfoundexception.php',
141
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\PayPalApiException' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Exception/class-paypalapiexception.php',
142
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Exception\\RuntimeException' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Exception/class-runtimeexception.php',
143
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AddressFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-addressfactory.php',
144
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AmountFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-amountfactory.php',
145
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ApplicationContextFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-applicationcontextfactory.php',
146
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\AuthorizationFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-authorizationfactory.php',
147
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\CaptureFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-capturefactory.php',
148
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ItemFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-itemfactory.php',
149
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\OrderFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-orderfactory.php',
150
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PatchCollectionFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-patchcollectionfactory.php',
151
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayeeFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-payeefactory.php',
152
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PayerFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-payerfactory.php',
153
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentSourceFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-paymentsourcefactory.php',
154
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentTokenFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-paymenttokenfactory.php',
155
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PaymentsFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-paymentsfactory.php',
156
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\PurchaseUnitFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-purchaseunitfactory.php',
157
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\SellerStatusFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-sellerstatusfactory.php',
158
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\ShippingFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-shippingfactory.php',
159
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookEventFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-webhookeventfactory.php',
160
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Factory\\WebhookFactory' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Factory/class-webhookfactory.php',
161
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\Cache' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Helper/class-cache.php',
162
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\DccApplies' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Helper/class-dccapplies.php',
163
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Helper\\ErrorResponse' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Helper/class-errorresponse.php',
164
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\ApplicationContextRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-applicationcontextrepository.php',
165
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\CartRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-cartrepository.php',
166
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PartnerReferralsData' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-partnerreferralsdata.php',
167
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayPalRequestIdRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-paypalrequestidrepository.php',
168
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PayeeRepository' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-payeerepository.php',
169
- 'WooCommerce\\PayPalCommerce\\ApiClient\\Repository\\PurchaseUnitRepositoryInterface' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Repository/class-purchaseunitrepositoryinterface.php',
170
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\DisabledSmartButton' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Assets/class-disabledsmartbutton.php',
171
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButton' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Assets/class-smartbutton.php',
172
- 'WooCommerce\\PayPalCommerce\\Button\\Assets\\SmartButtonInterface' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Assets/class-smartbuttoninterface.php',
173
- 'WooCommerce\\PayPalCommerce\\Button\\ButtonModule' => __DIR__ . '/../..' . '/modules/ppcp-button/src/class-buttonmodule.php',
174
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ApproveOrderEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-approveorderendpoint.php',
175
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\ChangeCartEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-changecartendpoint.php',
176
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\CreateOrderEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-createorderendpoint.php',
177
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\DataClientIdEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-dataclientidendpoint.php',
178
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\EndpointInterface' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-endpointinterface.php',
179
- 'WooCommerce\\PayPalCommerce\\Button\\Endpoint\\RequestData' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Endpoint/class-requestdata.php',
180
- 'WooCommerce\\PayPalCommerce\\Button\\Exception\\RuntimeException' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Exception/class-runtimeexception.php',
181
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\EarlyOrderHandler' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-earlyorderhandler.php',
182
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesApply' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-messagesapply.php',
183
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\MessagesDisclaimers' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-messagesdisclaimers.php',
184
- 'WooCommerce\\PayPalCommerce\\Button\\Helper\\ThreeDSecure' => __DIR__ . '/../..' . '/modules/ppcp-button/src/Helper/class-threedsecure.php',
185
- 'WooCommerce\\PayPalCommerce\\Compat\\CompatModule' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/class-compatmodule.php',
186
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\DeactivateNote' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-deactivatenote.php',
187
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\MockGateway' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-mockgateway.php',
188
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\PPECHelper' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-ppechelper.php',
189
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\SettingsImporter' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-settingsimporter.php',
190
- 'WooCommerce\\PayPalCommerce\\Compat\\PPEC\\SubscriptionsHandler' => __DIR__ . '/../..' . '/modules/ppcp-compat/src/PPEC/class-subscriptionshandler.php',
191
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Assets\\OnboardingAssets' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/Assets/class-onboardingassets.php',
192
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Endpoint\\LoginSellerEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/Endpoint/class-loginsellerendpoint.php',
193
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Environment' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-environment.php',
194
- 'WooCommerce\\PayPalCommerce\\Onboarding\\OnboardingModule' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-onboardingmodule.php',
195
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Onboarding_REST_Controller' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-onboarding-rest-controller.php',
196
- 'WooCommerce\\PayPalCommerce\\Onboarding\\Render\\OnboardingRenderer' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/Render/class-onboardingrenderer.php',
197
- 'WooCommerce\\PayPalCommerce\\Onboarding\\State' => __DIR__ . '/../..' . '/modules/ppcp-onboarding/src/class-state.php',
198
- 'WooCommerce\\PayPalCommerce\\PluginModule' => __DIR__ . '/../..' . '/src/class-pluginmodule.php',
199
- 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelController' => __DIR__ . '/../..' . '/modules/ppcp-session/src/Cancellation/class-cancelcontroller.php',
200
- 'WooCommerce\\PayPalCommerce\\Session\\Cancellation\\CancelView' => __DIR__ . '/../..' . '/modules/ppcp-session/src/Cancellation/class-cancelview.php',
201
- 'WooCommerce\\PayPalCommerce\\Session\\SessionHandler' => __DIR__ . '/../..' . '/modules/ppcp-session/src/class-sessionhandler.php',
202
- 'WooCommerce\\PayPalCommerce\\Session\\SessionModule' => __DIR__ . '/../..' . '/modules/ppcp-session/src/class-sessionmodule.php',
203
- 'WooCommerce\\PayPalCommerce\\StatusReport\\Renderer' => __DIR__ . '/../..' . '/modules/ppcp-status-report/src/class-renderer.php',
204
- 'WooCommerce\\PayPalCommerce\\StatusReport\\StatusReportModule' => __DIR__ . '/../..' . '/modules/ppcp-status-report/src/class-statusreportmodule.php',
205
- 'WooCommerce\\PayPalCommerce\\Subscription\\Helper\\SubscriptionHelper' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/Helper/class-subscriptionhelper.php',
206
- 'WooCommerce\\PayPalCommerce\\Subscription\\RenewalHandler' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/class-renewalhandler.php',
207
- 'WooCommerce\\PayPalCommerce\\Subscription\\SubscriptionModule' => __DIR__ . '/../..' . '/modules/ppcp-subscription/src/class-subscriptionmodule.php',
208
- 'WooCommerce\\PayPalCommerce\\Vaulting\\Assets\\MyAccountPaymentsAssets' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/Assets/class-myaccountpaymentsassets.php',
209
- 'WooCommerce\\PayPalCommerce\\Vaulting\\Endpoint\\DeletePaymentTokenEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/Endpoint/class-deletepaymenttokenendpoint.php',
210
- 'WooCommerce\\PayPalCommerce\\Vaulting\\PaymentTokenRepository' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/class-paymenttokenrepository.php',
211
- 'WooCommerce\\PayPalCommerce\\Vaulting\\PaymentTokensRenderer' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/class-paymenttokensrenderer.php',
212
- 'WooCommerce\\PayPalCommerce\\Vaulting\\VaultingModule' => __DIR__ . '/../..' . '/modules/ppcp-vaulting/src/class-vaultingmodule.php',
213
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\OrderTablePaymentStatusColumn' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Admin/class-ordertablepaymentstatuscolumn.php',
214
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\PaymentStatusOrderDetail' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Admin/class-paymentstatusorderdetail.php',
215
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Admin\\RenderAuthorizeAction' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Admin/class-renderauthorizeaction.php',
216
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Assets\\SettingsPageAssets' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Assets/class-settingspageassets.php',
217
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Assets\\WebhooksStatusPageAssets' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Status/Assets/class-webhooksstatuspageassets.php',
218
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\CheckoutPayPalAddressPreset' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Checkout/class-checkoutpaypaladdresspreset.php',
219
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Checkout\\DisableGateways' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Checkout/class-disablegateways.php',
220
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Endpoint\\ReturnUrlEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Endpoint/class-returnurlendpoint.php',
221
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Exception\\NotFoundException' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Exception/class-notfoundexception.php',
222
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\CreditCardGateway' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-creditcardgateway.php',
223
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\PayPalGateway' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-paypalgateway.php',
224
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\ProcessPaymentTrait' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-processpaymenttrait.php',
225
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Gateway\\TransactionUrlProvider' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Gateway/class-transactionurlprovider.php',
226
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\AuthorizeOrderActionNotice' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Notice/class-authorizeorderactionnotice.php',
227
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\ConnectAdminNotice' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Notice/class-connectadminnotice.php',
228
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Notice\\DccWithoutPayPalAdminNotice' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Notice/class-dccwithoutpaypaladminnotice.php',
229
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\AuthorizedPaymentsProcessor' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-authorizedpaymentsprocessor.php',
230
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderMetaTrait' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-ordermetatrait.php',
231
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\OrderProcessor' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-orderprocessor.php',
232
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\PaymentsStatusHandlingTrait' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-paymentstatushandlingtrait.php',
233
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Processor\\RefundProcessor' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Processor/class-refundprocessor.php',
234
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\PageMatcherTrait' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-pagematchertrait.php',
235
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SectionsRenderer' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-sectionsrenderer.php',
236
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\Settings' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-settings.php',
237
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsListener' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-settingslistener.php',
238
- 'WooCommerce\\PayPalCommerce\\WcGateway\\Settings\\SettingsRenderer' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Settings/class-settingsrenderer.php',
239
- 'WooCommerce\\PayPalCommerce\\WcGateway\\WcGatewayModule' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/class-wcgatewaymodule.php',
240
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\ResubscribeEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Endpoint/class-resubscribeendpoint.php',
241
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\SimulateEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Endpoint/class-simulateendpoint.php',
242
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Endpoint\\SimulationStateEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Endpoint/class-simulationstateendpoint.php',
243
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderApproved' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-checkoutorderapproved.php',
244
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\CheckoutOrderCompleted' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-checkoutordercompleted.php',
245
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureCompleted' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturecompleted.php',
246
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureRefunded' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturerefunded.php',
247
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PaymentCaptureReversed' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-paymentcapturereversed.php',
248
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\PrefixTrait' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-prefixtrait.php',
249
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Handler\\RequestHandler' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Handler/class-requesthandler.php',
250
- 'WooCommerce\\PayPalCommerce\\Webhooks\\IncomingWebhookEndpoint' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/class-incomingwebhookendpoint.php',
251
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Status\\WebhookSimulation' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Status/class-webhooksimulation.php',
252
- 'WooCommerce\\PayPalCommerce\\Webhooks\\Status\\WebhooksStatusPage' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/Status/class-webhooksstatuspage.php',
253
- 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookModule' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/class-webhookmodule.php',
254
- 'WooCommerce\\PayPalCommerce\\Webhooks\\WebhookRegistrar' => __DIR__ . '/../..' . '/modules/ppcp-webhooks/src/class-webhookregistrar.php',
255
- 'WooCommerce\\WooCommerce\\Logging\\Logger\\NullLogger' => __DIR__ . '/../..' . '/modules/woocommerce-logging/src/Logger/class-nulllogger.php',
256
- 'WooCommerce\\WooCommerce\\Logging\\Logger\\WooCommerceLogger' => __DIR__ . '/../..' . '/modules/woocommerce-logging/src/Logger/class-woocommercelogger.php',
257
- 'WooCommerce\\WooCommerce\\Logging\\WooCommerceLoggingModule' => __DIR__ . '/../..' . '/modules/woocommerce-logging/src/class-woocommerceloggingmodule.php',
258
- 'Woocommerce\\PayPalCommerce\\ApiClient\\Entity\\Capture' => __DIR__ . '/../..' . '/modules/ppcp-api-client/src/Entity/class-capture.php',
259
- 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\DccProductStatus' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Helper/class-dccproductstatus.php',
260
- 'Woocommerce\\PayPalCommerce\\WcGateway\\Helper\\SettingsStatus' => __DIR__ . '/../..' . '/modules/ppcp-wc-gateway/src/Helper/class-settingsstatus.php',
261
- );
262
-
263
  public static function getInitializer(ClassLoader $loader)
264
  {
265
  return \Closure::bind(function () use ($loader) {
266
- $loader->prefixLengthsPsr4 = ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::$prefixLengthsPsr4;
267
- $loader->prefixDirsPsr4 = ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::$prefixDirsPsr4;
268
- $loader->classMap = ComposerStaticInit4607be6ea28f9ff73f3cf09747918e4b::$classMap;
269
 
270
  }, null, ClassLoader::class);
271
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit3acb3642cf46c3f8b0d913579e285e9c
8
  {
9
  public static $files = array (
10
  '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
11
  );
12
 
13
  public static $prefixLengthsPsr4 = array (
14
+ 'W' =>
15
+ array (
16
+ 'WooCommerce\\WooCommerce\\Logging\\' => 32,
17
+ 'WooCommerce\\PayPalCommerce\\Webhooks\\' => 36,
18
+ 'WooCommerce\\PayPalCommerce\\WcGateway\\' => 37,
19
+ 'WooCommerce\\PayPalCommerce\\Vaulting\\' => 36,
20
+ 'WooCommerce\\PayPalCommerce\\Subscription\\' => 40,
21
+ 'WooCommerce\\PayPalCommerce\\StatusReport\\' => 40,
22
+ 'WooCommerce\\PayPalCommerce\\Session\\' => 35,
23
+ 'WooCommerce\\PayPalCommerce\\Onboarding\\' => 38,
24
+ 'WooCommerce\\PayPalCommerce\\Compat\\' => 34,
25
+ 'WooCommerce\\PayPalCommerce\\Button\\' => 34,
26
+ 'WooCommerce\\PayPalCommerce\\ApiClient\\' => 37,
27
+ 'WooCommerce\\PayPalCommerce\\AdminNotices\\' => 40,
28
+ 'WooCommerce\\PayPalCommerce\\' => 27,
29
+ 'Wikimedia\\Composer\\' => 19,
30
+ ),
31
  'P' =>
32
  array (
33
  'Psr\\Log\\' => 8,
39
  ),
40
  'D' =>
41
  array (
 
 
42
  'Dhii\\Modular\\Module\\' => 20,