Changeset 3262577
- Timestamp:
- 03/27/2025 07:46:57 AM (12 months ago)
- Location:
- mollie-payments-for-woocommerce/trunk
- Files:
-
- 98 added
- 13 deleted
- 66 edited
-
inc/modules.php (added)
-
inc/settings (deleted)
-
inc/utils.php (modified) (1 diff)
-
lib (added)
-
lib/payment-gateway (added)
-
lib/payment-gateway/index.php (added)
-
lib/payment-gateway/src (added)
-
lib/payment-gateway/src/DefaultIconsRenderer.php (added)
-
lib/payment-gateway/src/Fields (added)
-
lib/payment-gateway/src/Fields/ContentField.php (added)
-
lib/payment-gateway/src/GatewayIconsRendererInterface.php (added)
-
lib/payment-gateway/src/I18n.php (added)
-
lib/payment-gateway/src/Icon.php (added)
-
lib/payment-gateway/src/IconProviderInterface.php (added)
-
lib/payment-gateway/src/Method (added)
-
lib/payment-gateway/src/Method/CustomSettingsFields.php (added)
-
lib/payment-gateway/src/Method/CustomSettingsFieldsDefinition.php (added)
-
lib/payment-gateway/src/Method/DefaultPaymentMethodDefinitionTrait.php (added)
-
lib/payment-gateway/src/Method/PaymentMethodDefinition.php (added)
-
lib/payment-gateway/src/NoopPaymentProcessor.php (added)
-
lib/payment-gateway/src/NoopPaymentRequestValidator.php (added)
-
lib/payment-gateway/src/NoopRefundProcessor.php (added)
-
lib/payment-gateway/src/PaymentFieldsRendererInterface.php (added)
-
lib/payment-gateway/src/PaymentGateway.php (added)
-
lib/payment-gateway/src/PaymentGatewayBlocks.php (added)
-
lib/payment-gateway/src/PaymentGatewayModule.php (added)
-
lib/payment-gateway/src/PaymentGatewayValidator.php (added)
-
lib/payment-gateway/src/PaymentMethodServiceProviderTrait.php (added)
-
lib/payment-gateway/src/PaymentProcessorInterface.php (added)
-
lib/payment-gateway/src/PaymentRequestValidatorInterface.php (added)
-
lib/payment-gateway/src/RefundProcessorInterface.php (added)
-
lib/payment-gateway/src/ServiceKeyGenerator.php (added)
-
lib/payment-gateway/src/SettingsFieldRendererInterface.php (added)
-
lib/payment-gateway/src/SettingsFieldSanitizerInterface.php (added)
-
lib/payment-gateway/src/StaticIconProvider.php (added)
-
mollie-payments-for-woocommerce.php (modified) (3 diffs)
-
public/js/mollieBlockIndex.min.js (modified) (12 diffs)
-
readme.txt (modified) (5 diffs)
-
src/Activation/ActivationModule.php (modified) (2 diffs)
-
src/Assets/AssetsModule.php (modified) (7 diffs)
-
src/Assets/MollieCheckoutBlocksSupport.php (modified) (8 diffs)
-
src/BlockService/CheckoutBlockService.php (modified) (1 diff)
-
src/Buttons/ApplePayButton/ResponsesToApple.php (modified) (2 diffs)
-
src/Buttons/PayPalButton/PayPalAjaxRequests.php (modified) (2 diffs)
-
src/Gateway/DeprecatedGatewayBuilder.php (added)
-
src/Gateway/GatewayModule.php (modified) (9 diffs)
-
src/Gateway/MolliePaymentGateway.php (deleted)
-
src/Gateway/MolliePaymentGatewayHandler.php (added)
-
src/Gateway/MolliePaymentGatewayI.php (deleted)
-
src/Gateway/OrderMandatoryGatewayDisabler.php (modified) (3 diffs)
-
src/Gateway/Refund (added)
-
src/Gateway/Refund/OrderItemsRefunder.php (added)
-
src/Gateway/Refund/OrderLineStatus.php (added)
-
src/Gateway/Refund/PartialRefundException.php (added)
-
src/Gateway/Refund/RefundLineItemsBuilder.php (added)
-
src/Gateway/Refund/RefundProcessor.php (added)
-
src/Gateway/Voucher/MaybeDisableGateway.php (modified) (4 diffs)
-
src/Gateway/Voucher/VoucherModule.php (modified) (1 diff)
-
src/Gateway/inc (added)
-
src/Gateway/inc/extensions.php (added)
-
src/Gateway/inc/services.php (added)
-
src/Payment/MollieObject.php (modified) (9 diffs)
-
src/Payment/MollieOrder.php (modified) (10 diffs)
-
src/Payment/MollieOrderService.php (modified) (9 diffs)
-
src/Payment/MolliePayment.php (modified) (8 diffs)
-
src/Payment/MollieSubscription.php (modified) (7 diffs)
-
src/Payment/OrderInstructionsService.php (deleted)
-
src/Payment/OrderItemsRefunder.php (deleted)
-
src/Payment/OrderLineStatus.php (deleted)
-
src/Payment/OrderLines.php (modified) (1 diff)
-
src/Payment/PartialRefundException.php (deleted)
-
src/Payment/PaymentCheckoutRedirectService.php (modified) (1 diff)
-
src/Payment/PaymentFactory.php (modified) (2 diffs)
-
src/Payment/PaymentFieldsService.php (deleted)
-
src/Payment/PaymentLines.php (added)
-
src/Payment/PaymentModule.php (modified) (12 diffs)
-
src/Payment/PaymentProcessor.php (added)
-
src/Payment/PaymentService.php (deleted)
-
src/Payment/RefundLineItemsBuilder.php (deleted)
-
src/Payment/Request (added)
-
src/Payment/Request/Middleware (added)
-
src/Payment/Request/Middleware/AddCustomRequestFieldsMiddleware.php (added)
-
src/Payment/Request/Middleware/AddSequenceTypeForSubscriptionsMiddleware.php (added)
-
src/Payment/Request/Middleware/AddressMiddleware.php (added)
-
src/Payment/Request/Middleware/ApplePayTokenMiddleware.php (added)
-
src/Payment/Request/Middleware/CaptureModeMiddleware.php (added)
-
src/Payment/Request/Middleware/CardTokenMiddleware.php (added)
-
src/Payment/Request/Middleware/CustomerBirthdateMiddleware.php (added)
-
src/Payment/Request/Middleware/MiddlewareHandler.php (added)
-
src/Payment/Request/Middleware/OrderLinesMiddleware.php (added)
-
src/Payment/Request/Middleware/PaymentDescriptionMiddleware.php (added)
-
src/Payment/Request/Middleware/RequestMiddlewareInterface.php (added)
-
src/Payment/Request/Middleware/SelectedIssuerMiddleware.php (added)
-
src/Payment/Request/Middleware/StoreCustomerMiddleware.php (added)
-
src/Payment/Request/Middleware/UrlMiddleware.php (added)
-
src/Payment/Request/RequestFactory.php (added)
-
src/Payment/Request/Strategies (added)
-
src/Payment/Request/Strategies/OrderRequestStrategy.php (added)
-
src/Payment/Request/Strategies/PaymentRequestStrategy.php (added)
-
src/Payment/Request/Strategies/RequestStrategyInterface.php (added)
-
src/Payment/inc (added)
-
src/Payment/inc/services.php (added)
-
src/PaymentMethods/AbstractPaymentMethod.php (modified) (10 diffs)
-
src/PaymentMethods/Alma.php (modified) (1 diff)
-
src/PaymentMethods/Applepay.php (modified) (1 diff)
-
src/PaymentMethods/Billie.php (modified) (1 diff)
-
src/PaymentMethods/Icon (added)
-
src/PaymentMethods/Icon/GatewayIconsRenderer.php (added)
-
src/PaymentMethods/InstructionStrategies/OrderInstructionsManager.php (added)
-
src/PaymentMethods/Klarna.php (modified) (1 diff)
-
src/PaymentMethods/PaymentFieldsStrategies/AbstractPaymentFieldsRenderer.php (added)
-
src/PaymentMethods/PaymentFieldsStrategies/BancomatpayFieldsStrategy.php (modified) (3 diffs)
-
src/PaymentMethods/PaymentFieldsStrategies/BillieFieldsStrategy.php (modified) (3 diffs)
-
src/PaymentMethods/PaymentFieldsStrategies/CreditcardFieldsStrategy.php (modified) (2 diffs)
-
src/PaymentMethods/PaymentFieldsStrategies/DefaultFieldsStrategy.php (modified) (1 diff)
-
src/PaymentMethods/PaymentFieldsStrategies/GiftcardFieldsStrategy.php (modified) (3 diffs)
-
src/PaymentMethods/PaymentFieldsStrategies/In3FieldsStrategy.php (modified) (3 diffs)
-
src/PaymentMethods/PaymentFieldsStrategies/IssuersDropdownBehavior.php (modified) (1 diff)
-
src/PaymentMethods/PaymentFieldsStrategies/KbcFieldsStrategy.php (modified) (1 diff)
-
src/PaymentMethods/PaymentFieldsStrategies/NoopPaymentFieldsRenderer.php (added)
-
src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategiesTrait.php (modified) (1 diff)
-
src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategyI.php (modified) (1 diff)
-
src/PaymentMethods/PaymentFieldsStrategies/RivertyFieldsStrategy.php (modified) (4 diffs)
-
src/PaymentMethods/PaymentMethodI.php (modified) (1 diff)
-
src/PaymentMethods/PaymentMethodsIconUrl.php (modified) (1 diff)
-
src/PaymentMethods/Riverty.php (modified) (1 diff)
-
src/Settings/General/MollieGeneralSettings.php (modified) (2 diffs)
-
src/Settings/General/MultiCountrySettingsField.php (added)
-
src/Settings/MollieSettingsPage.php (modified) (4 diffs)
-
src/Settings/Page/AbstractPage.php (modified) (4 diffs)
-
src/Settings/Page/Section/AbstractSection.php (modified) (3 diffs)
-
src/Settings/Page/Section/Advanced.php (modified) (2 diffs)
-
src/Settings/Page/Section/Notices.php (modified) (2 diffs)
-
src/Settings/Page/Section/PaymentMethods.php (modified) (1 diff)
-
src/Settings/Settings.php (modified) (10 diffs)
-
src/Settings/SettingsModule.php (modified) (3 diffs)
-
src/Shared/Data.php (modified) (1 diff)
-
src/Subscription/MaybeFixSubscription.php (deleted)
-
src/Subscription/MollieSepaRecurringGateway.php (deleted)
-
src/Subscription/MollieSepaRecurringGatewayHandler.php (added)
-
src/Subscription/MollieSubscriptionGateway.php (deleted)
-
src/Subscription/MollieSubscriptionGatewayHandler.php (added)
-
src/Subscription/SubscriptionModule.php (modified) (2 diffs)
-
vendor/autoload.php (modified) (1 diff)
-
vendor/composer/autoload_classmap.php (modified) (10 diffs)
-
vendor/composer/autoload_psr4.php (modified) (1 diff)
-
vendor/composer/autoload_real.php (modified) (2 diffs)
-
vendor/composer/autoload_static.php (modified) (15 diffs)
-
vendor/composer/ca-bundle/res/cacert.pem (modified) (5 diffs)
-
vendor/composer/installed.json (modified) (7 diffs)
-
vendor/composer/installed.php (modified) (1 diff)
-
vendor/dhii (added)
-
vendor/dhii/services (added)
-
vendor/dhii/services/LICENSE (added)
-
vendor/dhii/services/docker (added)
-
vendor/dhii/services/docker-compose.yml (added)
-
vendor/dhii/services/docker/Dockerfile (added)
-
vendor/dhii/services/src (added)
-
vendor/dhii/services/src/Extension.php (added)
-
vendor/dhii/services/src/Extensions (added)
-
vendor/dhii/services/src/Extensions/ArrayExtension.php (added)
-
vendor/dhii/services/src/Factories (added)
-
vendor/dhii/services/src/Factories/Alias.php (added)
-
vendor/dhii/services/src/Factories/Constructor.php (added)
-
vendor/dhii/services/src/Factories/FuncService.php (added)
-
vendor/dhii/services/src/Factories/GlobalVar.php (added)
-
vendor/dhii/services/src/Factories/ServiceList.php (added)
-
vendor/dhii/services/src/Factories/StringService.php (added)
-
vendor/dhii/services/src/Factories/Value.php (added)
-
vendor/dhii/services/src/Factory.php (added)
-
vendor/dhii/services/src/ResolveKeysCapableTrait.php (added)
-
vendor/dhii/services/src/Service.php (added)
-
vendor/mollie/mollie-api-php/src/Endpoints/CustomerEndpoint.php (modified) (1 diff)
-
vendor/mollie/mollie-api-php/src/Endpoints/ProfileEndpoint.php (modified) (1 diff)
-
vendor/mollie/mollie-api-php/src/Endpoints/ShipmentEndpoint.php (modified) (1 diff)
-
vendor/mollie/mollie-api-php/src/Endpoints/SubscriptionEndpoint.php (modified) (1 diff)
-
vendor/mollie/mollie-api-php/src/MollieApiClient.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
mollie-payments-for-woocommerce/trunk/inc/utils.php
r3191126 r3262577 166 166 function mollieWooCommerceIsMollieGateway($gateway) 167 167 { 168 if (strpos($gateway, 'mollie_wc_gateway_') !== false) { 168 if ( 169 (is_string($gateway) && strpos($gateway, 'mollie_wc_gateway_') !== false) 170 || (is_object($gateway) && strpos($gateway->id, 'mollie_wc_gateway_') !== false) 171 ) { 169 172 return true; 170 173 } -
mollie-payments-for-woocommerce/trunk/mollie-payments-for-woocommerce.php
r3242448 r3262577 5 5 * Plugin URI: https://www.mollie.com 6 6 * Description: Accept payments in WooCommerce with the official Mollie plugin 7 * Version: 7.10.07 * Version: 8.0.0 8 8 * Author: Mollie 9 9 * Author URI: https://www.mollie.com … … 14 14 * License: GPLv2 or later 15 15 * WC requires at least: 3.9 16 * WC tested up to: 9. 516 * WC tested up to: 9.7 17 17 * Requires PHP: 7.4 18 18 * Requires Plugins: woocommerce … … 97 97 function initialize() 98 98 { 99 try { 100 require_once __DIR__ . '/inc/functions.php'; 101 if (!mollie_wc_plugin_autoload()) { 102 return; 99 static $package; 100 if (!$package) { 101 try { 102 require_once __DIR__ . '/inc/functions.php'; 103 if (!mollie_wc_plugin_autoload()) { 104 return; 105 } 106 $checker = new ConstraintsChecker(); 107 $meetRequirements = $checker->handleActivation(); 108 if (!$meetRequirements) { 109 $nextScheduledTime = wp_next_scheduled('pending_payment_confirmation_check'); 110 if ($nextScheduledTime) { 111 wp_unschedule_event($nextScheduledTime, 'pending_payment_confirmation_check'); 112 } 113 return; 114 } 115 // Initialize plugin. 116 $properties = PluginProperties::new(__FILE__); 117 $package = Package::new($properties); 118 $modules = (require __DIR__ . '/inc/modules.php')(); 119 $modules = apply_filters('mollie_wc_plugin_modules', $modules); 120 foreach ($modules as $module) { 121 $package->addModule($module); 122 } 123 $package->boot(); 124 } catch (Throwable $throwable) { 125 handleException($throwable); 103 126 } 104 $checker = new ConstraintsChecker();105 $meetRequirements = $checker->handleActivation();106 if (!$meetRequirements) {107 $nextScheduledTime = wp_next_scheduled('pending_payment_confirmation_check');108 if ($nextScheduledTime) {109 wp_unschedule_event($nextScheduledTime, 'pending_payment_confirmation_check');110 }111 return;112 }113 // Initialize plugin.114 $properties = PluginProperties::new(__FILE__);115 $bootstrap = Package::new($properties);116 $modules = [new ActivationModule(__FILE__, $properties->get('version')), new NoticeModule(), new SharedModule(), new SDKModule(), new SettingsModule(), new LogModule('mollie-payments-for-woocommerce-'), new AssetsModule(), new GatewayModule(), new VoucherModule(), new PaymentModule(), new MerchantCaptureModule(), new UninstallModule()];117 $modules = apply_filters('mollie_wc_plugin_modules', $modules);118 foreach ($modules as $module) {119 $bootstrap->addModule($module);120 }121 $bootstrap->boot();122 } catch (Throwable $throwable) {123 handleException($throwable);124 127 } 128 /** @var Package $package */ 129 return $package; 125 130 } 126 add_action('plugins_loaded', __NAMESPACE__ . '\initialize'); 131 add_action( 132 /** 133 * @throws Throwable 134 */ 135 'plugins_loaded', 136 static function () { 137 initialize(); 138 } 139 ); -
mollie-payments-for-woocommerce/trunk/public/js/mollieBlockIndex.min.js
r3242448 r3262577 338 338 return wcSettings.currency.priceFormat.replace('%1$s', wcSettings.currency.symbol).replace('%2$s', price.toFixed(wcSettings.currency.precision).replace('.', wcSettings.currency.decimalSeparator)); 339 339 } 340 function loadCachedAvailableGateways() {341 var storedData = localStorage.getItem('cachedAvailableGateways');342 if (storedData) {343 try {344 cachedAvailableGateways = JSON.parse(storedData);345 } catch (e) {346 console.warn('Error parsing cachedAvailableGateways from localStorage:', e);347 cachedAvailableGateways = {};348 }349 }350 }351 function saveCachedAvailableGateways() {352 localStorage.setItem('cachedAvailableGateways', JSON.stringify(cachedAvailableGateways));353 }354 loadCachedAvailableGateways();355 340 function setAvailableGateways(country, currencyCode, data) { 356 341 cachedAvailableGateways = _objectSpread(_objectSpread({}, cachedAvailableGateways), data); 357 saveCachedAvailableGateways();358 342 } 359 function useMollieAvailableGateways(billing, currencyCode, cartTotal, filters, ajaxUrl , jQuery, item) {343 function useMollieAvailableGateways(billing, currencyCode, cartTotal, filters, ajaxUrl) { 360 344 var country = billing.country; 361 345 var code = currencyCode; … … 366 350 } 367 351 wp.element.useEffect(function () { 368 if (!country || !item) return;352 if (!country) return; 369 353 var currencyCode = code; 370 354 var cartTotal = value; … … 373 357 return; 374 358 } 375 jQuery.ajax({ 376 url: ajaxUrl, 359 fetch(ajaxUrl, { 377 360 method: 'POST', 378 data: { 361 headers: { 362 "Content-Type": "application/x-www-form-urlencoded" 363 }, 364 body: new URLSearchParams({ 379 365 action: 'mollie_checkout_blocks_canmakepayment', 380 currentGateway: item,381 366 currency: currencyCode, 382 367 billingCountry: country, 383 368 cartTotal: cartTotal, 384 369 paymentLocale: filters.paymentLocale 385 }, 386 success: function success(response) { 387 setAvailableGateways(country, currencyCode, response.data); 388 var cartTotals = wp.data.select('wc/store/cart').getCartTotals(); 389 // Dispatch them again to trigger a re-render: 390 wp.data.dispatch('wc/store/cart').setCartData(_objectSpread({}, cartTotals)); 391 }, 392 error: function error(jqXHR, textStatus, errorThrown) { 393 console.warn('Failed to fetch available gateways:', textStatus, errorThrown); 394 } 370 }) 371 }).then(function (response) { 372 return response.json(); 373 }).then(function (data) { 374 setAvailableGateways(country, currencyCode, data.data); 375 var cartTotals = wp.data.select('wc/store/cart').getCartTotals(); 376 // Dispatch them again to trigger a re-render: 377 wp.data.dispatch('wc/store/cart').setCartData(_objectSpread({}, cartTotals)); 395 378 }); 396 }, [billing, currencyCode, filters.paymentLocale , ajaxUrl, jQuery, item]);379 }, [billing, currencyCode, filters.paymentLocale]); 397 380 return cachedAvailableGateways; 398 381 } … … 404 387 cartTotal = _ref.cartTotal, 405 388 filters = _ref.filters, 406 ajaxUrl = _ref.ajaxUrl, 407 jQuery = _ref.jQuery, 408 item = _ref.item; 409 useMollieAvailableGateways(billing, currencyCode, cartTotal, filters, ajaxUrl, jQuery, item); 389 ajaxUrl = _ref.ajaxUrl; 390 useMollieAvailableGateways(billing, currencyCode, cartTotal, filters, ajaxUrl); 410 391 return null; 411 392 } … … 523 504 useEffect(function () { 524 505 var onProcessingPayment = function onProcessingPayment() { 506 var data = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({ 507 payment_method: activePaymentMethod, 508 payment_method_title: item.title 509 }, issuerKey, selectedIssuer), "billing_phone", inputPhone), "billing_company_billie", inputCompany), "billing_birthdate", inputBirthdate), "cardToken", ''); 525 510 var tokenVal = jQuery('.mollie-components > input').val(); 511 if (tokenVal) { 512 data.cardToken = tokenVal; 513 } 526 514 return { 527 515 type: responseTypes.SUCCESS, 528 516 meta: { 529 paymentMethodData: _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({ 530 payment_method: activePaymentMethod, 531 payment_method_title: item.title 532 }, issuerKey, selectedIssuer), "billing_phone", inputPhone), "billing_company_billie", inputCompany), "billing_birthdate", inputBirthdate), "cardToken", tokenVal) 517 paymentMethodData: data 533 518 } 534 519 }; … … 682 667 var item = _ref2.item, 683 668 filters = _ref2.filters, 684 ajaxUrl = _ref2.ajaxUrl, 685 jQuery = _ref2.jQuery; 669 ajaxUrl = _ref2.ajaxUrl; 686 670 var cartData = wp.data.useSelect(function (select) { 687 671 return select('wc/store/cart').getCartData(); … … 700 684 filters: filters, 701 685 ajaxUrl: ajaxUrl, 702 jQuery: jQuery,703 item: item,704 686 cartTotal: cartTotal 705 687 })); 706 688 }; 707 689 var molliePaymentMethod = function molliePaymentMethod(useEffect, ajaxUrl, filters, gatewayData, availableGateways, item, jQuery, requiredFields, isCompanyFieldVisible, isPhoneFieldVisible) { 708 document.addEventListener('mollie_components_ready_to_submit', function () { 709 onSubmitLocal(); 710 }); 690 if (item.name === "mollie_wc_gateway_creditcard") { 691 document.addEventListener('mollie_components_ready_to_submit', function () { 692 onSubmitLocal(); 693 }); 694 } 711 695 function creditcardSelectedEvent() { 712 696 if (item.name === "mollie_wc_gateway_creditcard") { 713 697 document.documentElement.dispatchEvent(creditCardSelected); 714 698 } 715 }716 717 // On first load, if availableGateways is not empty, store it718 if (_.isEmpty(cachedAvailableGateways) && !_.isEmpty(availableGateways)) {719 cachedAvailableGateways = availableGateways;720 saveCachedAvailableGateways();721 699 } 722 700 return { … … 725 703 item: item, 726 704 ajaxUrl: ajaxUrl, 727 jQuery: jQuery,728 705 filters: filters 729 706 }), … … 747 724 return true; 748 725 } 749 loadCachedAvailableGateways();750 726 var currencyCode = cartTotals === null || cartTotals === void 0 ? void 0 : cartTotals.currency_code; 751 727 var country = billingData === null || billingData === void 0 ? void 0 : billingData.country; … … 757 733 creditcardSelectedEvent(); 758 734 if (!cachedAvailableGateways.hasOwnProperty(currentFilterKey)) { 759 return false; 760 } 761 return cachedAvailableGateways[currentFilterKey].hasOwnProperty(item.name); 735 cachedAvailableGateways = _objectSpread(_objectSpread({}, cachedAvailableGateways), availableGateways); 736 } 737 if (availableGateways.hasOwnProperty(currentFilterKey) && availableGateways[currentFilterKey].hasOwnProperty(item.name)) { 738 return true; 739 } 740 if (cachedAvailableGateways.hasOwnProperty(currentFilterKey) && cachedAvailableGateways[currentFilterKey].hasOwnProperty(item.name)) { 741 return true; 742 } 743 return false; 762 744 }, 763 745 ariaLabel: item.ariaLabel, … … 857 839 var useEffect = wp.element.useEffect; 858 840 var isAppleSession = typeof window.ApplePaySession === "function"; 859 localStorage.removeItem('cachedAvailableGateways');860 841 function getPhoneField() { 861 842 var phoneFieldDataset = document.querySelector('[data-show-phone-field]'); … … 911 892 /******/ })() 912 893 ; 913 //# sourceMappingURL=data:application/json;charset=utf-8;base64,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tBQUssRUFBRSwwQkFBMEI7VUFDakNrRyxXQUFXLEVBQUUsMEJBQTBCO1VBQ3ZDM0QsT0FBTyxlQUFFMUosS0FBQSxDQUFBQyxhQUFBLENBQUN2Ryx1RUFBdUIsTUFBQyxDQUFDO1VBQ25DZ1MsSUFBSSxlQUFFMUwsS0FBQSxDQUFBQyxhQUFBLENBQUNLLDZFQUE2QixNQUFDLENBQUM7VUFDdEM0TCxTQUFTLEVBQUUsV0FBVztVQUN0Qk4sY0FBYyxFQUFFLFNBQUFBLGVBQUE7WUFBQSxPQUFNLElBQUk7VUFBQTtVQUMxQkQsZUFBZSxFQUFFLDRCQUE0QjtVQUM3QzJCLFNBQVMsRUFBRSw0QkFBNEI7VUFDdkNuQixRQUFRLEVBQUU7WUFDTkMsUUFBUSxFQUFFLENBQUMsVUFBVSxDQUFDO1lBQ3RCclIsS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLGNBQWM7VUFDcEM7UUFDSixDQUFDLENBQUM7TUFDTjtNQUNBO0lBQ0o7SUFDQWtTLFFBQVEsQ0FBQyxDQUFDO0VBQ2QsQ0FBQyxDQUFDO0FBQ04sQ0FBQyxFQUNIbFQsTUFBTSxFQUFFc1MsRUFBRSxDQUFDLEMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlLy4vcmVzb3VyY2VzL2pzL2FwcGxlUGF5RXJyb3IuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9hcHBsZVBheVJlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9ibG9ja3MvQXBwbGVQYXlCdXR0b25Db21wb25lbnQuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9ibG9ja3MvQXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9ibG9ja3MvbW9sbGllUGF5bWVudE1ldGhvZC5qcyIsIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2Uvd2VicGFjay9ydW50aW1lL2RlZmluZSBwcm9wZXJ0eSBnZXR0ZXJzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2Uvd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlL3dlYnBhY2svcnVudGltZS9tYWtlIG5hbWVzcGFjZSBvYmplY3QiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9tb2xsaWVCbG9ja0luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBcHBsZUVycm9ycyhlcnJvcnMpIHtcbiAgICBjb25zdCBlcnJvckxpc3QgPSBbXVxuICAgIGZvciAoY29uc3QgZXJyb3Igb2YgZXJyb3JzKSB7XG4gICAgICAgIGNvbnN0IHtjb250YWN0RmllbGQgPSBudWxsLCBjb2RlID0gbnVsbCwgbWVzc2FnZSA9IG51bGx9ID0gZXJyb3JcbiAgICAgICAgY29uc3QgYXBwbGVFcnJvciA9IGNvbnRhY3RGaWVsZCA/IG5ldyBBcHBsZVBheUVycm9yKGNvZGUsIGNvbnRhY3RGaWVsZCwgbWVzc2FnZSkgOiBuZXcgQXBwbGVQYXlFcnJvcihjb2RlKVxuICAgICAgICBlcnJvckxpc3QucHVzaChhcHBsZUVycm9yKVxuICAgIH1cblxuICAgIHJldHVybiBlcnJvckxpc3Rcbn1cbiIsImV4cG9ydCBjb25zdCByZXF1ZXN0ID0gKGNvdW50cnlDb2RlLCBjdXJyZW5jeUNvZGUsIHRvdGFsTGFiZWwsIHN1YnRvdGFsKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY291bnRyeUNvZGU6IGNvdW50cnlDb2RlLFxuICAgICAgICBjdXJyZW5jeUNvZGU6IGN1cnJlbmN5Q29kZSxcbiAgICAgICAgc3VwcG9ydGVkTmV0d29ya3M6IFsnYW1leCcsICdtYWVzdHJvJywgJ21hc3RlckNhcmQnLCAndmlzYScsICd2UGF5J10sXG4gICAgICAgIG1lcmNoYW50Q2FwYWJpbGl0aWVzOiBbJ3N1cHBvcnRzM0RTJ10sXG4gICAgICAgIHNoaXBwaW5nVHlwZTogJ3NoaXBwaW5nJyxcbiAgICAgICAgcmVxdWlyZWRCaWxsaW5nQ29udGFjdEZpZWxkczogW1xuICAgICAgICAgICAgJ3Bvc3RhbEFkZHJlc3MnLFxuICAgICAgICAgICAgJ2VtYWlsJ1xuICAgICAgICBdLFxuICAgICAgICByZXF1aXJlZFNoaXBwaW5nQ29udGFjdEZpZWxkczogW1xuICAgICAgICAgICAgJ3Bvc3RhbEFkZHJlc3MnLFxuICAgICAgICAgICAgJ2VtYWlsJ1xuICAgICAgICBdLFxuICAgICAgICB0b3RhbDoge1xuICAgICAgICAgICAgbGFiZWw6IHRvdGFsTGFiZWwsXG4gICAgICAgICAgICBhbW91bnQ6IHN1YnRvdGFsLFxuICAgICAgICAgICAgdHlwZTogJ2ZpbmFsJ1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiaW1wb3J0IHtyZXF1ZXN0fSBmcm9tIFwiLi4vYXBwbGVQYXlSZXF1ZXN0XCI7XG5pbXBvcnQge2NyZWF0ZUFwcGxlRXJyb3JzfSBmcm9tIFwiLi4vYXBwbGVQYXlFcnJvclwiO1xuXG5leHBvcnQgY29uc3QgQXBwbGVQYXlCdXR0b25Db21wb25lbnQgPSAoeyBidXR0b25BdHRyaWJ1dGVzID0ge30gfSkgPT4ge1xuICAgIGNvbnN0IG1vbGxpZUFwcGxlUGF5QmxvY2tEYXRhQ2FydCA9IHdpbmRvdy5tb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnQgfHwgd2luZG93Lm1vbGxpZUJsb2NrRGF0YS5tb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnRcbiAgICBjb25zdCBub25jZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwid29vY29tbWVyY2UtcHJvY2Vzcy1jaGVja291dC1ub25jZVwiKS52YWx1ZVxuICAgIGxldCB1cGRhdGVkQ29udGFjdEluZm8gPSBbXVxuICAgIGxldCByZWRpcmVjdGlvblVybCA9ICcnXG4gICAgY29uc3Qge1xuICAgICAgICBwcm9kdWN0OiB7bmVlZFNoaXBwaW5nID0gdHJ1ZSwgc3VidG90YWx9LFxuICAgICAgICBzaG9wOiB7Y291bnRyeUNvZGUsIGN1cnJlbmN5Q29kZSA9ICdFVVInLCB0b3RhbExhYmVsID0gJyd9LFxuICAgICAgICBhamF4VXJsLFxuICAgIH0gPSBtb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnRcbiAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgICAgaGVpZ2h0OiBgJHtidXR0b25BdHRyaWJ1dGVzLmhlaWdodCB8fCA0OH1weGAsXG4gICAgICAgIGJvcmRlclJhZGl1czogYCR7YnV0dG9uQXR0cmlidXRlcy5ib3JkZXJSYWRpdXMgfHwgNH1weGBcbiAgICB9XG5cbiAgICBjb25zdCBmaW5kU2VsZWN0ZWRTaGlwcGluZ01ldGhvZCA9IChzaGlwcGluZ1JhdGVzKSA9PiB7XG4gICAgICAgIGxldCBzaGlwcGluZ1JhdGUgPSBzaGlwcGluZ1JhdGVzLmZpbmQoKHNoaXBwaW5nTWV0aG9kKSA9PiBzaGlwcGluZ01ldGhvZC5zZWxlY3RlZCA9PT0gdHJ1ZSlcbiAgICAgICAgY29uc3QgYXBwbGVGb3JtYXR0ZWRSYXRlID0ge1xuICAgICAgICAgICAgYW1vdW50OiAnJyxcbiAgICAgICAgICAgIGRldGFpbDogJycsXG4gICAgICAgICAgICBsYWJlbDogc2hpcHBpbmdSYXRlLm5hbWUsXG4gICAgICAgICAgICBpZGVudGlmaWVyOiBzaGlwcGluZ1JhdGUucmF0ZV9pZCxcbiAgICAgICAgICAgIHNlbGVjdGVkOiBzaGlwcGluZ1JhdGUuc2VsZWN0ZWQsXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNoaXBwaW5nUmF0ZSA/IGFwcGxlRm9ybWF0dGVkUmF0ZSA6ICcnXG4gICAgfVxuXG4gICAgbGV0IGFwcGxlUGF5U2Vzc2lvbiA9ICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBBcHBsZVBheVNlc3Npb24oMywgcmVxdWVzdChjb3VudHJ5Q29kZSwgY3VycmVuY3lDb2RlLCB0b3RhbExhYmVsLCBzdWJ0b3RhbCkpXG4gICAgICAgIGNvbnN0IHN0b3JlID0gd3AuZGF0YS5zZWxlY3QoJ3djL3N0b3JlL2NhcnQnKVxuICAgICAgICBjb25zdCBzaGlwcGluZ1JhdGVzID0gc3RvcmUuZ2V0U2hpcHBpbmdSYXRlcygpPy5bMF0/LnNoaXBwaW5nX3JhdGVzO1xuICAgICAgICBsZXQgc2VsZWN0ZWRTaGlwcGluZ01ldGhvZCA9ICcnO1xuICAgICAgICBpZiAoc2hpcHBpbmdSYXRlcyAmJiBzaGlwcGluZ1JhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSBmaW5kU2VsZWN0ZWRTaGlwcGluZ01ldGhvZChzaGlwcGluZ1JhdGVzLCBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kKTtcbiAgICAgICAgfVxuICAgICAgICAgICAgc2Vzc2lvbi5vbnNoaXBwaW5nbWV0aG9kc2VsZWN0ZWQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGpRdWVyeS5hamF4KHtcbiAgICAgICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfYXBwbGVfcGF5X3VwZGF0ZV9zaGlwcGluZ19tZXRob2QnLFxuICAgICAgICAgICAgICAgICAgICBzaGlwcGluZ01ldGhvZDogZXZlbnQuc2hpcHBpbmdNZXRob2QsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxlclBhZ2U6ICdjYXJ0JyxcbiAgICAgICAgICAgICAgICAgICAgc2ltcGxpZmllZENvbnRhY3Q6IHVwZGF0ZWRDb250YWN0SW5mbyxcbiAgICAgICAgICAgICAgICAgICAgJ3dvb2NvbW1lcmNlLXByb2Nlc3MtY2hlY2tvdXQtbm9uY2UnOiBub25jZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IChhcHBsZVBheVNoaXBwaW5nTWV0aG9kVXBkYXRlLCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSBhcHBsZVBheVNoaXBwaW5nTWV0aG9kVXBkYXRlLmRhdGFcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRTaGlwcGluZ01ldGhvZCA9IGV2ZW50LnNoaXBwaW5nTWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmIChhcHBsZVBheVNoaXBwaW5nTWV0aG9kVXBkYXRlLnN1Y2Nlc3MgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5lcnJvcnMgPSBjcmVhdGVBcHBsZUVycm9ycyhyZXNwb25zZS5lcnJvcnMpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0ZVNoaXBwaW5nTWV0aG9kU2VsZWN0aW9uKHJlc3BvbnNlKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBzZXNzaW9uLm9uc2hpcHBpbmdjb250YWN0c2VsZWN0ZWQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGpRdWVyeS5hamF4KHtcbiAgICAgICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfYXBwbGVfcGF5X3VwZGF0ZV9zaGlwcGluZ19jb250YWN0JyxcbiAgICAgICAgICAgICAgICAgICAgc2ltcGxpZmllZENvbnRhY3Q6IGV2ZW50LnNoaXBwaW5nQ29udGFjdCxcbiAgICAgICAgICAgICAgICAgICAgY2FsbGVyUGFnZTogJ2NhcnQnLFxuICAgICAgICAgICAgICAgICAgICBuZWVkU2hpcHBpbmc6IG5lZWRTaGlwcGluZyxcbiAgICAgICAgICAgICAgICAgICAgJ3dvb2NvbW1lcmNlLXByb2Nlc3MtY2hlY2tvdXQtbm9uY2UnOiBub25jZSxcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdNZXRob2Q6IHNlbGVjdGVkU2hpcHBpbmdNZXRob2QsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiAoYXBwbGVQYXlTaGlwcGluZ0NvbnRhY3RVcGRhdGUsIHRleHRTdGF0dXMsIGpxWEhSKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZXNwb25zZSA9IGFwcGxlUGF5U2hpcHBpbmdDb250YWN0VXBkYXRlLmRhdGFcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlZENvbnRhY3RJbmZvID0gZXZlbnQuc2hpcHBpbmdDb250YWN0XG4gICAgICAgICAgICAgICAgICAgIGlmIChhcHBsZVBheVNoaXBwaW5nQ29udGFjdFVwZGF0ZS5zdWNjZXNzID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZXJyb3JzID0gY3JlYXRlQXBwbGVFcnJvcnMocmVzcG9uc2UuZXJyb3JzKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5uZXdTaGlwcGluZ01ldGhvZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSByZXNwb25zZS5uZXdTaGlwcGluZ01ldGhvZHNbMF1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBsZXRlU2hpcHBpbmdDb250YWN0U2VsZWN0aW9uKHJlc3BvbnNlKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBzZXNzaW9uLm9udmFsaWRhdGVtZXJjaGFudCA9IChhcHBsZVBheVZhbGlkYXRlTWVyY2hhbnRFdmVudCkgPT4ge1xuICAgICAgICAgICAgalF1ZXJ5LmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogYWpheFVybCxcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbjogJ21vbGxpZV9hcHBsZV9wYXlfdmFsaWRhdGlvbicsXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25Vcmw6IGFwcGxlUGF5VmFsaWRhdGVNZXJjaGFudEV2ZW50LnZhbGlkYXRpb25VUkwsXG4gICAgICAgICAgICAgICAgICAgICd3b29jb21tZXJjZS1wcm9jZXNzLWNoZWNrb3V0LW5vbmNlJzogbm9uY2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiAobWVyY2hhbnRTZXNzaW9uLCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAobWVyY2hhbnRTZXNzaW9uLnN1Y2Nlc3MgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uY29tcGxldGVNZXJjaGFudFZhbGlkYXRpb24oSlNPTi5wYXJzZShtZXJjaGFudFNlc3Npb24uZGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4obWVyY2hhbnRTZXNzaW9uLmRhdGEpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBzZXNzaW9uLm9ucGF5bWVudGF1dGhvcml6ZWQgPSAoQXBwbGVQYXlQYXltZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7YmlsbGluZ0NvbnRhY3QsIHNoaXBwaW5nQ29udGFjdH0gPSBBcHBsZVBheVBheW1lbnQucGF5bWVudFxuXG4gICAgICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAnbW9sbGllX2FwcGxlX3BheV9jcmVhdGVfb3JkZXJfY2FydCcsXG4gICAgICAgICAgICAgICAgICAgIHNoaXBwaW5nQ29udGFjdDogQXBwbGVQYXlQYXltZW50LnBheW1lbnQuc2hpcHBpbmdDb250YWN0LFxuICAgICAgICAgICAgICAgICAgICBiaWxsaW5nQ29udGFjdDogQXBwbGVQYXlQYXltZW50LnBheW1lbnQuYmlsbGluZ0NvbnRhY3QsXG4gICAgICAgICAgICAgICAgICAgIHRva2VuOiBBcHBsZVBheVBheW1lbnQucGF5bWVudC50b2tlbixcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdNZXRob2Q6IHNlbGVjdGVkU2hpcHBpbmdNZXRob2QsXG4gICAgICAgICAgICAgICAgICAgICdtb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlX2lzc3Vlcl9hcHBsZXBheSc6ICdhcHBsZXBheScsXG4gICAgICAgICAgICAgICAgICAgICd3b29jb21tZXJjZS1wcm9jZXNzLWNoZWNrb3V0LW5vbmNlJzogbm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2ZpcnN0X25hbWUnOiBiaWxsaW5nQ29udGFjdC5naXZlbk5hbWUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2xhc3RfbmFtZSc6IGJpbGxpbmdDb250YWN0LmZhbWlseU5hbWUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2NvbXBhbnknOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfY291bnRyeSc6IGJpbGxpbmdDb250YWN0LmNvdW50cnlDb2RlIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19hZGRyZXNzXzEnOiBiaWxsaW5nQ29udGFjdC5hZGRyZXNzTGluZXNbMF0gfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2FkZHJlc3NfMic6IGJpbGxpbmdDb250YWN0LmFkZHJlc3NMaW5lc1sxXSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfcG9zdGNvZGUnOiBiaWxsaW5nQ29udGFjdC5wb3N0YWxDb2RlIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19jaXR5JzogYmlsbGluZ0NvbnRhY3QubG9jYWxpdHkgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX3N0YXRlJzogYmlsbGluZ0NvbnRhY3QuYWRtaW5pc3RyYXRpdmVBcmVhIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19waG9uZSc6IGJpbGxpbmdDb250YWN0LnBob25lTnVtYmVyIHx8ICcwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19lbWFpbCc6IHNoaXBwaW5nQ29udGFjdC5lbWFpbEFkZHJlc3MgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19maXJzdF9uYW1lJzogc2hpcHBpbmdDb250YWN0LmdpdmVuTmFtZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2xhc3RfbmFtZSc6IHNoaXBwaW5nQ29udGFjdC5mYW1pbHlOYW1lIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfY29tcGFueSc6ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfY291bnRyeSc6IHNoaXBwaW5nQ29udGFjdC5jb3VudHJ5Q29kZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2FkZHJlc3NfMSc6IHNoaXBwaW5nQ29udGFjdC5hZGRyZXNzTGluZXNbMF0gfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19hZGRyZXNzXzInOiBzaGlwcGluZ0NvbnRhY3QuYWRkcmVzc0xpbmVzWzFdIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfcG9zdGNvZGUnOiBzaGlwcGluZ0NvbnRhY3QucG9zdGFsQ29kZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2NpdHknOiBzaGlwcGluZ0NvbnRhY3QubG9jYWxpdHkgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19zdGF0ZSc6IHNoaXBwaW5nQ29udGFjdC5hZG1pbmlzdHJhdGl2ZUFyZWEgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19waG9uZSc6IHNoaXBwaW5nQ29udGFjdC5waG9uZU51bWJlciB8fCAnMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2VtYWlsJzogc2hpcHBpbmdDb250YWN0LmVtYWlsQWRkcmVzcyB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ29yZGVyX2NvbW1lbnRzJzogJycsXG4gICAgICAgICAgICAgICAgICAgICdwYXltZW50X21ldGhvZCc6ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheScsXG4gICAgICAgICAgICAgICAgICAgICdfd3BfaHR0cF9yZWZlcmVyJzogJy8/d2MtYWpheD11cGRhdGVfb3JkZXJfcmV2aWV3J1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogKGF1dGhvcml6YXRpb25SZXN1bHQsIHRleHRTdGF0dXMsIGpxWEhSKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZXN1bHQgPSBhdXRob3JpemF0aW9uUmVzdWx0LmRhdGFcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1dGhvcml6YXRpb25SZXN1bHQuc3VjY2VzcyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVkaXJlY3Rpb25VcmwgPSByZXN1bHRbJ3JldHVyblVybCddO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5jb21wbGV0ZVBheW1lbnQocmVzdWx0WydyZXNwb25zZVRvQXBwbGUnXSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gcmVkaXJlY3Rpb25VcmxcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5lcnJvcnMgPSBjcmVhdGVBcHBsZUVycm9ycyhyZXN1bHQuZXJyb3JzKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5jb21wbGV0ZVBheW1lbnQocmVzdWx0KVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogKGpxWEhSLCB0ZXh0U3RhdHVzLCBlcnJvclRocm93bikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4odGV4dFN0YXR1cywgZXJyb3JUaHJvd24pXG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24uYWJvcnQoKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIHNlc3Npb24uYmVnaW4oKVxuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGlkPVwibW9sbGllX2FwcGxlcGF5X2J1dHRvblwiXG4gICAgICAgICAgICBjbGFzc05hbWU9XCJhcHBsZS1wYXktYnV0dG9uIGFwcGxlLXBheS1idXR0b24tYmxhY2tcIlxuICAgICAgICAgICAgb25DbGljaz17KGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBhcHBsZVBheVNlc3Npb24oKTtcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgICBzdHlsZT17c3R5bGV9XG4gICAgICAgID5cbiAgICAgICAgPC9idXR0b24+XG4gICAgKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgQXBwbGVQYXlCdXR0b25Db21wb25lbnQ7XG4iLCJleHBvcnQgY29uc3QgQXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQgPSAoeyBidXR0b25BdHRyaWJ1dGVzID0ge30gfSkgPT4ge1xuICAgIGNvbnN0IHN0eWxlID0ge1xuICAgICAgICBoZWlnaHQ6IGAke2J1dHRvbkF0dHJpYnV0ZXMuaGVpZ2h0IHx8IDQ4fXB4YCxcbiAgICAgICAgYm9yZGVyUmFkaXVzOiBgJHtidXR0b25BdHRyaWJ1dGVzLmJvcmRlclJhZGl1cyB8fCA0fXB4YFxuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGlkPVwibW9sbGllX2FwcGxlcGF5X2J1dHRvblwiXG4gICAgICAgICAgICBjbGFzc05hbWU9XCJhcHBsZS1wYXktYnV0dG9uIGFwcGxlLXBheS1idXR0b24tYmxhY2tcIlxuICAgICAgICAgICAgc3R5bGU9e3N0eWxlfVxuICAgICAgICA+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICk7XG59O1xuZXhwb3J0IGRlZmF1bHQgQXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQ7XG4iLCJsZXQgY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMgPSB7fTtcblxuZnVuY3Rpb24gZm9ybWF0UHJpY2VMaWtlV2MocHJpY2UpIHtcbiAgICAvLyB0b2RvIGFkZCB0aG91c2FuZFNlcGFyYXRvclxuICAgIHJldHVybiB3Y1NldHRpbmdzLmN1cnJlbmN5LnByaWNlRm9ybWF0LnJlcGxhY2UoJyUxJHMnLCB3Y1NldHRpbmdzLmN1cnJlbmN5LnN5bWJvbCkucmVwbGFjZSgnJTIkcycscHJpY2UudG9GaXhlZCh3Y1NldHRpbmdzLmN1cnJlbmN5LnByZWNpc2lvbikucmVwbGFjZSgnLicsIHdjU2V0dGluZ3MuY3VycmVuY3kuZGVjaW1hbFNlcGFyYXRvcikpO1xufVxuXG5mdW5jdGlvbiBsb2FkQ2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMoKSB7XG4gICAgY29uc3Qgc3RvcmVkRGF0YSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdjYWNoZWRBdmFpbGFibGVHYXRld2F5cycpO1xuICAgIGlmIChzdG9yZWREYXRhKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjYWNoZWRBdmFpbGFibGVHYXRld2F5cyA9IEpTT04ucGFyc2Uoc3RvcmVkRGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRXJyb3IgcGFyc2luZyBjYWNoZWRBdmFpbGFibGVHYXRld2F5cyBmcm9tIGxvY2FsU3RvcmFnZTonLCBlKTtcbiAgICAgICAgICAgIGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzID0ge307XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNhdmVDYWNoZWRBdmFpbGFibGVHYXRld2F5cygpIHtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMnLCBKU09OLnN0cmluZ2lmeShjYWNoZWRBdmFpbGFibGVHYXRld2F5cykpO1xufVxuXG5sb2FkQ2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMoKTtcbmZ1bmN0aW9uIHNldEF2YWlsYWJsZUdhdGV3YXlzKGNvdW50cnksIGN1cnJlbmN5Q29kZSwgZGF0YSkge1xuICAgIGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzID0ge1xuICAgICAgICAuLi5jYWNoZWRBdmFpbGFibGVHYXRld2F5cyxcbiAgICAgICAgLi4uZGF0YVxuICAgIH07XG4gICAgc2F2ZUNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzKCk7XG59XG5mdW5jdGlvbiB1c2VNb2xsaWVBdmFpbGFibGVHYXRld2F5cyhiaWxsaW5nLCBjdXJyZW5jeUNvZGUsIGNhcnRUb3RhbCwgZmlsdGVycywgYWpheFVybCwgalF1ZXJ5LCBpdGVtKSB7XG4gICAgbGV0IGNvdW50cnkgPSBiaWxsaW5nLmNvdW50cnk7XG4gICAgY29uc3QgY29kZSA9IGN1cnJlbmN5Q29kZTtcbiAgICBjb25zdCB2YWx1ZSA9IGNhcnRUb3RhbDtcbiAgICBpZiAoIWNvdW50cnkpIHtcbiAgICAgICAgY291bnRyeSA9IHdjU2V0dGluZ3M/LmJhc2VMb2NhdGlvbi5jb3VudHJ5O1xuICAgIH1cblxuICAgIHdwLmVsZW1lbnQudXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgaWYgKCFjb3VudHJ5IHx8ICFpdGVtKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGN1cnJlbmN5Q29kZSA9IGNvZGU7XG4gICAgICAgIGNvbnN0IGNhcnRUb3RhbCA9IHZhbHVlO1xuICAgICAgICBjb25zdCBjdXJyZW50RmlsdGVyS2V5ID0gY3VycmVuY3lDb2RlICsgXCItXCIgKyBjb3VudHJ5O1xuICAgICAgICBpZiAoY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMuaGFzT3duUHJvcGVydHkoY3VycmVudEZpbHRlcktleSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfY2hlY2tvdXRfYmxvY2tzX2Nhbm1ha2VwYXltZW50JyxcbiAgICAgICAgICAgICAgICBjdXJyZW50R2F0ZXdheTogaXRlbSxcbiAgICAgICAgICAgICAgICBjdXJyZW5jeTogY3VycmVuY3lDb2RlLFxuICAgICAgICAgICAgICAgIGJpbGxpbmdDb3VudHJ5OiBjb3VudHJ5LFxuICAgICAgICAgICAgICAgIGNhcnRUb3RhbCxcbiAgICAgICAgICAgICAgICBwYXltZW50TG9jYWxlOiBmaWx0ZXJzLnBheW1lbnRMb2NhbGVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdWNjZXNzOiAocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBzZXRBdmFpbGFibGVHYXRld2F5cyhjb3VudHJ5LCBjdXJyZW5jeUNvZGUsIHJlc3BvbnNlLmRhdGEpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhcnRUb3RhbHMgPSB3cC5kYXRhLnNlbGVjdCgnd2Mvc3RvcmUvY2FydCcpLmdldENhcnRUb3RhbHMoKTtcbiAgICAgICAgICAgICAgICAvLyBEaXNwYXRjaCB0aGVtIGFnYWluIHRvIHRyaWdnZXIgYSByZS1yZW5kZXI6XG4gICAgICAgICAgICAgICAgd3AuZGF0YS5kaXNwYXRjaCgnd2Mvc3RvcmUvY2FydCcpLnNldENhcnREYXRhKHsuLi5jYXJ0VG90YWxzfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBmZXRjaCBhdmFpbGFibGUgZ2F0ZXdheXM6JywgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfSwgW2JpbGxpbmcsIGN1cnJlbmN5Q29kZSwgZmlsdGVycy5wYXltZW50TG9jYWxlLCBhamF4VXJsLCBqUXVlcnksIGl0ZW1dKTtcblxuICAgIHJldHVybiBjYWNoZWRBdmFpbGFibGVHYXRld2F5cztcbn1cblxuLy8gQ29tcG9uZW50IHRoYXQgcnVucyB0aGUgaG9vayBidXQgZG9lcyBub3QgcmVuZGVyIGFueXRoaW5nLlxuZnVuY3Rpb24gTW9sbGllR2F0ZXdheVVwZGF0ZXIoeyBiaWxsaW5nLCBjdXJyZW5jeUNvZGUsIGNhcnRUb3RhbCwgZmlsdGVycywgYWpheFVybCwgalF1ZXJ5LCBpdGVtIH0pIHtcblxuICAgIHVzZU1vbGxpZUF2YWlsYWJsZUdhdGV3YXlzKGJpbGxpbmcsIGN1cnJlbmN5Q29kZSwgY2FydFRvdGFsLCBmaWx0ZXJzLCBhamF4VXJsLCBqUXVlcnksIGl0ZW0pO1xuICAgIHJldHVybiBudWxsO1xufVxuXG5sZXQgb25TdWJtaXRMb2NhbFxubGV0IGFjdGl2ZVBheW1lbnRNZXRob2RMb2NhbFxubGV0IGNyZWRpdENhcmRTZWxlY3RlZCA9IG5ldyBFdmVudChcIm1vbGxpZV9jcmVkaXRjYXJkX2NvbXBvbmVudF9zZWxlY3RlZFwiLCB7YnViYmxlczogdHJ1ZX0pO1xuY29uc3QgTW9sbGllQ29tcG9uZW50ID0gKHByb3BzKSA9PiB7XG4gICAgbGV0IHtvblN1Ym1pdCwgYWN0aXZlUGF5bWVudE1ldGhvZCwgYmlsbGluZywgaXRlbSwgdXNlRWZmZWN0LCBhamF4VXJsLCBqUXVlcnksIGVtaXRSZXNwb25zZSwgZXZlbnRSZWdpc3RyYXRpb24sIHJlcXVpcmVkRmllbGRzLCBzaGlwcGluZ0RhdGEsIGlzUGhvbmVGaWVsZFZpc2libGV9ID0gcHJvcHNcbiAgICBjb25zdCB7ICByZXNwb25zZVR5cGVzIH0gPSBlbWl0UmVzcG9uc2U7XG4gICAgY29uc3Qge29uUGF5bWVudFNldHVwLCBvbkNoZWNrb3V0VmFsaWRhdGlvbn0gPSBldmVudFJlZ2lzdHJhdGlvbjtcbiAgICBpZiAoIWl0ZW0gfHwgIWl0ZW0ubmFtZSkge1xuICAgICAgICByZXR1cm4gPGRpdj5Mb2FkaW5nIHBheW1lbnQgbWV0aG9kcy4uLjwvZGl2PjtcbiAgICB9XG4gICAgY29uc3QgWyBzZWxlY3RlZElzc3Vlciwgc2VsZWN0SXNzdWVyIF0gPSB3cC5lbGVtZW50LnVzZVN0YXRlKCcnKTtcbiAgICBjb25zdCBbIGlucHV0UGhvbmUsIHNlbGVjdFBob25lIF0gPSB3cC5lbGVtZW50LnVzZVN0YXRlKCcnKTtcbiAgICBjb25zdCBbIGlucHV0QmlydGhkYXRlLCBzZWxlY3RCaXJ0aGRhdGUgXSA9IHdwLmVsZW1lbnQudXNlU3RhdGUoJycpO1xuICAgIGNvbnN0IFsgaW5wdXRDb21wYW55LCBzZWxlY3RDb21wYW55IF0gPSB3cC5lbGVtZW50LnVzZVN0YXRlKCcnKTtcbiAgICBjb25zdCBpc3N1ZXJLZXkgPSAnbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZV9pc3N1ZXJfJyArIGFjdGl2ZVBheW1lbnRNZXRob2RcbiAgICBjb25zdCB7Y29tcGFueU5hbWVTdHJpbmcsIHBob25lU3RyaW5nfSA9IHJlcXVpcmVkRmllbGRzXG4gICAgZnVuY3Rpb24gZ2V0UGhvbmVGaWVsZCgpXG4gICAge1xuICAgICAgICBjb25zdCBzaGlwcGluZ1Bob25lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NoaXBwaW5nLXBob25lJyk7XG4gICAgICAgIGNvbnN0IGJpbGxpbmdQaG9uZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nLXBob25lJyk7XG4gICAgICAgIHJldHVybiBiaWxsaW5nUGhvbmUgfHwgc2hpcHBpbmdQaG9uZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gdXBkYXRlVG90YWxMYWJlbChuZXdUb3RhbCkge1xuICAgICAgICBsZXQgdG90YWxTcGFuID0gXCI8c3BhbiBjbGFzcz0nd2MtYmxvY2stZm9ybWF0dGVkLW1vbmV5LWFtb3VudCB3Yy1ibG9jay1jb21wb25lbnRzLWZvcm1hdHRlZC1tb25leS1hbW91bnQgd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fdmFsdWUnPlwiICsgZm9ybWF0UHJpY2VMaWtlV2MobmV3VG90YWwpICsgXCI8L3NwYW4+XCJcbiAgICAgICAgbGV0IHRvdGFsID0galF1ZXJ5KCcud2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtZm9vdGVyLWl0ZW0gLndjLWJsb2NrLWZvcm1hdHRlZC1tb25leS1hbW91bnQ6Zmlyc3QnKVxuICAgICAgICB0b3RhbC5yZXBsYWNlV2l0aCh0b3RhbFNwYW4pXG4gICAgfVxuICAgIGZ1bmN0aW9uIHVwZGF0ZVRheGVzTGFiZWwobmV3VG90YWwpIHtcbiAgICAgICAgbGV0IHRvdGFsU3BhbiA9IFwiPHNwYW4gY2xhc3M9J3djLWJsb2NrLWZvcm1hdHRlZC1tb25leS1hbW91bnQgd2MtYmxvY2stY29tcG9uZW50cy1mb3JtYXR0ZWQtbW9uZXktYW1vdW50IHdjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX3ZhbHVlJz5cIiArIGZvcm1hdFByaWNlTGlrZVdjKG5ld1RvdGFsKSArIFwiPC9zcGFuPlwiXG4gICAgICAgIGxldCB0b3RhbCA9IGpRdWVyeSgnZGl2LndwLWJsb2NrLXdvb2NvbW1lcmNlLWNoZWNrb3V0LW9yZGVyLXN1bW1hcnktdGF4ZXMtYmxvY2sud2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtd3JhcHBlciA+IGRpdiA+IHNwYW4ud2MtYmxvY2stZm9ybWF0dGVkLW1vbmV5LWFtb3VudC53Yy1ibG9jay1jb21wb25lbnRzLWZvcm1hdHRlZC1tb25leS1hbW91bnQud2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fdmFsdWU6Zmlyc3QnKVxuICAgICAgICB0b3RhbC5yZXBsYWNlV2l0aCh0b3RhbFNwYW4pXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGlkZUZlZShmZWUsIHJlc3BvbnNlKSB7XG4gICAgICAgIGZlZT8uaGlkZSgpXG4gICAgICAgIHVwZGF0ZVRvdGFsTGFiZWwocmVzcG9uc2UuZGF0YS5uZXdUb3RhbCk7XG4gICAgICAgIHVwZGF0ZVRheGVzTGFiZWwocmVzcG9uc2UuZGF0YS50b3RhbFRheCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmVlTWFya3VwKHJlc3BvbnNlKSB7XG4gICAgICAgIHJldHVybiBcIjxkaXYgY2xhc3M9J3djLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW0gd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtZmVlcyc+XCIgK1xuICAgICAgICAgICAgXCI8c3BhbiBjbGFzcz0nd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fbGFiZWwnPlwiXG4gICAgICAgICAgICArIHJlc3BvbnNlLmRhdGEubmFtZVxuICAgICAgICAgICAgKyBcIjwvc3Bhbj5cIiArXG4gICAgICAgICAgICBcIjxzcGFuIGNsYXNzPSd3Yy1ibG9jay1mb3JtYXR0ZWQtbW9uZXktYW1vdW50IHdjLWJsb2NrLWNvbXBvbmVudHMtZm9ybWF0dGVkLW1vbmV5LWFtb3VudCB3Yy1ibG9jay1jb21wb25lbnRzLXRvdGFscy1pdGVtX192YWx1ZSc+XCJcbiAgICAgICAgICAgICsgZm9ybWF0UHJpY2VMaWtlV2MocmVzcG9uc2UuZGF0YS5hbW91bnQpXG4gICAgICAgICAgICArIFwiPC9zcGFuPlwiICtcbiAgICAgICAgICAgIFwiPGRpdiBjbGFzcz0nd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fZGVzY3JpcHRpb24nPlwiICtcbiAgICAgICAgICAgIFwiPC9kaXY+XCIgK1xuICAgICAgICAgICAgXCI8L2Rpdj5cIjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXBsYWNlRmVlKGZlZSwgbmV3RmVlLCByZXNwb25zZSkge1xuICAgICAgICBmZWUucmVwbGFjZVdpdGgobmV3RmVlKVxuICAgICAgICB1cGRhdGVUb3RhbExhYmVsKHJlc3BvbnNlLmRhdGEubmV3VG90YWwpO1xuICAgICAgICB1cGRhdGVUYXhlc0xhYmVsKHJlc3BvbnNlLmRhdGEudG90YWxUYXgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc2VydE5ld0ZlZShuZXdGZWUsIHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IHN1YnRvdGFsID0galF1ZXJ5KCcud2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbTpmaXJzdCcpXG4gICAgICAgIHN1YnRvdGFsLmFmdGVyKG5ld0ZlZSlcbiAgICAgICAgdXBkYXRlVG90YWxMYWJlbChyZXNwb25zZS5kYXRhLm5ld1RvdGFsKTtcbiAgICAgICAgdXBkYXRlVGF4ZXNMYWJlbChyZXNwb25zZS5kYXRhLnRvdGFsVGF4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYW5kbGVGZWVzKHJlc3BvbnNlKSB7XG4gICAgICAgIGNvbnN0IGZlZSA9IGpRdWVyeSgnLndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWZlZXMnKVxuICAgICAgICBpZiAoIXJlc3BvbnNlLmRhdGEuYW1vdW50KSB7XG4gICAgICAgICAgICBoaWRlRmVlKGZlZSwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbmV3RmVlID0gZmVlTWFya3VwKHJlc3BvbnNlKTtcbiAgICAgICAgaWYgKGZlZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJlcGxhY2VGZWUoZmVlLCBuZXdGZWUsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGluc2VydE5ld0ZlZShuZXdGZWUsIHJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBpZihhY3RpdmVQYXltZW50TWV0aG9kTG9jYWwgIT09IGFjdGl2ZVBheW1lbnRNZXRob2QgJiYgYWN0aXZlUGF5bWVudE1ldGhvZCA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2NyZWRpdGNhcmQnKXtcbiAgICAgICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kaXNwYXRjaEV2ZW50KGNyZWRpdENhcmRTZWxlY3RlZCk7XG4gICAgICAgIH1cbiAgICAgICAgYWN0aXZlUGF5bWVudE1ldGhvZExvY2FsID0gYWN0aXZlUGF5bWVudE1ldGhvZFxuICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfY2hlY2tvdXRfYmxvY2tzX3N1cmNoYWdlJyxcbiAgICAgICAgICAgICAgICBtZXRob2Q6IGFjdGl2ZVBheW1lbnRNZXRob2RcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb21wbGV0ZTogKGpxWEhSLCB0ZXh0U3RhdHVzKSA9PiB7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3VjY2VzczogKHJlc3BvbnNlLCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgIGhhbmRsZUZlZXMocmVzcG9uc2UpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4odGV4dFN0YXR1cywgZXJyb3JUaHJvd24pXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgIH0sIFthY3RpdmVQYXltZW50TWV0aG9kLCBiaWxsaW5nLmNhcnRUb3RhbF0pXG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBjb25zdCBvblByb2Nlc3NpbmdQYXltZW50ID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdG9rZW5WYWwgPSBqUXVlcnkoJy5tb2xsaWUtY29tcG9uZW50cyA+IGlucHV0JykudmFsKClcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogcmVzcG9uc2VUeXBlcy5TVUNDRVNTLFxuICAgICAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bWVudE1ldGhvZERhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheW1lbnRfbWV0aG9kOiBhY3RpdmVQYXltZW50TWV0aG9kLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF5bWVudF9tZXRob2RfdGl0bGU6IGl0ZW0udGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBbaXNzdWVyS2V5XTogc2VsZWN0ZWRJc3N1ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBiaWxsaW5nX3Bob25lOiBpbnB1dFBob25lLFxuICAgICAgICAgICAgICAgICAgICAgICAgYmlsbGluZ19jb21wYW55X2JpbGxpZTogaW5wdXRDb21wYW55LFxuICAgICAgICAgICAgICAgICAgICAgICAgYmlsbGluZ19iaXJ0aGRhdGU6IGlucHV0QmlydGhkYXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FyZFRva2VuOiB0b2tlblZhbCxcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdW5zdWJzY3JpYmVQYXltZW50UHJvY2Vzc2luZyA9IG9uUGF5bWVudFNldHVwKFxuICAgICAgICAgICAgb25Qcm9jZXNzaW5nUGF5bWVudFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgdW5zdWJzY3JpYmVQYXltZW50UHJvY2Vzc2luZygpXG4gICAgICAgIH07XG5cbiAgICB9LCBbc2VsZWN0ZWRJc3N1ZXIsIG9uUGF5bWVudFNldHVwLCBpbnB1dFBob25lLCBpbnB1dENvbXBhbnksIGlucHV0QmlydGhkYXRlXSlcblxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICAgIGxldCBjb21wYW55TGFiZWwgPSBqUXVlcnkoJ2Rpdi53Yy1ibG9jay1jb21wb25lbnRzLXRleHQtaW5wdXQud2MtYmxvY2stY29tcG9uZW50cy1hZGRyZXNzLWZvcm1fX2NvbXBhbnkgPiBsYWJlbCcpXG4gICAgICAgIGlmIChjb21wYW55TGFiZWwubGVuZ3RoID09PSAwIHx8IGl0ZW0uaGlkZUNvbXBhbnlGaWVsZCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWN0aXZlUGF5bWVudE1ldGhvZCA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2JpbGxpZScpIHtcbiAgICAgICAgICAgIGxldCBtZXNzYWdlID0gaXRlbS5jb21wYW55UGxhY2Vob2xkZXJcbiAgICAgICAgICAgIGNvbXBhbnlMYWJlbC5yZXBsYWNlV2l0aCgnPGxhYmVsIGh0bWxGb3I9XCJzaGlwcGluZy1jb21wYW55XCI+JyArIG1lc3NhZ2UgKyAnPC9sYWJlbD4nKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNvbXBhbnlOYW1lU3RyaW5nICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGNvbXBhbnlMYWJlbC5yZXBsYWNlV2l0aCgnPGxhYmVsIGh0bWxGb3I9XCJzaGlwcGluZy1jb21wYW55XCI+JyArIGNvbXBhbnlOYW1lU3RyaW5nICsgJzwvbGFiZWw+JylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgaXNDb21wYW55RW1wdHkgPSAoYmlsbGluZy5iaWxsaW5nRGF0YS5jb21wYW55ID09PSAnJyAmJiBzaGlwcGluZ0RhdGEuc2hpcHBpbmdBZGRyZXNzLmNvbXBhbnkgPT09ICcnKSAmJiBpbnB1dENvbXBhbnkgPT09ICcnO1xuICAgICAgICBjb25zdCB1bnN1YnNjcmliZVByb2Nlc3NpbmcgPSBvbkNoZWNrb3V0VmFsaWRhdGlvbihcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYWN0aXZlUGF5bWVudE1ldGhvZCA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2JpbGxpZScgJiYgaXNDb21wYW55RW1wdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZTogaXRlbS5lcnJvck1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgdW5zdWJzY3JpYmVQcm9jZXNzaW5nKClcbiAgICAgICAgfTtcblxuICAgIH0sIFthY3RpdmVQYXltZW50TWV0aG9kLCBvbkNoZWNrb3V0VmFsaWRhdGlvbiwgYmlsbGluZy5iaWxsaW5nRGF0YSwgaXRlbSwgY29tcGFueU5hbWVTdHJpbmcsIGlucHV0Q29tcGFueV0pO1xuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgbGV0IHBob25lTGFiZWwgPSBnZXRQaG9uZUZpZWxkKCk/LmxhYmVscz8uWzBdID8/IG51bGw7XG4gICAgICAgIGlmICghcGhvbmVMYWJlbCB8fCBwaG9uZUxhYmVsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFjdGl2ZVBheW1lbnRNZXRob2QgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9pbjMnKSB7XG4gICAgICAgICAgICBwaG9uZUxhYmVsLmlubmVyVGV4dCA9IGl0ZW0ucGhvbmVQbGFjZWhvbGRlclxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHBob25lU3RyaW5nICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHBob25lTGFiZWwuaW5uZXJUZXh0ID0gcGhvbmVTdHJpbmdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgaXNQaG9uZUVtcHR5ID0gKGJpbGxpbmcuYmlsbGluZ0RhdGEucGhvbmUgPT09ICcnICYmIHNoaXBwaW5nRGF0YS5zaGlwcGluZ0FkZHJlc3MucGhvbmUgPT09ICcnKSAmJiBpbnB1dFBob25lID09PSAnJztcbiAgICAgICAgbGV0IGlzQmlydGhkYXRlVmFsaWQgPSBpbnB1dEJpcnRoZGF0ZSA9PT0gJydcbiAgICAgICAgbGV0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICAgICAgbGV0IGJpcnRoZGF0ZSA9IG5ldyBEYXRlKGlucHV0QmlydGhkYXRlKTtcbiAgICAgICAgaWYgKGJpcnRoZGF0ZSA+IHRvZGF5KSB7XG4gICAgICAgICAgICBpc0JpcnRoZGF0ZVZhbGlkID0gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1bnN1YnNjcmliZVByb2Nlc3NpbmcgPSBvbkNoZWNrb3V0VmFsaWRhdGlvbihcblxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhY3RpdmVQYXltZW50TWV0aG9kID09PSAnbW9sbGllX3djX2dhdGV3YXlfaW4zJyAmJiAoaXNQaG9uZUVtcHR5IHx8IGlzQmlydGhkYXRlVmFsaWQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2U6IGl0ZW0uZXJyb3JNZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlUHJvY2Vzc2luZygpXG4gICAgICAgIH07XG5cbiAgICB9LCBbYWN0aXZlUGF5bWVudE1ldGhvZCwgb25DaGVja291dFZhbGlkYXRpb24sIGJpbGxpbmcuYmlsbGluZ0RhdGEsIHNoaXBwaW5nRGF0YS5zaGlwcGluZ0FkZHJlc3MsIGl0ZW0sIHBob25lU3RyaW5nLCBpbnB1dEJpcnRoZGF0ZSwgaW5wdXRQaG9uZV0pO1xuXG4gICAgb25TdWJtaXRMb2NhbCA9IG9uU3VibWl0XG4gICAgY29uc3QgdXBkYXRlSXNzdWVyID0gKGUpID0+IHNlbGVjdElzc3VlcihlLnRhcmdldC52YWx1ZSk7XG4gICAgY29uc3QgdXBkYXRlQ29tcGFueSA9IChlKSA9PiBzZWxlY3RDb21wYW55KGUudGFyZ2V0LnZhbHVlKTtcbiAgICBjb25zdCB1cGRhdGVQaG9uZSA9IChlKSA9PiBzZWxlY3RQaG9uZShlLnRhcmdldC52YWx1ZSk7XG4gICAgY29uc3QgdXBkYXRlQmlydGhkYXRlID0gKGUpID0+IHNlbGVjdEJpcnRoZGF0ZSggZS50YXJnZXQudmFsdWUgKTtcblxuICAgIGZ1bmN0aW9uIGZpZWxkTWFya3VwKGlkLCBmaWVsZFR5cGUsIGxhYmVsLCBhY3Rpb24sIHZhbHVlLCBwbGFjZWhvbGRlciA9IG51bGwpIHtcbiAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gXCJ3Yy1ibG9jay1jb21wb25lbnRzLXRleHQtaW5wdXQgd2MtYmxvY2stY29tcG9uZW50cy1hZGRyZXNzLWZvcm1fX1wiICsgaWQ7XG4gICAgICAgIHJldHVybiA8ZGl2IGNsYXNzPVwiY3VzdG9tLWlucHV0XCI+XG4gICAgICAgICAgICA8bGFiZWwgaHRtbEZvcj17aWR9IGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MPXt7X19odG1sOiBsYWJlbH19PjwvbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT17ZmllbGRUeXBlfSBuYW1lPXtpZH0gaWQ9e2lkfSB2YWx1ZT17dmFsdWV9IG9uQ2hhbmdlPXthY3Rpb259IHBsYWNlaG9sZGVyPXtwbGFjZWhvbGRlcn0+PC9pbnB1dD5cbiAgICAgICAgPC9kaXY+XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0uaXNzdWVycyAmJiBpdGVtLm5hbWUgIT09IFwibW9sbGllX3djX2dhdGV3YXlfY3JlZGl0Y2FyZFwiKXtcbiAgICAgICAgcmV0dXJuIDxkaXY+PHA+e2l0ZW0uY29udGVudH08L3A+PHNlbGVjdCBuYW1lPXtpc3N1ZXJLZXl9IGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MPXsge19faHRtbDogaXRlbS5pc3N1ZXJzfSB9IHZhbHVlPXtzZWxlY3RlZElzc3Vlcn0gb25DaGFuZ2U9e3VwZGF0ZUlzc3Vlcn0+PC9zZWxlY3Q+PC9kaXY+XG4gICAgfVxuXG4gICAgaWYoaXRlbS5uYW1lID09PSBcIm1vbGxpZV93Y19nYXRld2F5X2NyZWRpdGNhcmRcIil7XG4gICAgICAgIHJldHVybiA8ZGl2IGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MPXsge19faHRtbDogaXRlbS5jb250ZW50fSB9PjwvZGl2PjtcbiAgICB9XG5cbiAgICBpZiAoaXRlbS5uYW1lID09PSBcIm1vbGxpZV93Y19nYXRld2F5X2JpbGxpZVwiKSB7XG4gICAgICAgIGNvbnN0IGJpbGxpbmdDb21wYW55RmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZy1jb21wYW55Jyk7XG4gICAgICAgIGNvbnN0IHNoaXBwaW5nQ29tcGFueUZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3NoaXBwaW5nLWNvbXBhbnknKTtcbiAgICAgICAgY29uc3QgaXNCaWxsaW5nQ29tcGFueVJlcXVpcmVkID0gYmlsbGluZ0NvbXBhbnlGaWVsZD8uaGFzQXR0cmlidXRlKCdyZXF1aXJlZCcpO1xuICAgICAgICBjb25zdCBpc1NoaXBwaW5nQ29tcGFueVJlcXVpcmVkID0gc2hpcHBpbmdDb21wYW55RmllbGQ/Lmhhc0F0dHJpYnV0ZSgncmVxdWlyZWQnKTtcblxuICAgICAgICBpZiAoKGJpbGxpbmdDb21wYW55RmllbGQgJiYgaXNCaWxsaW5nQ29tcGFueVJlcXVpcmVkKSB8fCAoc2hpcHBpbmdDb21wYW55RmllbGQgJiYgaXNTaGlwcGluZ0NvbXBhbnlSZXF1aXJlZCkgfHwgaXRlbS5oaWRlQ29tcGFueUZpZWxkID09PSB0cnVlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb21wYW55RmllbGQgPSBpdGVtLmNvbXBhbnlQbGFjZWhvbGRlciA/IGl0ZW0uY29tcGFueVBsYWNlaG9sZGVyIDogXCJDb21wYW55IG5hbWVcIjtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgPGRpdj48cD57aXRlbS5jb250ZW50fTwvcD48L2Rpdj5cbiAgICAgICAgICAgICAgICB7ZmllbGRNYXJrdXAoXCJiaWxsaW5nX2NvbXBhbnlfYmlsbGllXCIsXCJ0ZXh0XCIsIGNvbXBhbnlGaWVsZCwgdXBkYXRlQ29tcGFueSwgaW5wdXRDb21wYW55KX1cbiAgICAgICAgICAgIDwvPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvdW50cnlDb2RlcyA9IHtcbiAgICAgICAgICAgIEJFOiAnKzMyeHh4eHh4eHh4JyxcbiAgICAgICAgICAgIE5MOiAnKzMxNnh4eHh4eHh4JyxcbiAgICAgICAgICAgIERFOiAnKzQ5eHh4eHh4eHh4JyxcbiAgICAgICAgICAgIEFUOiAnKzQzeHh4eHh4eHh4JyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY291bnRyeSA9IGJpbGxpbmcuYmlsbGluZ0RhdGEuY291bnRyeTtcbiAgICAgICAgaXRlbS5waG9uZVBsYWNlaG9sZGVyID0gY291bnRyeUNvZGVzW2NvdW50cnldIHx8IGNvdW50cnlDb2Rlc1snTkwnXTtcbiAgICB9LCBbYmlsbGluZy5iaWxsaW5nRGF0YS5jb3VudHJ5XSk7XG5cbiAgICBpZiAoaXRlbS5uYW1lID09PSBcIm1vbGxpZV93Y19nYXRld2F5X2luM1wiKSB7XG4gICAgICAgIGNvbnN0IGJpcnRoZGF0ZUZpZWxkID0gaXRlbS5iaXJ0aGRhdGVQbGFjZWhvbGRlciB8fCBcIkJpcnRoZGF0ZVwiO1xuICAgICAgICBjb25zdCBwaG9uZUZpZWxkID0gaXRlbS5waG9uZVBsYWNlaG9sZGVyIHx8IFwiKzMxNnh4eHh4eHh4XCI7XG4gICAgICAgIGNvbnN0IHBob25lTGFiZWwgPSBpdGVtLnBob25lTGFiZWwgfHwgXCJQaG9uZVwiO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICA8ZGl2PjxwPntpdGVtLmNvbnRlbnR9PC9wPjwvZGl2PlxuICAgICAgICAgICAgICAgIHtmaWVsZE1hcmt1cChcImJpbGxpbmctYmlydGhkYXRlXCIsIFwiZGF0ZVwiLCBiaXJ0aGRhdGVGaWVsZCwgdXBkYXRlQmlydGhkYXRlLCBpbnB1dEJpcnRoZGF0ZSl9XG4gICAgICAgICAgICAgICAgeyFpc1Bob25lRmllbGRWaXNpYmxlICYmIGZpZWxkTWFya3VwKFwiYmlsbGluZy1waG9uZS1pbjNcIiwgXCJ0ZWxcIiwgcGhvbmVMYWJlbCwgdXBkYXRlUGhvbmUsIGlucHV0UGhvbmUsIHBob25lRmllbGQpfVxuICAgICAgICAgICAgPC8+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0ubmFtZSA9PT0gXCJtb2xsaWVfd2NfZ2F0ZXdheV9yaXZlcnR5XCIpIHtcbiAgICAgICAgY29uc3QgYmlydGhkYXRlRmllbGQgPSBpdGVtLmJpcnRoZGF0ZVBsYWNlaG9sZGVyIHx8IFwiQmlydGhkYXRlXCI7XG4gICAgICAgIGNvbnN0IHBob25lRmllbGQgPSBpdGVtLnBob25lUGxhY2Vob2xkZXIgfHwgXCIrMzE2eHh4eHh4eHhcIjtcbiAgICAgICAgY29uc3QgcGhvbmVMYWJlbCA9IGl0ZW0ucGhvbmVMYWJlbCB8fCBcIlBob25lXCI7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIDxkaXY+PHA+e2l0ZW0uY29udGVudH08L3A+PC9kaXY+XG4gICAgICAgICAgICAgICAge2ZpZWxkTWFya3VwKFwiYmlsbGluZy1iaXJ0aGRhdGVcIiwgXCJkYXRlXCIsIGJpcnRoZGF0ZUZpZWxkLCB1cGRhdGVCaXJ0aGRhdGUsIGlucHV0QmlydGhkYXRlKX1cbiAgICAgICAgICAgICAgICB7IWlzUGhvbmVGaWVsZFZpc2libGUgJiYgZmllbGRNYXJrdXAoXCJiaWxsaW5nLXBob25lLXJpdmVydHlcIiwgXCJ0ZWxcIiwgcGhvbmVMYWJlbCwgdXBkYXRlUGhvbmUsIGlucHV0UGhvbmUsIHBob25lRmllbGQpfVxuICAgICAgICAgICAgPC8+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIDxkaXY+PHA+e2l0ZW0uY29udGVudH08L3A+PC9kaXY+XG59XG5cbmNvbnN0IExhYmVsID0gKHsgaXRlbSwgZmlsdGVycywgYWpheFVybCwgalF1ZXJ5IH0pID0+IHtcbiAgICBjb25zdCBjYXJ0RGF0YSA9IHdwLmRhdGEudXNlU2VsZWN0KChzZWxlY3QpID0+XG4gICAgICAgICAgICBzZWxlY3QoJ3djL3N0b3JlL2NhcnQnKS5nZXRDYXJ0RGF0YSgpLFxuICAgICAgICBbXVxuICAgICk7XG4gICAgY29uc3QgY2FydFRvdGFscyA9IHdwLmRhdGEudXNlU2VsZWN0KCAoc2VsZWN0KSA9PiBzZWxlY3QoJ3djL3N0b3JlL2NhcnQnKS5nZXRDYXJ0VG90YWxzKCksIFsgXSApO1xuICAgIGNvbnN0IGNhcnRUb3RhbCA9IGNhcnRUb3RhbHM/LnRvdGFsX3ByaWNlIHx8IDA7XG4gICAgcmV0dXJuIChcbiAgICAgICAgPD5cbiAgICAgICAgICAgIDxkaXYgZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw9e3sgX19odG1sOiBpdGVtLmxhYmVsIH19Lz5cbiAgICAgICAgICAgIDxNb2xsaWVHYXRld2F5VXBkYXRlclxuICAgICAgICAgICAgICAgIGJpbGxpbmc9e2NhcnREYXRhLmJpbGxpbmdBZGRyZXNzfVxuICAgICAgICAgICAgICAgIGN1cnJlbmN5Q29kZT17d2NTZXR0aW5ncy5jdXJyZW5jeS5jb2RlfVxuICAgICAgICAgICAgICAgIGZpbHRlcnM9e2ZpbHRlcnN9XG4gICAgICAgICAgICAgICAgYWpheFVybD17YWpheFVybH1cbiAgICAgICAgICAgICAgICBqUXVlcnk9e2pRdWVyeX1cbiAgICAgICAgICAgICAgICBpdGVtPXtpdGVtfVxuICAgICAgICAgICAgICAgIGNhcnRUb3RhbD17Y2FydFRvdGFsfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC8+XG4gICAgKTtcbn07XG5cbmNvbnN0IG1vbGxpZVBheW1lbnRNZXRob2QgPSAodXNlRWZmZWN0LCBhamF4VXJsLCBmaWx0ZXJzLCBnYXRld2F5RGF0YSwgYXZhaWxhYmxlR2F0ZXdheXMsIGl0ZW0sIGpRdWVyeSwgcmVxdWlyZWRGaWVsZHMsIGlzQ29tcGFueUZpZWxkVmlzaWJsZSwgaXNQaG9uZUZpZWxkVmlzaWJsZSkgPT57XG5cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb2xsaWVfY29tcG9uZW50c19yZWFkeV90b19zdWJtaXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG9uU3VibWl0TG9jYWwoKVxuICAgIH0pXG4gICAgZnVuY3Rpb24gY3JlZGl0Y2FyZFNlbGVjdGVkRXZlbnQoKSB7XG4gICAgICAgIGlmIChpdGVtLm5hbWUgPT09IFwibW9sbGllX3djX2dhdGV3YXlfY3JlZGl0Y2FyZFwiKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGlzcGF0Y2hFdmVudChjcmVkaXRDYXJkU2VsZWN0ZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gT24gZmlyc3QgbG9hZCwgaWYgYXZhaWxhYmxlR2F0ZXdheXMgaXMgbm90IGVtcHR5LCBzdG9yZSBpdFxuICAgIGlmIChfLmlzRW1wdHkoY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMpICYmICFfLmlzRW1wdHkoYXZhaWxhYmxlR2F0ZXdheXMpKSB7XG4gICAgICAgIGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzID0gYXZhaWxhYmxlR2F0ZXdheXM7XG4gICAgICAgIHNhdmVDYWNoZWRBdmFpbGFibGVHYXRld2F5cygpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBuYW1lOiBpdGVtLm5hbWUsXG4gICAgICAgIGxhYmVsOjxMYWJlbFxuICAgICAgICAgICAgaXRlbT17aXRlbX1cbiAgICAgICAgICAgIGFqYXhVcmw9e2FqYXhVcmx9XG4gICAgICAgICAgICBqUXVlcnk9e2pRdWVyeX1cbiAgICAgICAgICAgIGZpbHRlcnM9e2ZpbHRlcnN9XG4gICAgICAgIC8+LFxuICAgICAgICBjb250ZW50OiA8TW9sbGllQ29tcG9uZW50XG4gICAgICAgICAgICBpdGVtPXtpdGVtfVxuICAgICAgICAgICAgdXNlRWZmZWN0PXt1c2VFZmZlY3R9XG4gICAgICAgICAgICBhamF4VXJsPXthamF4VXJsfVxuICAgICAgICAgICAgalF1ZXJ5PXtqUXVlcnl9XG4gICAgICAgICAgICByZXF1aXJlZEZpZWxkcz17cmVxdWlyZWRGaWVsZHN9XG4gICAgICAgICAgICBpc1Bob25lRmllbGRWaXNpYmxlPXtpc1Bob25lRmllbGRWaXNpYmxlfS8+LFxuICAgICAgICBlZGl0OiA8ZGl2PntpdGVtLmVkaXR9PC9kaXY+LFxuICAgICAgICBwYXltZW50TWV0aG9kSWQ6IGl0ZW0ucGF5bWVudE1ldGhvZElkLFxuICAgICAgICBjYW5NYWtlUGF5bWVudDogKHtjYXJ0VG90YWxzLCBiaWxsaW5nRGF0YX0pID0+IHtcbiAgICAgICAgICAgIGlmICghXy5pc0VtcHR5KGl0ZW0uYWxsb3dlZENvdW50cmllcykgJiYgIShpdGVtLmFsbG93ZWRDb3VudHJpZXMuaW5jbHVkZXMoYmlsbGluZ0RhdGEuY291bnRyeSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY2FydFRvdGFscyA8PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvYWRDYWNoZWRBdmFpbGFibGVHYXRld2F5cygpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVuY3lDb2RlID0gY2FydFRvdGFscz8uY3VycmVuY3lfY29kZTtcbiAgICAgICAgICAgIGxldCBjb3VudHJ5ID0gYmlsbGluZ0RhdGE/LmNvdW50cnk7XG4gICAgICAgICAgICBpZiAoIWNvdW50cnkpIHtcbiAgICAgICAgICAgICAgICBjb3VudHJ5ID0gd2NTZXR0aW5ncz8uYmFzZUxvY2F0aW9uLmNvdW50cnk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RmlsdGVyS2V5ID0gY3VycmVuY3lDb2RlICsgXCItXCIgKyBjb3VudHJ5O1xuXG4gICAgICAgICAgICBjcmVkaXRjYXJkU2VsZWN0ZWRFdmVudCgpO1xuICAgICAgICAgICAgaWYgKCFjYWNoZWRBdmFpbGFibGVHYXRld2F5cy5oYXNPd25Qcm9wZXJ0eShjdXJyZW50RmlsdGVyS2V5KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzW2N1cnJlbnRGaWx0ZXJLZXldLmhhc093blByb3BlcnR5KGl0ZW0ubmFtZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGFyaWFMYWJlbDogaXRlbS5hcmlhTGFiZWwsXG4gICAgICAgIHN1cHBvcnRzOiB7XG4gICAgICAgICAgICBmZWF0dXJlczogaXRlbS5zdXBwb3J0cyxcbiAgICAgICAgfSxcbiAgICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBtb2xsaWVQYXltZW50TWV0aG9kXG5cbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuXHRcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiaW1wb3J0IG1vbGxpZVBheW1lbnRNZXRob2QgZnJvbSAnLi9ibG9ja3MvbW9sbGllUGF5bWVudE1ldGhvZCdcbmltcG9ydCBBcHBsZVBheUJ1dHRvbkNvbXBvbmVudCBmcm9tICcuL2Jsb2Nrcy9BcHBsZVBheUJ1dHRvbkNvbXBvbmVudCdcbmltcG9ydCBBcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCBmcm9tICcuL2Jsb2Nrcy9BcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCdcblxuKFxuICAgIGZ1bmN0aW9uICh7bW9sbGllQmxvY2tEYXRhLCB3YywgXywgalF1ZXJ5fSkge1xuICAgICAgICBpZiAoXy5pc0VtcHR5KG1vbGxpZUJsb2NrRGF0YSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHtyZWdpc3RlclBheW1lbnRNZXRob2R9ID0gd2Mud2NCbG9ja3NSZWdpc3RyeTtcbiAgICAgICAgY29uc3Qge2RlZmF1bHRGaWVsZHN9ID0gd2Mud2NTZXR0aW5ncy5hbGxTZXR0aW5ncztcbiAgICAgICAgY29uc3Qge2FqYXhVcmwsIGZpbHRlcnMsIGdhdGV3YXlEYXRhLCBhdmFpbGFibGVHYXRld2F5c30gPSBtb2xsaWVCbG9ja0RhdGEuZ2F0ZXdheURhdGE7XG4gICAgICAgIGNvbnN0IHt1c2VFZmZlY3R9ID0gd3AuZWxlbWVudDtcbiAgICAgICAgY29uc3QgaXNBcHBsZVNlc3Npb24gPSB0eXBlb2Ygd2luZG93LkFwcGxlUGF5U2Vzc2lvbiA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdjYWNoZWRBdmFpbGFibGVHYXRld2F5cycpO1xuXG4gICAgICAgIGZ1bmN0aW9uIGdldFBob25lRmllbGQoKSB7XG4gICAgICAgICAgICBjb25zdCBwaG9uZUZpZWxkRGF0YXNldCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tkYXRhLXNob3ctcGhvbmUtZmllbGRdJyk7XG4gICAgICAgICAgICBpZiAoIXBob25lRmllbGREYXRhc2V0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGhvbmVGaWVsZERhdGFzZXQuZGF0YXNldC5zaG93UGhvbmVGaWVsZCAhPT0gXCJmYWxzZVwiXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb21wYW55TmFtZVN0cmluZyA9IGRlZmF1bHRGaWVsZHMuY29tcGFueS5sYWJlbFxuICAgICAgICBjb25zdCBpc1Bob25lRmllbGRWaXNpYmxlID0gZ2V0UGhvbmVGaWVsZCgpO1xuICAgICAgICBjb25zdCBwaG9uZVN0cmluZyA9IGRlZmF1bHRGaWVsZHMucGhvbmUubGFiZWxcbiAgICAgICAgbGV0IHJlcXVpcmVkRmllbGRzID0ge1xuICAgICAgICAgICAgJ2NvbXBhbnlOYW1lU3RyaW5nJzogY29tcGFueU5hbWVTdHJpbmcsXG4gICAgICAgICAgICAncGhvbmVTdHJpbmcnOiBwaG9uZVN0cmluZyxcbiAgICAgICAgfVxuICAgICAgICBnYXRld2F5RGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgbGV0IHJlZ2lzdGVyID0gKCkgPT4gcmVnaXN0ZXJQYXltZW50TWV0aG9kKG1vbGxpZVBheW1lbnRNZXRob2QodXNlRWZmZWN0LCBhamF4VXJsLCBmaWx0ZXJzLCBnYXRld2F5RGF0YSwgYXZhaWxhYmxlR2F0ZXdheXMsIGl0ZW0sIGpRdWVyeSwgcmVxdWlyZWRGaWVsZHMsIGlzUGhvbmVGaWVsZFZpc2libGUpKTtcbiAgICAgICAgICAgIGlmIChpdGVtLm5hbWUgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheScpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7aXNFeHByZXNzRW5hYmxlZH0gPSBpdGVtO1xuICAgICAgICAgICAgICAgIGlmICgoaXNBcHBsZVNlc3Npb24gJiYgd2luZG93LkFwcGxlUGF5U2Vzc2lvbi5jYW5NYWtlUGF5bWVudHMoKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRXhwcmVzc0VuYWJsZWQgIT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCB7cmVnaXN0ZXJFeHByZXNzUGF5bWVudE1ldGhvZH0gPSB3Yy53Y0Jsb2Nrc1JlZ2lzdHJ5O1xuICAgICAgICAgICAgICAgICAgICByZWdpc3RlckV4cHJlc3NQYXltZW50TWV0aG9kKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheV9leHByZXNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnQXBwbGUgUGF5IEV4cHJlc3MgYnV0dG9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQXBwbGUgUGF5IEV4cHJlc3MgYnV0dG9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IDxBcHBsZVBheUJ1dHRvbkNvbXBvbmVudC8+LFxuICAgICAgICAgICAgICAgICAgICAgICAgZWRpdDogPEFwcGxlUGF5QnV0dG9uRWRpdG9yQ29tcG9uZW50Lz4sXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmlhTGFiZWw6ICdBcHBsZSBQYXknLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FuTWFrZVBheW1lbnQ6ICgpID0+IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXltZW50TWV0aG9kSWQ6ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheScsXG4gICAgICAgICAgICAgICAgICAgICAgICBnYXRld2F5SWQ6ICdtb2xsaWVfd2NfZ2F0ZXdheV9hcHBsZXBheScsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0czoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzOiBbJ3Byb2R1Y3RzJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IFsnaGVpZ2h0JywgJ2JvcmRlclJhZGl1cyddXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWdpc3RlcigpO1xuICAgICAgICB9KTtcbiAgICB9XG4pKHdpbmRvdywgd2MpXG4iXSwibmFtZXMiOlsiY3JlYXRlQXBwbGVFcnJvcnMiLCJlcnJvcnMiLCJlcnJvckxpc3QiLCJfaXRlcmF0b3IiLCJfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlciIsIl9zdGVwIiwicyIsIm4iLCJkb25lIiwiZXJyb3IiLCJ2YWx1ZSIsIl9lcnJvciRjb250YWN0RmllbGQiLCJjb250YWN0RmllbGQiLCJfZXJyb3IkY29kZSIsImNvZGUiLCJfZXJyb3IkbWVzc2FnZSIsIm1lc3NhZ2UiLCJhcHBsZUVycm9yIiwiQXBwbGVQYXlFcnJvciIsInB1c2giLCJlcnIiLCJlIiwiZiIsInJlcXVlc3QiLCJjb3VudHJ5Q29kZSIsImN1cnJlbmN5Q29kZSIsInRvdGFsTGFiZWwiLCJzdWJ0b3RhbCIsInN1cHBvcnRlZE5ldHdvcmtzIiwibWVyY2hhbnRDYXBhYmlsaXRpZXMiLCJzaGlwcGluZ1R5cGUiLCJyZXF1aXJlZEJpbGxpbmdDb250YWN0RmllbGRzIiwicmVxdWlyZWRTaGlwcGluZ0NvbnRhY3RGaWVsZHMiLCJ0b3RhbCIsImxhYmVsIiwiYW1vdW50IiwidHlwZSIsIkFwcGxlUGF5QnV0dG9uQ29tcG9uZW50IiwiX3JlZiIsIl9yZWYkYnV0dG9uQXR0cmlidXRlcyIsImJ1dHRvbkF0dHJpYnV0ZXMiLCJtb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnQiLCJ3aW5kb3ciLCJtb2xsaWVCbG9ja0RhdGEiLCJub25jZSIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJ1cGRhdGVkQ29udGFjdEluZm8iLCJyZWRpcmVjdGlvblVybCIsIl9tb2xsaWVBcHBsZVBheUJsb2NrRCIsInByb2R1Y3QiLCJfbW9sbGllQXBwbGVQYXlCbG9ja0QyIiwibmVlZFNoaXBwaW5nIiwiX21vbGxpZUFwcGxlUGF5QmxvY2tEMyIsInNob3AiLCJfbW9sbGllQXBwbGVQYXlCbG9ja0Q0IiwiX21vbGxpZUFwcGxlUGF5QmxvY2tENSIsImFqYXhVcmwiLCJzdHlsZSIsImhlaWdodCIsImNvbmNhdCIsImJvcmRlclJhZGl1cyIsImZpbmRTZWxlY3RlZFNoaXBwaW5nTWV0aG9kIiwic2hpcHBpbmdSYXRlcyIsInNoaXBwaW5nUmF0ZSIsImZpbmQiLCJzaGlwcGluZ01ldGhvZCIsInNlbGVjdGVkIiwiYXBwbGVGb3JtYXR0ZWRSYXRlIiwiZGV0YWlsIiwibmFtZSIsImlkZW50aWZpZXIiLCJyYXRlX2lkIiwiYXBwbGVQYXlTZXNzaW9uIiwiX3N0b3JlJGdldFNoaXBwaW5nUmF0Iiwic2Vzc2lvbiIsIkFwcGxlUGF5U2Vzc2lvbiIsInN0b3JlIiwid3AiLCJkYXRhIiwic2VsZWN0IiwiZ2V0U2hpcHBpbmdSYXRlcyIsInNoaXBwaW5nX3JhdGVzIiwic2VsZWN0ZWRTaGlwcGluZ01ldGhvZCIsImxlbmd0aCIsIm9uc2hpcHBpbmdtZXRob2RzZWxlY3RlZCIsImV2ZW50IiwiX3RoaXMiLCJqUXVlcnkiLCJhamF4IiwidXJsIiwibWV0aG9kIiwiYWN0aW9uIiwiY2FsbGVyUGFnZSIsInNpbXBsaWZpZWRDb250YWN0Iiwic3VjY2VzcyIsImFwcGxlUGF5U2hpcHBpbmdNZXRob2RVcGRhdGUiLCJ0ZXh0U3RhdHVzIiwianFYSFIiLCJyZXNwb25zZSIsImNvbXBsZXRlU2hpcHBpbmdNZXRob2RTZWxlY3Rpb24iLCJlcnJvclRocm93biIsImNvbnNvbGUiLCJ3YXJuIiwiYWJvcnQiLCJvbnNoaXBwaW5nY29udGFjdHNlbGVjdGVkIiwiX3RoaXMyIiwic2hpcHBpbmdDb250YWN0IiwiYXBwbGVQYXlTaGlwcGluZ0NvbnRhY3RVcGRhdGUiLCJuZXdTaGlwcGluZ01ldGhvZHMiLCJjb21wbGV0ZVNoaXBwaW5nQ29udGFjdFNlbGVjdGlvbiIsIm9udmFsaWRhdGVtZXJjaGFudCIsImFwcGxlUGF5VmFsaWRhdGVNZXJjaGFudEV2ZW50IiwidmFsaWRhdGlvblVybCIsInZhbGlkYXRpb25VUkwiLCJtZXJjaGFudFNlc3Npb24iLCJjb21wbGV0ZU1lcmNoYW50VmFsaWRhdGlvbiIsIkpTT04iLCJwYXJzZSIsIm9ucGF5bWVudGF1dGhvcml6ZWQiLCJBcHBsZVBheVBheW1lbnQiLCJfQXBwbGVQYXlQYXltZW50JHBheW0iLCJwYXltZW50IiwiYmlsbGluZ0NvbnRhY3QiLCJ0b2tlbiIsImdpdmVuTmFtZSIsImZhbWlseU5hbWUiLCJhZGRyZXNzTGluZXMiLCJwb3N0YWxDb2RlIiwibG9jYWxpdHkiLCJhZG1pbmlzdHJhdGl2ZUFyZWEiLCJwaG9uZU51bWJlciIsImVtYWlsQWRkcmVzcyIsImF1dGhvcml6YXRpb25SZXN1bHQiLCJyZXN1bHQiLCJjb21wbGV0ZVBheW1lbnQiLCJsb2NhdGlvbiIsImhyZWYiLCJiZWdpbiIsIlJlYWN0IiwiY3JlYXRlRWxlbWVudCIsImlkIiwiY2xhc3NOYW1lIiwib25DbGljayIsInByZXZlbnREZWZhdWx0IiwiQXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQiLCJjYWNoZWRBdmFpbGFibGVHYXRld2F5cyIsImZvcm1hdFByaWNlTGlrZVdjIiwicHJpY2UiLCJ3Y1NldHRpbmdzIiwiY3VycmVuY3kiLCJwcmljZUZvcm1hdCIsInJlcGxhY2UiLCJzeW1ib2wiLCJ0b0ZpeGVkIiwicHJlY2lzaW9uIiwiZGVjaW1hbFNlcGFyYXRvciIsImxvYWRDYWNoZWRBdmFpbGFibGVHYXRld2F5cyIsInN0b3JlZERhdGEiLCJsb2NhbFN0b3JhZ2UiLCJnZXRJdGVtIiwic2F2ZUNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzIiwic2V0SXRlbSIsInN0cmluZ2lmeSIsInNldEF2YWlsYWJsZUdhdGV3YXlzIiwiY291bnRyeSIsIl9vYmplY3RTcHJlYWQiLCJ1c2VNb2xsaWVBdmFpbGFibGVHYXRld2F5cyIsImJpbGxpbmciLCJjYXJ0VG90YWwiLCJmaWx0ZXJzIiwiaXRlbSIsIl93Y1NldHRpbmdzIiwiYmFzZUxvY2F0aW9uIiwiZWxlbWVudCIsInVzZUVmZmVjdCIsImN1cnJlbnRGaWx0ZXJLZXkiLCJoYXNPd25Qcm9wZXJ0eSIsImN1cnJlbnRHYXRld2F5IiwiYmlsbGluZ0NvdW50cnkiLCJwYXltZW50TG9jYWxlIiwiY2FydFRvdGFscyIsImdldENhcnRUb3RhbHMiLCJkaXNwYXRjaCIsInNldENhcnREYXRhIiwiTW9sbGllR2F0ZXdheVVwZGF0ZXIiLCJvblN1Ym1pdExvY2FsIiwiYWN0aXZlUGF5bWVudE1ldGhvZExvY2FsIiwiY3JlZGl0Q2FyZFNlbGVjdGVkIiwiRXZlbnQiLCJidWJibGVzIiwiTW9sbGllQ29tcG9uZW50IiwicHJvcHMiLCJvblN1Ym1pdCIsImFjdGl2ZVBheW1lbnRNZXRob2QiLCJlbWl0UmVzcG9uc2UiLCJldmVudFJlZ2lzdHJhdGlvbiIsInJlcXVpcmVkRmllbGRzIiwic2hpcHBpbmdEYXRhIiwiaXNQaG9uZUZpZWxkVmlzaWJsZSIsInJlc3BvbnNlVHlwZXMiLCJvblBheW1lbnRTZXR1cCIsIm9uQ2hlY2tvdXRWYWxpZGF0aW9uIiwiX3dwJGVsZW1lbnQkdXNlU3RhdGUiLCJ1c2VTdGF0ZSIsIl93cCRlbGVtZW50JHVzZVN0YXRlMiIsIl9zbGljZWRUb0FycmF5Iiwic2VsZWN0ZWRJc3N1ZXIiLCJzZWxlY3RJc3N1ZXIiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTMiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTQiLCJpbnB1dFBob25lIiwic2VsZWN0UGhvbmUiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTUiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTYiLCJpbnB1dEJpcnRoZGF0ZSIsInNlbGVjdEJpcnRoZGF0ZSIsIl93cCRlbGVtZW50JHVzZVN0YXRlNyIsIl93cCRlbGVtZW50JHVzZVN0YXRlOCIsImlucHV0Q29tcGFueSIsInNlbGVjdENvbXBhbnkiLCJpc3N1ZXJLZXkiLCJjb21wYW55TmFtZVN0cmluZyIsInBob25lU3RyaW5nIiwiZ2V0UGhvbmVGaWVsZCIsInNoaXBwaW5nUGhvbmUiLCJiaWxsaW5nUGhvbmUiLCJ1cGRhdGVUb3RhbExhYmVsIiwibmV3VG90YWwiLCJ0b3RhbFNwYW4iLCJyZXBsYWNlV2l0aCIsInVwZGF0ZVRheGVzTGFiZWwiLCJoaWRlRmVlIiwiZmVlIiwiaGlkZSIsInRvdGFsVGF4IiwiZmVlTWFya3VwIiwicmVwbGFjZUZlZSIsIm5ld0ZlZSIsImluc2VydE5ld0ZlZSIsImFmdGVyIiwiaGFuZGxlRmVlcyIsImRvY3VtZW50RWxlbWVudCIsImRpc3BhdGNoRXZlbnQiLCJjb21wbGV0ZSIsIm9uUHJvY2Vzc2luZ1BheW1lbnQiLCJ0b2tlblZhbCIsInZhbCIsIlNVQ0NFU1MiLCJtZXRhIiwicGF5bWVudE1ldGhvZERhdGEiLCJfZGVmaW5lUHJvcGVydHkiLCJwYXltZW50X21ldGhvZCIsInBheW1lbnRfbWV0aG9kX3RpdGxlIiwidGl0bGUiLCJ1bnN1YnNjcmliZVBheW1lbnRQcm9jZXNzaW5nIiwiY29tcGFueUxhYmVsIiwiaGlkZUNvbXBhbnlGaWVsZCIsImNvbXBhbnlQbGFjZWhvbGRlciIsImlzQ29tcGFueUVtcHR5IiwiYmlsbGluZ0RhdGEiLCJjb21wYW55Iiwic2hpcHBpbmdBZGRyZXNzIiwidW5zdWJzY3JpYmVQcm9jZXNzaW5nIiwiZXJyb3JNZXNzYWdlIiwiX2dldFBob25lRmllbGQkbGFiZWxzIiwiX2dldFBob25lRmllbGQiLCJwaG9uZUxhYmVsIiwibGFiZWxzIiwiaW5uZXJUZXh0IiwicGhvbmVQbGFjZWhvbGRlciIsImlzUGhvbmVFbXB0eSIsInBob25lIiwiaXNCaXJ0aGRhdGVWYWxpZCIsInRvZGF5IiwiRGF0ZSIsImJpcnRoZGF0ZSIsInVwZGF0ZUlzc3VlciIsInRhcmdldCIsInVwZGF0ZUNvbXBhbnkiLCJ1cGRhdGVQaG9uZSIsInVwZGF0ZUJpcnRoZGF0ZSIsImZpZWxkTWFya3VwIiwiZmllbGRUeXBlIiwicGxhY2Vob2xkZXIiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJjbGFzcyIsImh0bWxGb3IiLCJkYW5nZXJvdXNseVNldElubmVySFRNTCIsIl9faHRtbCIsIm9uQ2hhbmdlIiwiaXNzdWVycyIsImNvbnRlbnQiLCJiaWxsaW5nQ29tcGFueUZpZWxkIiwicXVlcnlTZWxlY3RvciIsInNoaXBwaW5nQ29tcGFueUZpZWxkIiwiaXNCaWxsaW5nQ29tcGFueVJlcXVpcmVkIiwiaGFzQXR0cmlidXRlIiwiaXNTaGlwcGluZ0NvbXBhbnlSZXF1aXJlZCIsImNvbXBhbnlGaWVsZCIsIkZyYWdtZW50IiwiY291bnRyeUNvZGVzIiwiQkUiLCJOTCIsIkRFIiwiQVQiLCJiaXJ0aGRhdGVGaWVsZCIsImJpcnRoZGF0ZVBsYWNlaG9sZGVyIiwicGhvbmVGaWVsZCIsIkxhYmVsIiwiX3JlZjIiLCJjYXJ0RGF0YSIsInVzZVNlbGVjdCIsImdldENhcnREYXRhIiwidG90YWxfcHJpY2UiLCJiaWxsaW5nQWRkcmVzcyIsIm1vbGxpZVBheW1lbnRNZXRob2QiLCJnYXRld2F5RGF0YSIsImF2YWlsYWJsZUdhdGV3YXlzIiwiaXNDb21wYW55RmllbGRWaXNpYmxlIiwiYWRkRXZlbnRMaXN0ZW5lciIsImNyZWRpdGNhcmRTZWxlY3RlZEV2ZW50IiwiXyIsImlzRW1wdHkiLCJlZGl0IiwicGF5bWVudE1ldGhvZElkIiwiY2FuTWFrZVBheW1lbnQiLCJfcmVmMyIsImFsbG93ZWRDb3VudHJpZXMiLCJpbmNsdWRlcyIsImN1cnJlbmN5X2NvZGUiLCJfd2NTZXR0aW5nczIiLCJhcmlhTGFiZWwiLCJzdXBwb3J0cyIsImZlYXR1cmVzIiwid2MiLCJyZWdpc3RlclBheW1lbnRNZXRob2QiLCJ3Y0Jsb2Nrc1JlZ2lzdHJ5IiwiZGVmYXVsdEZpZWxkcyIsImFsbFNldHRpbmdzIiwiX21vbGxpZUJsb2NrRGF0YSRnYXRlIiwiaXNBcHBsZVNlc3Npb24iLCJyZW1vdmVJdGVtIiwicGhvbmVGaWVsZERhdGFzZXQiLCJkYXRhc2V0Iiwic2hvd1Bob25lRmllbGQiLCJmb3JFYWNoIiwicmVnaXN0ZXIiLCJpc0V4cHJlc3NFbmFibGVkIiwiY2FuTWFrZVBheW1lbnRzIiwicmVnaXN0ZXJFeHByZXNzUGF5bWVudE1ldGhvZCIsImRlc2NyaXB0aW9uIiwiZ2F0ZXdheUlkIl0sInNvdXJjZVJvb3QiOiIifQ==894 //# sourceMappingURL=data:application/json;charset=utf-8;base64,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Y0FBYyxJQUFJM1MsTUFBTSxDQUFDa0MsZUFBZSxDQUFDZ1IsZUFBZSxDQUFDLENBQUMsRUFBRztRQUM5REYsUUFBUSxDQUFDLENBQUM7UUFDVixJQUFJQyxnQkFBZ0IsS0FBSyxJQUFJLEVBQUU7VUFDM0I7UUFDSjtRQUNBLElBQU9FLDRCQUE0QixHQUFJZCxFQUFFLENBQUNFLGdCQUFnQixDQUFuRFksNEJBQTRCO1FBQ25DQSw0QkFBNEIsQ0FBQztVQUN6QnZSLElBQUksRUFBRSxvQ0FBb0M7VUFDMUNpTCxLQUFLLEVBQUUsMEJBQTBCO1VBQ2pDdUcsV0FBVyxFQUFFLDBCQUEwQjtVQUN2QzFELE9BQU8sZUFBRXpKLEtBQUEsQ0FBQUMsYUFBQSxDQUFDdkcsdUVBQXVCLE1BQUMsQ0FBQztVQUNuQzZSLElBQUksZUFBRXZMLEtBQUEsQ0FBQUMsYUFBQSxDQUFDSyw2RUFBNkIsTUFBQyxDQUFDO1VBQ3RDMkwsU0FBUyxFQUFFLFdBQVc7VUFDdEJSLGNBQWMsRUFBRSxTQUFBQSxlQUFBO1lBQUEsT0FBTSxJQUFJO1VBQUE7VUFDMUJELGVBQWUsRUFBRSw0QkFBNEI7VUFDN0M0QixTQUFTLEVBQUUsNEJBQTRCO1VBQ3ZDbEIsUUFBUSxFQUFFO1lBQ05DLFFBQVEsRUFBRSxDQUFDLFVBQVUsQ0FBQztZQUN0QnBSLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxjQUFjO1VBQ3BDO1FBQ0osQ0FBQyxDQUFDO01BQ047TUFDQTtJQUNKO0lBQ0FnUyxRQUFRLENBQUMsQ0FBQztFQUNkLENBQUMsQ0FBQztBQUNOLENBQUMsRUFDSGhULE1BQU0sRUFBRXFTLEVBQUUsQ0FBQyxDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS8uL3Jlc291cmNlcy9qcy9hcHBsZVBheUVycm9yLmpzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvYXBwbGVQYXlSZXF1ZXN0LmpzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvYmxvY2tzL0FwcGxlUGF5QnV0dG9uQ29tcG9uZW50LmpzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvYmxvY2tzL0FwcGxlUGF5QnV0dG9uRWRpdG9yQ29tcG9uZW50LmpzIiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvYmxvY2tzL21vbGxpZVBheW1lbnRNZXRob2QuanMiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlL3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly9tb2xsaWUtcGF5bWVudHMtZm9yLXdvb2NvbW1lcmNlL3dlYnBhY2svcnVudGltZS9oYXNPd25Qcm9wZXJ0eSBzaG9ydGhhbmQiLCJ3ZWJwYWNrOi8vbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZS93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2UvLi9yZXNvdXJjZXMvanMvbW9sbGllQmxvY2tJbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gY3JlYXRlQXBwbGVFcnJvcnMoZXJyb3JzKSB7XG4gICAgY29uc3QgZXJyb3JMaXN0ID0gW11cbiAgICBmb3IgKGNvbnN0IGVycm9yIG9mIGVycm9ycykge1xuICAgICAgICBjb25zdCB7Y29udGFjdEZpZWxkID0gbnVsbCwgY29kZSA9IG51bGwsIG1lc3NhZ2UgPSBudWxsfSA9IGVycm9yXG4gICAgICAgIGNvbnN0IGFwcGxlRXJyb3IgPSBjb250YWN0RmllbGQgPyBuZXcgQXBwbGVQYXlFcnJvcihjb2RlLCBjb250YWN0RmllbGQsIG1lc3NhZ2UpIDogbmV3IEFwcGxlUGF5RXJyb3IoY29kZSlcbiAgICAgICAgZXJyb3JMaXN0LnB1c2goYXBwbGVFcnJvcilcbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3JMaXN0XG59XG4iLCJleHBvcnQgY29uc3QgcmVxdWVzdCA9IChjb3VudHJ5Q29kZSwgY3VycmVuY3lDb2RlLCB0b3RhbExhYmVsLCBzdWJ0b3RhbCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvdW50cnlDb2RlOiBjb3VudHJ5Q29kZSxcbiAgICAgICAgY3VycmVuY3lDb2RlOiBjdXJyZW5jeUNvZGUsXG4gICAgICAgIHN1cHBvcnRlZE5ldHdvcmtzOiBbJ2FtZXgnLCAnbWFlc3RybycsICdtYXN0ZXJDYXJkJywgJ3Zpc2EnLCAndlBheSddLFxuICAgICAgICBtZXJjaGFudENhcGFiaWxpdGllczogWydzdXBwb3J0czNEUyddLFxuICAgICAgICBzaGlwcGluZ1R5cGU6ICdzaGlwcGluZycsXG4gICAgICAgIHJlcXVpcmVkQmlsbGluZ0NvbnRhY3RGaWVsZHM6IFtcbiAgICAgICAgICAgICdwb3N0YWxBZGRyZXNzJyxcbiAgICAgICAgICAgICdlbWFpbCdcbiAgICAgICAgXSxcbiAgICAgICAgcmVxdWlyZWRTaGlwcGluZ0NvbnRhY3RGaWVsZHM6IFtcbiAgICAgICAgICAgICdwb3N0YWxBZGRyZXNzJyxcbiAgICAgICAgICAgICdlbWFpbCdcbiAgICAgICAgXSxcbiAgICAgICAgdG90YWw6IHtcbiAgICAgICAgICAgIGxhYmVsOiB0b3RhbExhYmVsLFxuICAgICAgICAgICAgYW1vdW50OiBzdWJ0b3RhbCxcbiAgICAgICAgICAgIHR5cGU6ICdmaW5hbCdcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImltcG9ydCB7cmVxdWVzdH0gZnJvbSBcIi4uL2FwcGxlUGF5UmVxdWVzdFwiO1xuaW1wb3J0IHtjcmVhdGVBcHBsZUVycm9yc30gZnJvbSBcIi4uL2FwcGxlUGF5RXJyb3JcIjtcblxuZXhwb3J0IGNvbnN0IEFwcGxlUGF5QnV0dG9uQ29tcG9uZW50ID0gKHsgYnV0dG9uQXR0cmlidXRlcyA9IHt9IH0pID0+IHtcbiAgICBjb25zdCBtb2xsaWVBcHBsZVBheUJsb2NrRGF0YUNhcnQgPSB3aW5kb3cubW9sbGllQXBwbGVQYXlCbG9ja0RhdGFDYXJ0IHx8IHdpbmRvdy5tb2xsaWVCbG9ja0RhdGEubW9sbGllQXBwbGVQYXlCbG9ja0RhdGFDYXJ0XG4gICAgY29uc3Qgbm9uY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIndvb2NvbW1lcmNlLXByb2Nlc3MtY2hlY2tvdXQtbm9uY2VcIikudmFsdWVcbiAgICBsZXQgdXBkYXRlZENvbnRhY3RJbmZvID0gW11cbiAgICBsZXQgcmVkaXJlY3Rpb25VcmwgPSAnJ1xuICAgIGNvbnN0IHtcbiAgICAgICAgcHJvZHVjdDoge25lZWRTaGlwcGluZyA9IHRydWUsIHN1YnRvdGFsfSxcbiAgICAgICAgc2hvcDoge2NvdW50cnlDb2RlLCBjdXJyZW5jeUNvZGUgPSAnRVVSJywgdG90YWxMYWJlbCA9ICcnfSxcbiAgICAgICAgYWpheFVybCxcbiAgICB9ID0gbW9sbGllQXBwbGVQYXlCbG9ja0RhdGFDYXJ0XG4gICAgY29uc3Qgc3R5bGUgPSB7XG4gICAgICAgIGhlaWdodDogYCR7YnV0dG9uQXR0cmlidXRlcy5oZWlnaHQgfHwgNDh9cHhgLFxuICAgICAgICBib3JkZXJSYWRpdXM6IGAke2J1dHRvbkF0dHJpYnV0ZXMuYm9yZGVyUmFkaXVzIHx8IDR9cHhgXG4gICAgfVxuXG4gICAgY29uc3QgZmluZFNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSAoc2hpcHBpbmdSYXRlcykgPT4ge1xuICAgICAgICBsZXQgc2hpcHBpbmdSYXRlID0gc2hpcHBpbmdSYXRlcy5maW5kKChzaGlwcGluZ01ldGhvZCkgPT4gc2hpcHBpbmdNZXRob2Quc2VsZWN0ZWQgPT09IHRydWUpXG4gICAgICAgIGNvbnN0IGFwcGxlRm9ybWF0dGVkUmF0ZSA9IHtcbiAgICAgICAgICAgIGFtb3VudDogJycsXG4gICAgICAgICAgICBkZXRhaWw6ICcnLFxuICAgICAgICAgICAgbGFiZWw6IHNoaXBwaW5nUmF0ZS5uYW1lLFxuICAgICAgICAgICAgaWRlbnRpZmllcjogc2hpcHBpbmdSYXRlLnJhdGVfaWQsXG4gICAgICAgICAgICBzZWxlY3RlZDogc2hpcHBpbmdSYXRlLnNlbGVjdGVkLFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzaGlwcGluZ1JhdGUgPyBhcHBsZUZvcm1hdHRlZFJhdGUgOiAnJ1xuICAgIH1cblxuICAgIGxldCBhcHBsZVBheVNlc3Npb24gPSAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSBuZXcgQXBwbGVQYXlTZXNzaW9uKDMsIHJlcXVlc3QoY291bnRyeUNvZGUsIGN1cnJlbmN5Q29kZSwgdG90YWxMYWJlbCwgc3VidG90YWwpKVxuICAgICAgICBjb25zdCBzdG9yZSA9IHdwLmRhdGEuc2VsZWN0KCd3Yy9zdG9yZS9jYXJ0JylcbiAgICAgICAgY29uc3Qgc2hpcHBpbmdSYXRlcyA9IHN0b3JlLmdldFNoaXBwaW5nUmF0ZXMoKT8uWzBdPy5zaGlwcGluZ19yYXRlcztcbiAgICAgICAgbGV0IHNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSAnJztcbiAgICAgICAgaWYgKHNoaXBwaW5nUmF0ZXMgJiYgc2hpcHBpbmdSYXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kID0gZmluZFNlbGVjdGVkU2hpcHBpbmdNZXRob2Qoc2hpcHBpbmdSYXRlcywgc2VsZWN0ZWRTaGlwcGluZ01ldGhvZCk7XG4gICAgICAgIH1cbiAgICAgICAgICAgIHNlc3Npb24ub25zaGlwcGluZ21ldGhvZHNlbGVjdGVkID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAnbW9sbGllX2FwcGxlX3BheV91cGRhdGVfc2hpcHBpbmdfbWV0aG9kJyxcbiAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdNZXRob2Q6IGV2ZW50LnNoaXBwaW5nTWV0aG9kLFxuICAgICAgICAgICAgICAgICAgICBjYWxsZXJQYWdlOiAnY2FydCcsXG4gICAgICAgICAgICAgICAgICAgIHNpbXBsaWZpZWRDb250YWN0OiB1cGRhdGVkQ29udGFjdEluZm8sXG4gICAgICAgICAgICAgICAgICAgICd3b29jb21tZXJjZS1wcm9jZXNzLWNoZWNrb3V0LW5vbmNlJzogbm9uY2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiAoYXBwbGVQYXlTaGlwcGluZ01ldGhvZFVwZGF0ZSwgdGV4dFN0YXR1cywganFYSFIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlc3BvbnNlID0gYXBwbGVQYXlTaGlwcGluZ01ldGhvZFVwZGF0ZS5kYXRhXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkU2hpcHBpbmdNZXRob2QgPSBldmVudC5zaGlwcGluZ01ldGhvZFxuICAgICAgICAgICAgICAgICAgICBpZiAoYXBwbGVQYXlTaGlwcGluZ01ldGhvZFVwZGF0ZS5zdWNjZXNzID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZXJyb3JzID0gY3JlYXRlQXBwbGVFcnJvcnMocmVzcG9uc2UuZXJyb3JzKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcGxldGVTaGlwcGluZ01ldGhvZFNlbGVjdGlvbihyZXNwb25zZSlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2Fybih0ZXh0U3RhdHVzLCBlcnJvclRocm93bilcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5hYm9ydCgpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgc2Vzc2lvbi5vbnNoaXBwaW5nY29udGFjdHNlbGVjdGVkID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAnbW9sbGllX2FwcGxlX3BheV91cGRhdGVfc2hpcHBpbmdfY29udGFjdCcsXG4gICAgICAgICAgICAgICAgICAgIHNpbXBsaWZpZWRDb250YWN0OiBldmVudC5zaGlwcGluZ0NvbnRhY3QsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxlclBhZ2U6ICdjYXJ0JyxcbiAgICAgICAgICAgICAgICAgICAgbmVlZFNoaXBwaW5nOiBuZWVkU2hpcHBpbmcsXG4gICAgICAgICAgICAgICAgICAgICd3b29jb21tZXJjZS1wcm9jZXNzLWNoZWNrb3V0LW5vbmNlJzogbm9uY2UsXG4gICAgICAgICAgICAgICAgICAgIHNoaXBwaW5nTWV0aG9kOiBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogKGFwcGxlUGF5U2hpcHBpbmdDb250YWN0VXBkYXRlLCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSBhcHBsZVBheVNoaXBwaW5nQ29udGFjdFVwZGF0ZS5kYXRhXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRDb250YWN0SW5mbyA9IGV2ZW50LnNoaXBwaW5nQ29udGFjdFxuICAgICAgICAgICAgICAgICAgICBpZiAoYXBwbGVQYXlTaGlwcGluZ0NvbnRhY3RVcGRhdGUuc3VjY2VzcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmVycm9ycyA9IGNyZWF0ZUFwcGxlRXJyb3JzKHJlc3BvbnNlLmVycm9ycylcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UubmV3U2hpcHBpbmdNZXRob2RzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kID0gcmVzcG9uc2UubmV3U2hpcHBpbmdNZXRob2RzWzBdXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0ZVNoaXBwaW5nQ29udGFjdFNlbGVjdGlvbihyZXNwb25zZSlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2Fybih0ZXh0U3RhdHVzLCBlcnJvclRocm93bilcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5hYm9ydCgpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgc2Vzc2lvbi5vbnZhbGlkYXRlbWVyY2hhbnQgPSAoYXBwbGVQYXlWYWxpZGF0ZU1lcmNoYW50RXZlbnQpID0+IHtcbiAgICAgICAgICAgIGpRdWVyeS5hamF4KHtcbiAgICAgICAgICAgICAgICB1cmw6IGFqYXhVcmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb246ICdtb2xsaWVfYXBwbGVfcGF5X3ZhbGlkYXRpb24nLFxuICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uVXJsOiBhcHBsZVBheVZhbGlkYXRlTWVyY2hhbnRFdmVudC52YWxpZGF0aW9uVVJMLFxuICAgICAgICAgICAgICAgICAgICAnd29vY29tbWVyY2UtcHJvY2Vzcy1jaGVja291dC1ub25jZSc6IG5vbmNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogKG1lcmNoYW50U2Vzc2lvbiwgdGV4dFN0YXR1cywganFYSFIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1lcmNoYW50U2Vzc2lvbi5zdWNjZXNzID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmNvbXBsZXRlTWVyY2hhbnRWYWxpZGF0aW9uKEpTT04ucGFyc2UobWVyY2hhbnRTZXNzaW9uLmRhdGEpKVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKG1lcmNoYW50U2Vzc2lvbi5kYXRhKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5hYm9ydCgpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2Fybih0ZXh0U3RhdHVzLCBlcnJvclRocm93bilcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5hYm9ydCgpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgc2Vzc2lvbi5vbnBheW1lbnRhdXRob3JpemVkID0gKEFwcGxlUGF5UGF5bWVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qge2JpbGxpbmdDb250YWN0LCBzaGlwcGluZ0NvbnRhY3R9ID0gQXBwbGVQYXlQYXltZW50LnBheW1lbnRcblxuICAgICAgICAgICAgalF1ZXJ5LmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogYWpheFVybCxcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbjogJ21vbGxpZV9hcHBsZV9wYXlfY3JlYXRlX29yZGVyX2NhcnQnLFxuICAgICAgICAgICAgICAgICAgICBzaGlwcGluZ0NvbnRhY3Q6IEFwcGxlUGF5UGF5bWVudC5wYXltZW50LnNoaXBwaW5nQ29udGFjdCxcbiAgICAgICAgICAgICAgICAgICAgYmlsbGluZ0NvbnRhY3Q6IEFwcGxlUGF5UGF5bWVudC5wYXltZW50LmJpbGxpbmdDb250YWN0LFxuICAgICAgICAgICAgICAgICAgICB0b2tlbjogQXBwbGVQYXlQYXltZW50LnBheW1lbnQudG9rZW4sXG4gICAgICAgICAgICAgICAgICAgIHNoaXBwaW5nTWV0aG9kOiBzZWxlY3RlZFNoaXBwaW5nTWV0aG9kLFxuICAgICAgICAgICAgICAgICAgICAnbW9sbGllLXBheW1lbnRzLWZvci13b29jb21tZXJjZV9pc3N1ZXJfYXBwbGVwYXknOiAnYXBwbGVwYXknLFxuICAgICAgICAgICAgICAgICAgICAnd29vY29tbWVyY2UtcHJvY2Vzcy1jaGVja291dC1ub25jZSc6IG5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19maXJzdF9uYW1lJzogYmlsbGluZ0NvbnRhY3QuZ2l2ZW5OYW1lIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19sYXN0X25hbWUnOiBiaWxsaW5nQ29udGFjdC5mYW1pbHlOYW1lIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19jb21wYW55JzogJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX2NvdW50cnknOiBiaWxsaW5nQ29udGFjdC5jb3VudHJ5Q29kZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfYWRkcmVzc18xJzogYmlsbGluZ0NvbnRhY3QuYWRkcmVzc0xpbmVzWzBdIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19hZGRyZXNzXzInOiBiaWxsaW5nQ29udGFjdC5hZGRyZXNzTGluZXNbMV0gfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdiaWxsaW5nX3Bvc3Rjb2RlJzogYmlsbGluZ0NvbnRhY3QucG9zdGFsQ29kZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfY2l0eSc6IGJpbGxpbmdDb250YWN0LmxvY2FsaXR5IHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnYmlsbGluZ19zdGF0ZSc6IGJpbGxpbmdDb250YWN0LmFkbWluaXN0cmF0aXZlQXJlYSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfcGhvbmUnOiBiaWxsaW5nQ29udGFjdC5waG9uZU51bWJlciB8fCAnMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICAgICAgICAgICAgJ2JpbGxpbmdfZW1haWwnOiBzaGlwcGluZ0NvbnRhY3QuZW1haWxBZGRyZXNzIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfZmlyc3RfbmFtZSc6IHNoaXBwaW5nQ29udGFjdC5naXZlbk5hbWUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19sYXN0X25hbWUnOiBzaGlwcGluZ0NvbnRhY3QuZmFtaWx5TmFtZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2NvbXBhbnknOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX2NvdW50cnknOiBzaGlwcGluZ0NvbnRhY3QuY291bnRyeUNvZGUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19hZGRyZXNzXzEnOiBzaGlwcGluZ0NvbnRhY3QuYWRkcmVzc0xpbmVzWzBdIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfYWRkcmVzc18yJzogc2hpcHBpbmdDb250YWN0LmFkZHJlc3NMaW5lc1sxXSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NoaXBwaW5nX3Bvc3Rjb2RlJzogc2hpcHBpbmdDb250YWN0LnBvc3RhbENvZGUgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19jaXR5Jzogc2hpcHBpbmdDb250YWN0LmxvY2FsaXR5IHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfc3RhdGUnOiBzaGlwcGluZ0NvbnRhY3QuYWRtaW5pc3RyYXRpdmVBcmVhIHx8ICcnLFxuICAgICAgICAgICAgICAgICAgICAnc2hpcHBpbmdfcGhvbmUnOiBzaGlwcGluZ0NvbnRhY3QucGhvbmVOdW1iZXIgfHwgJzAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgICAgICAgICAgICdzaGlwcGluZ19lbWFpbCc6IHNoaXBwaW5nQ29udGFjdC5lbWFpbEFkZHJlc3MgfHwgJycsXG4gICAgICAgICAgICAgICAgICAgICdvcmRlcl9jb21tZW50cyc6ICcnLFxuICAgICAgICAgICAgICAgICAgICAncGF5bWVudF9tZXRob2QnOiAnbW9sbGllX3djX2dhdGV3YXlfYXBwbGVwYXknLFxuICAgICAgICAgICAgICAgICAgICAnX3dwX2h0dHBfcmVmZXJlcic6ICcvP3djLWFqYXg9dXBkYXRlX29yZGVyX3JldmlldydcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IChhdXRob3JpemF0aW9uUmVzdWx0LCB0ZXh0U3RhdHVzLCBqcVhIUikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gYXV0aG9yaXphdGlvblJlc3VsdC5kYXRhXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdXRob3JpemF0aW9uUmVzdWx0LnN1Y2Nlc3MgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0aW9uVXJsID0gcmVzdWx0WydyZXR1cm5VcmwnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uY29tcGxldGVQYXltZW50KHJlc3VsdFsncmVzcG9uc2VUb0FwcGxlJ10pXG4gICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHJlZGlyZWN0aW9uVXJsXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuZXJyb3JzID0gY3JlYXRlQXBwbGVFcnJvcnMocmVzdWx0LmVycm9ycylcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uY29tcGxldGVQYXltZW50KHJlc3VsdClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IChqcVhIUiwgdGV4dFN0YXR1cywgZXJyb3JUaHJvd24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLmFib3J0KClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBzZXNzaW9uLmJlZ2luKClcbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBpZD1cIm1vbGxpZV9hcHBsZXBheV9idXR0b25cIlxuICAgICAgICAgICAgY2xhc3NOYW1lPVwiYXBwbGUtcGF5LWJ1dHRvbiBhcHBsZS1wYXktYnV0dG9uLWJsYWNrXCJcbiAgICAgICAgICAgIG9uQ2xpY2s9eyhldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYXBwbGVQYXlTZXNzaW9uKCk7XG4gICAgICAgICAgICB9fVxuICAgICAgICAgICAgc3R5bGU9e3N0eWxlfVxuICAgICAgICA+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFwcGxlUGF5QnV0dG9uQ29tcG9uZW50O1xuIiwiZXhwb3J0IGNvbnN0IEFwcGxlUGF5QnV0dG9uRWRpdG9yQ29tcG9uZW50ID0gKHsgYnV0dG9uQXR0cmlidXRlcyA9IHt9IH0pID0+IHtcbiAgICBjb25zdCBzdHlsZSA9IHtcbiAgICAgICAgaGVpZ2h0OiBgJHtidXR0b25BdHRyaWJ1dGVzLmhlaWdodCB8fCA0OH1weGAsXG4gICAgICAgIGJvcmRlclJhZGl1czogYCR7YnV0dG9uQXR0cmlidXRlcy5ib3JkZXJSYWRpdXMgfHwgNH1weGBcbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBpZD1cIm1vbGxpZV9hcHBsZXBheV9idXR0b25cIlxuICAgICAgICAgICAgY2xhc3NOYW1lPVwiYXBwbGUtcGF5LWJ1dHRvbiBhcHBsZS1wYXktYnV0dG9uLWJsYWNrXCJcbiAgICAgICAgICAgIHN0eWxlPXtzdHlsZX1cbiAgICAgICAgPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICApO1xufTtcbmV4cG9ydCBkZWZhdWx0IEFwcGxlUGF5QnV0dG9uRWRpdG9yQ29tcG9uZW50O1xuIiwibGV0IGNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzID0ge307XG5cbmZ1bmN0aW9uIGZvcm1hdFByaWNlTGlrZVdjKHByaWNlKSB7XG4gICAgLy8gdG9kbyBhZGQgdGhvdXNhbmRTZXBhcmF0b3JcbiAgICByZXR1cm4gd2NTZXR0aW5ncy5jdXJyZW5jeS5wcmljZUZvcm1hdC5yZXBsYWNlKCclMSRzJywgd2NTZXR0aW5ncy5jdXJyZW5jeS5zeW1ib2wpLnJlcGxhY2UoJyUyJHMnLHByaWNlLnRvRml4ZWQod2NTZXR0aW5ncy5jdXJyZW5jeS5wcmVjaXNpb24pLnJlcGxhY2UoJy4nLCB3Y1NldHRpbmdzLmN1cnJlbmN5LmRlY2ltYWxTZXBhcmF0b3IpKTtcbn1cblxuZnVuY3Rpb24gc2V0QXZhaWxhYmxlR2F0ZXdheXMoY291bnRyeSwgY3VycmVuY3lDb2RlLCBkYXRhKSB7XG4gICAgY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMgPSB7XG4gICAgICAgIC4uLmNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzLFxuICAgICAgICAuLi5kYXRhXG4gICAgfTtcbn1cbmZ1bmN0aW9uIHVzZU1vbGxpZUF2YWlsYWJsZUdhdGV3YXlzKGJpbGxpbmcsIGN1cnJlbmN5Q29kZSwgY2FydFRvdGFsLCBmaWx0ZXJzLCBhamF4VXJsKSB7XG4gICAgbGV0IGNvdW50cnkgPSBiaWxsaW5nLmNvdW50cnk7XG4gICAgY29uc3QgY29kZSA9IGN1cnJlbmN5Q29kZTtcbiAgICBjb25zdCB2YWx1ZSA9IGNhcnRUb3RhbDtcbiAgICBpZiAoIWNvdW50cnkpIHtcbiAgICAgICAgY291bnRyeSA9IHdjU2V0dGluZ3M/LmJhc2VMb2NhdGlvbi5jb3VudHJ5O1xuICAgIH1cblxuICAgIHdwLmVsZW1lbnQudXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgaWYgKCFjb3VudHJ5KSByZXR1cm47XG4gICAgICAgIGNvbnN0IGN1cnJlbmN5Q29kZSA9IGNvZGU7XG4gICAgICAgIGNvbnN0IGNhcnRUb3RhbCA9IHZhbHVlO1xuICAgICAgICBjb25zdCBjdXJyZW50RmlsdGVyS2V5ID0gY3VycmVuY3lDb2RlICsgXCItXCIgKyBjb3VudHJ5O1xuICAgICAgICBpZiAoY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMuaGFzT3duUHJvcGVydHkoY3VycmVudEZpbHRlcktleSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmZXRjaChcbiAgICAgICAgICAgIGFqYXhVcmwsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYm9keTogbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbjogJ21vbGxpZV9jaGVja291dF9ibG9ja3NfY2FubWFrZXBheW1lbnQnLFxuICAgICAgICAgICAgICAgICAgICBjdXJyZW5jeTogY3VycmVuY3lDb2RlLFxuICAgICAgICAgICAgICAgICAgICBiaWxsaW5nQ291bnRyeTogY291bnRyeSxcbiAgICAgICAgICAgICAgICAgICAgY2FydFRvdGFsLFxuICAgICAgICAgICAgICAgICAgICBwYXltZW50TG9jYWxlOiBmaWx0ZXJzLnBheW1lbnRMb2NhbGVcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgKS50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLmpzb24oKSkudGhlbihkYXRhID0+IHtcbiAgICAgICAgICAgIHNldEF2YWlsYWJsZUdhdGV3YXlzKGNvdW50cnksIGN1cnJlbmN5Q29kZSwgZGF0YS5kYXRhKTtcbiAgICAgICAgICAgIGNvbnN0IGNhcnRUb3RhbHMgPSB3cC5kYXRhLnNlbGVjdCgnd2Mvc3RvcmUvY2FydCcpLmdldENhcnRUb3RhbHMoKTtcbiAgICAgICAgICAgIC8vIERpc3BhdGNoIHRoZW0gYWdhaW4gdG8gdHJpZ2dlciBhIHJlLXJlbmRlcjpcbiAgICAgICAgICAgIHdwLmRhdGEuZGlzcGF0Y2goJ3djL3N0b3JlL2NhcnQnKS5zZXRDYXJ0RGF0YSh7Li4uY2FydFRvdGFsc30pO1xuICAgICAgICB9KTtcbiAgICB9LCBbYmlsbGluZywgY3VycmVuY3lDb2RlLCBmaWx0ZXJzLnBheW1lbnRMb2NhbGVdKTtcblxuICAgIHJldHVybiBjYWNoZWRBdmFpbGFibGVHYXRld2F5cztcbn1cblxuLy8gQ29tcG9uZW50IHRoYXQgcnVucyB0aGUgaG9vayBidXQgZG9lcyBub3QgcmVuZGVyIGFueXRoaW5nLlxuZnVuY3Rpb24gTW9sbGllR2F0ZXdheVVwZGF0ZXIoeyBiaWxsaW5nLCBjdXJyZW5jeUNvZGUsIGNhcnRUb3RhbCwgZmlsdGVycywgYWpheFVybH0pIHtcblxuICAgIHVzZU1vbGxpZUF2YWlsYWJsZUdhdGV3YXlzKGJpbGxpbmcsIGN1cnJlbmN5Q29kZSwgY2FydFRvdGFsLCBmaWx0ZXJzLCBhamF4VXJsKTtcbiAgICByZXR1cm4gbnVsbDtcbn1cblxubGV0IG9uU3VibWl0TG9jYWxcbmxldCBhY3RpdmVQYXltZW50TWV0aG9kTG9jYWxcbmxldCBjcmVkaXRDYXJkU2VsZWN0ZWQgPSBuZXcgRXZlbnQoXCJtb2xsaWVfY3JlZGl0Y2FyZF9jb21wb25lbnRfc2VsZWN0ZWRcIiwge2J1YmJsZXM6IHRydWV9KTtcbmNvbnN0IE1vbGxpZUNvbXBvbmVudCA9IChwcm9wcykgPT4ge1xuICAgIGxldCB7b25TdWJtaXQsIGFjdGl2ZVBheW1lbnRNZXRob2QsIGJpbGxpbmcsIGl0ZW0sIHVzZUVmZmVjdCwgYWpheFVybCwgalF1ZXJ5LCBlbWl0UmVzcG9uc2UsIGV2ZW50UmVnaXN0cmF0aW9uLCByZXF1aXJlZEZpZWxkcywgc2hpcHBpbmdEYXRhLCBpc1Bob25lRmllbGRWaXNpYmxlfSA9IHByb3BzXG4gICAgY29uc3QgeyAgcmVzcG9uc2VUeXBlcyB9ID0gZW1pdFJlc3BvbnNlO1xuICAgIGNvbnN0IHtvblBheW1lbnRTZXR1cCwgb25DaGVja291dFZhbGlkYXRpb259ID0gZXZlbnRSZWdpc3RyYXRpb247XG4gICAgaWYgKCFpdGVtIHx8ICFpdGVtLm5hbWUpIHtcbiAgICAgICAgcmV0dXJuIDxkaXY+TG9hZGluZyBwYXltZW50IG1ldGhvZHMuLi48L2Rpdj47XG4gICAgfVxuICAgIGNvbnN0IFsgc2VsZWN0ZWRJc3N1ZXIsIHNlbGVjdElzc3VlciBdID0gd3AuZWxlbWVudC51c2VTdGF0ZSgnJyk7XG4gICAgY29uc3QgWyBpbnB1dFBob25lLCBzZWxlY3RQaG9uZSBdID0gd3AuZWxlbWVudC51c2VTdGF0ZSgnJyk7XG4gICAgY29uc3QgWyBpbnB1dEJpcnRoZGF0ZSwgc2VsZWN0QmlydGhkYXRlIF0gPSB3cC5lbGVtZW50LnVzZVN0YXRlKCcnKTtcbiAgICBjb25zdCBbIGlucHV0Q29tcGFueSwgc2VsZWN0Q29tcGFueSBdID0gd3AuZWxlbWVudC51c2VTdGF0ZSgnJyk7XG4gICAgY29uc3QgaXNzdWVyS2V5ID0gJ21vbGxpZS1wYXltZW50cy1mb3Itd29vY29tbWVyY2VfaXNzdWVyXycgKyBhY3RpdmVQYXltZW50TWV0aG9kXG4gICAgY29uc3Qge2NvbXBhbnlOYW1lU3RyaW5nLCBwaG9uZVN0cmluZ30gPSByZXF1aXJlZEZpZWxkc1xuICAgIGZ1bmN0aW9uIGdldFBob25lRmllbGQoKVxuICAgIHtcbiAgICAgICAgY29uc3Qgc2hpcHBpbmdQaG9uZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaGlwcGluZy1waG9uZScpO1xuICAgICAgICBjb25zdCBiaWxsaW5nUGhvbmUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZy1waG9uZScpO1xuICAgICAgICByZXR1cm4gYmlsbGluZ1Bob25lIHx8IHNoaXBwaW5nUGhvbmU7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHVwZGF0ZVRvdGFsTGFiZWwobmV3VG90YWwpIHtcbiAgICAgICAgbGV0IHRvdGFsU3BhbiA9IFwiPHNwYW4gY2xhc3M9J3djLWJsb2NrLWZvcm1hdHRlZC1tb25leS1hbW91bnQgd2MtYmxvY2stY29tcG9uZW50cy1mb3JtYXR0ZWQtbW9uZXktYW1vdW50IHdjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX3ZhbHVlJz5cIiArIGZvcm1hdFByaWNlTGlrZVdjKG5ld1RvdGFsKSArIFwiPC9zcGFuPlwiXG4gICAgICAgIGxldCB0b3RhbCA9IGpRdWVyeSgnLndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWZvb3Rlci1pdGVtIC53Yy1ibG9jay1mb3JtYXR0ZWQtbW9uZXktYW1vdW50OmZpcnN0JylcbiAgICAgICAgdG90YWwucmVwbGFjZVdpdGgodG90YWxTcGFuKVxuICAgIH1cbiAgICBmdW5jdGlvbiB1cGRhdGVUYXhlc0xhYmVsKG5ld1RvdGFsKSB7XG4gICAgICAgIGxldCB0b3RhbFNwYW4gPSBcIjxzcGFuIGNsYXNzPSd3Yy1ibG9jay1mb3JtYXR0ZWQtbW9uZXktYW1vdW50IHdjLWJsb2NrLWNvbXBvbmVudHMtZm9ybWF0dGVkLW1vbmV5LWFtb3VudCB3Yy1ibG9jay1jb21wb25lbnRzLXRvdGFscy1pdGVtX192YWx1ZSc+XCIgKyBmb3JtYXRQcmljZUxpa2VXYyhuZXdUb3RhbCkgKyBcIjwvc3Bhbj5cIlxuICAgICAgICBsZXQgdG90YWwgPSBqUXVlcnkoJ2Rpdi53cC1ibG9jay13b29jb21tZXJjZS1jaGVja291dC1vcmRlci1zdW1tYXJ5LXRheGVzLWJsb2NrLndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLXdyYXBwZXIgPiBkaXYgPiBzcGFuLndjLWJsb2NrLWZvcm1hdHRlZC1tb25leS1hbW91bnQud2MtYmxvY2stY29tcG9uZW50cy1mb3JtYXR0ZWQtbW9uZXktYW1vdW50LndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX3ZhbHVlOmZpcnN0JylcbiAgICAgICAgdG90YWwucmVwbGFjZVdpdGgodG90YWxTcGFuKVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhpZGVGZWUoZmVlLCByZXNwb25zZSkge1xuICAgICAgICBmZWU/LmhpZGUoKVxuICAgICAgICB1cGRhdGVUb3RhbExhYmVsKHJlc3BvbnNlLmRhdGEubmV3VG90YWwpO1xuICAgICAgICB1cGRhdGVUYXhlc0xhYmVsKHJlc3BvbnNlLmRhdGEudG90YWxUYXgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZlZU1hcmt1cChyZXNwb25zZSkge1xuICAgICAgICByZXR1cm4gXCI8ZGl2IGNsYXNzPSd3Yy1ibG9jay1jb21wb25lbnRzLXRvdGFscy1pdGVtIHdjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWZlZXMnPlwiICtcbiAgICAgICAgICAgIFwiPHNwYW4gY2xhc3M9J3djLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX2xhYmVsJz5cIlxuICAgICAgICAgICAgKyByZXNwb25zZS5kYXRhLm5hbWVcbiAgICAgICAgICAgICsgXCI8L3NwYW4+XCIgK1xuICAgICAgICAgICAgXCI8c3BhbiBjbGFzcz0nd2MtYmxvY2stZm9ybWF0dGVkLW1vbmV5LWFtb3VudCB3Yy1ibG9jay1jb21wb25lbnRzLWZvcm1hdHRlZC1tb25leS1hbW91bnQgd2MtYmxvY2stY29tcG9uZW50cy10b3RhbHMtaXRlbV9fdmFsdWUnPlwiXG4gICAgICAgICAgICArIGZvcm1hdFByaWNlTGlrZVdjKHJlc3BvbnNlLmRhdGEuYW1vdW50KVxuICAgICAgICAgICAgKyBcIjwvc3Bhbj5cIiArXG4gICAgICAgICAgICBcIjxkaXYgY2xhc3M9J3djLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW1fX2Rlc2NyaXB0aW9uJz5cIiArXG4gICAgICAgICAgICBcIjwvZGl2PlwiICtcbiAgICAgICAgICAgIFwiPC9kaXY+XCI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVwbGFjZUZlZShmZWUsIG5ld0ZlZSwgcmVzcG9uc2UpIHtcbiAgICAgICAgZmVlLnJlcGxhY2VXaXRoKG5ld0ZlZSlcbiAgICAgICAgdXBkYXRlVG90YWxMYWJlbChyZXNwb25zZS5kYXRhLm5ld1RvdGFsKTtcbiAgICAgICAgdXBkYXRlVGF4ZXNMYWJlbChyZXNwb25zZS5kYXRhLnRvdGFsVGF4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnNlcnROZXdGZWUobmV3RmVlLCByZXNwb25zZSkge1xuICAgICAgICBjb25zdCBzdWJ0b3RhbCA9IGpRdWVyeSgnLndjLWJsb2NrLWNvbXBvbmVudHMtdG90YWxzLWl0ZW06Zmlyc3QnKVxuICAgICAgICBzdWJ0b3RhbC5hZnRlcihuZXdGZWUpXG4gICAgICAgIHVwZGF0ZVRvdGFsTGFiZWwocmVzcG9uc2UuZGF0YS5uZXdUb3RhbCk7XG4gICAgICAgIHVwZGF0ZVRheGVzTGFiZWwocmVzcG9uc2UuZGF0YS50b3RhbFRheCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFuZGxlRmVlcyhyZXNwb25zZSkge1xuICAgICAgICBjb25zdCBmZWUgPSBqUXVlcnkoJy53Yy1ibG9jay1jb21wb25lbnRzLXRvdGFscy1mZWVzJylcbiAgICAgICAgaWYgKCFyZXNwb25zZS5kYXRhLmFtb3VudCkge1xuICAgICAgICAgICAgaGlkZUZlZShmZWUsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IG5ld0ZlZSA9IGZlZU1hcmt1cChyZXNwb25zZSk7XG4gICAgICAgIGlmIChmZWUubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXBsYWNlRmVlKGZlZSwgbmV3RmVlLCByZXNwb25zZSk7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBpbnNlcnROZXdGZWUobmV3RmVlLCByZXNwb25zZSk7XG4gICAgfVxuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgaWYoYWN0aXZlUGF5bWVudE1ldGhvZExvY2FsICE9PSBhY3RpdmVQYXltZW50TWV0aG9kICYmIGFjdGl2ZVBheW1lbnRNZXRob2QgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9jcmVkaXRjYXJkJyl7XG4gICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGlzcGF0Y2hFdmVudChjcmVkaXRDYXJkU2VsZWN0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIGFjdGl2ZVBheW1lbnRNZXRob2RMb2NhbCA9IGFjdGl2ZVBheW1lbnRNZXRob2RcbiAgICAgICAgalF1ZXJ5LmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBhamF4VXJsLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiAnbW9sbGllX2NoZWNrb3V0X2Jsb2Nrc19zdXJjaGFnZScsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBhY3RpdmVQYXltZW50TWV0aG9kXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29tcGxldGU6IChqcVhIUiwgdGV4dFN0YXR1cykgPT4ge1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IChyZXNwb25zZSwgdGV4dFN0YXR1cywganFYSFIpID0+IHtcbiAgICAgICAgICAgICAgICBoYW5kbGVGZWVzKHJlc3BvbnNlKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiAoanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHRleHRTdGF0dXMsIGVycm9yVGhyb3duKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICB9LCBbYWN0aXZlUGF5bWVudE1ldGhvZCwgYmlsbGluZy5jYXJ0VG90YWxdKVxuXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgY29uc3Qgb25Qcm9jZXNzaW5nUGF5bWVudCA9ICgpID0+IHtcbiAgICAgICAgICAgIGxldCBkYXRhID0ge1xuICAgICAgICAgICAgICAgIHBheW1lbnRfbWV0aG9kOiBhY3RpdmVQYXltZW50TWV0aG9kLFxuICAgICAgICAgICAgICAgIHBheW1lbnRfbWV0aG9kX3RpdGxlOiBpdGVtLnRpdGxlLFxuICAgICAgICAgICAgICAgIFtpc3N1ZXJLZXldOiBzZWxlY3RlZElzc3VlcixcbiAgICAgICAgICAgICAgICBiaWxsaW5nX3Bob25lOiBpbnB1dFBob25lLFxuICAgICAgICAgICAgICAgIGJpbGxpbmdfY29tcGFueV9iaWxsaWU6IGlucHV0Q29tcGFueSxcbiAgICAgICAgICAgICAgICBiaWxsaW5nX2JpcnRoZGF0ZTogaW5wdXRCaXJ0aGRhdGUsXG4gICAgICAgICAgICAgICAgY2FyZFRva2VuOiAnJyxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCB0b2tlblZhbCA9IGpRdWVyeSgnLm1vbGxpZS1jb21wb25lbnRzID4gaW5wdXQnKS52YWwoKVxuICAgICAgICAgICAgaWYgKHRva2VuVmFsKSB7XG4gICAgICAgICAgICAgICAgZGF0YS5jYXJkVG9rZW4gPSB0b2tlblZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogcmVzcG9uc2VUeXBlcy5TVUNDRVNTLFxuICAgICAgICAgICAgICAgIG1ldGE6IHtcbiAgICAgICAgICAgICAgICAgICAgcGF5bWVudE1ldGhvZERhdGE6IGRhdGFcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHVuc3Vic2NyaWJlUGF5bWVudFByb2Nlc3NpbmcgPSBvblBheW1lbnRTZXR1cChcbiAgICAgICAgICAgIG9uUHJvY2Vzc2luZ1BheW1lbnRcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlUGF5bWVudFByb2Nlc3NpbmcoKVxuICAgICAgICB9O1xuXG4gICAgfSwgW3NlbGVjdGVkSXNzdWVyLCBvblBheW1lbnRTZXR1cCwgaW5wdXRQaG9uZSwgaW5wdXRDb21wYW55LCBpbnB1dEJpcnRoZGF0ZV0pXG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBsZXQgY29tcGFueUxhYmVsID0galF1ZXJ5KCdkaXYud2MtYmxvY2stY29tcG9uZW50cy10ZXh0LWlucHV0LndjLWJsb2NrLWNvbXBvbmVudHMtYWRkcmVzcy1mb3JtX19jb21wYW55ID4gbGFiZWwnKVxuICAgICAgICBpZiAoY29tcGFueUxhYmVsLmxlbmd0aCA9PT0gMCB8fCBpdGVtLmhpZGVDb21wYW55RmllbGQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFjdGl2ZVBheW1lbnRNZXRob2QgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9iaWxsaWUnKSB7XG4gICAgICAgICAgICBsZXQgbWVzc2FnZSA9IGl0ZW0uY29tcGFueVBsYWNlaG9sZGVyXG4gICAgICAgICAgICBjb21wYW55TGFiZWwucmVwbGFjZVdpdGgoJzxsYWJlbCBodG1sRm9yPVwic2hpcHBpbmctY29tcGFueVwiPicgKyBtZXNzYWdlICsgJzwvbGFiZWw+JylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb21wYW55TmFtZVN0cmluZyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBjb21wYW55TGFiZWwucmVwbGFjZVdpdGgoJzxsYWJlbCBodG1sRm9yPVwic2hpcHBpbmctY29tcGFueVwiPicgKyBjb21wYW55TmFtZVN0cmluZyArICc8L2xhYmVsPicpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGlzQ29tcGFueUVtcHR5ID0gKGJpbGxpbmcuYmlsbGluZ0RhdGEuY29tcGFueSA9PT0gJycgJiYgc2hpcHBpbmdEYXRhLnNoaXBwaW5nQWRkcmVzcy5jb21wYW55ID09PSAnJykgJiYgaW5wdXRDb21wYW55ID09PSAnJztcbiAgICAgICAgY29uc3QgdW5zdWJzY3JpYmVQcm9jZXNzaW5nID0gb25DaGVja291dFZhbGlkYXRpb24oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGFjdGl2ZVBheW1lbnRNZXRob2QgPT09ICdtb2xsaWVfd2NfZ2F0ZXdheV9iaWxsaWUnICYmIGlzQ29tcGFueUVtcHR5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2U6IGl0ZW0uZXJyb3JNZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlUHJvY2Vzc2luZygpXG4gICAgICAgIH07XG5cbiAgICB9LCBbYWN0aXZlUGF5bWVudE1ldGhvZCwgb25DaGVja291dFZhbGlkYXRpb24sIGJpbGxpbmcuYmlsbGluZ0RhdGEsIGl0ZW0sIGNvbXBhbnlOYW1lU3RyaW5nLCBpbnB1dENvbXBhbnldKTtcblxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICAgIGxldCBwaG9uZUxhYmVsID0gZ2V0UGhvbmVGaWVsZCgpPy5sYWJlbHM/LlswXSA/PyBudWxsO1xuICAgICAgICBpZiAoIXBob25lTGFiZWwgfHwgcGhvbmVMYWJlbC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGlmIChhY3RpdmVQYXltZW50TWV0aG9kID09PSAnbW9sbGllX3djX2dhdGV3YXlfaW4zJykge1xuICAgICAgICAgICAgcGhvbmVMYWJlbC5pbm5lclRleHQgPSBpdGVtLnBob25lUGxhY2Vob2xkZXJcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChwaG9uZVN0cmluZyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBwaG9uZUxhYmVsLmlubmVyVGV4dCA9IHBob25lU3RyaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGlzUGhvbmVFbXB0eSA9IChiaWxsaW5nLmJpbGxpbmdEYXRhLnBob25lID09PSAnJyAmJiBzaGlwcGluZ0RhdGEuc2hpcHBpbmdBZGRyZXNzLnBob25lID09PSAnJykgJiYgaW5wdXRQaG9uZSA9PT0gJyc7XG4gICAgICAgIGxldCBpc0JpcnRoZGF0ZVZhbGlkID0gaW5wdXRCaXJ0aGRhdGUgPT09ICcnXG4gICAgICAgIGxldCB0b2RheSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGxldCBiaXJ0aGRhdGUgPSBuZXcgRGF0ZShpbnB1dEJpcnRoZGF0ZSk7XG4gICAgICAgIGlmIChiaXJ0aGRhdGUgPiB0b2RheSkge1xuICAgICAgICAgICAgaXNCaXJ0aGRhdGVWYWxpZCA9IGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdW5zdWJzY3JpYmVQcm9jZXNzaW5nID0gb25DaGVja291dFZhbGlkYXRpb24oXG5cbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYWN0aXZlUGF5bWVudE1ldGhvZCA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2luMycgJiYgKGlzUGhvbmVFbXB0eSB8fCBpc0JpcnRoZGF0ZVZhbGlkKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlOiBpdGVtLmVycm9yTWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICB1bnN1YnNjcmliZVByb2Nlc3NpbmcoKVxuICAgICAgICB9O1xuXG4gICAgfSwgW2FjdGl2ZVBheW1lbnRNZXRob2QsIG9uQ2hlY2tvdXRWYWxpZGF0aW9uLCBiaWxsaW5nLmJpbGxpbmdEYXRhLCBzaGlwcGluZ0RhdGEuc2hpcHBpbmdBZGRyZXNzLCBpdGVtLCBwaG9uZVN0cmluZywgaW5wdXRCaXJ0aGRhdGUsIGlucHV0UGhvbmVdKTtcblxuICAgIG9uU3VibWl0TG9jYWwgPSBvblN1Ym1pdFxuICAgIGNvbnN0IHVwZGF0ZUlzc3VlciA9IChlKSA9PiBzZWxlY3RJc3N1ZXIoZS50YXJnZXQudmFsdWUpO1xuICAgIGNvbnN0IHVwZGF0ZUNvbXBhbnkgPSAoZSkgPT4gc2VsZWN0Q29tcGFueShlLnRhcmdldC52YWx1ZSk7XG4gICAgY29uc3QgdXBkYXRlUGhvbmUgPSAoZSkgPT4gc2VsZWN0UGhvbmUoZS50YXJnZXQudmFsdWUpO1xuICAgIGNvbnN0IHVwZGF0ZUJpcnRoZGF0ZSA9IChlKSA9PiBzZWxlY3RCaXJ0aGRhdGUoIGUudGFyZ2V0LnZhbHVlICk7XG5cbiAgICBmdW5jdGlvbiBmaWVsZE1hcmt1cChpZCwgZmllbGRUeXBlLCBsYWJlbCwgYWN0aW9uLCB2YWx1ZSwgcGxhY2Vob2xkZXIgPSBudWxsKSB7XG4gICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IFwid2MtYmxvY2stY29tcG9uZW50cy10ZXh0LWlucHV0IHdjLWJsb2NrLWNvbXBvbmVudHMtYWRkcmVzcy1mb3JtX19cIiArIGlkO1xuICAgICAgICByZXR1cm4gPGRpdiBjbGFzcz1cImN1c3RvbS1pbnB1dFwiPlxuICAgICAgICAgICAgPGxhYmVsIGh0bWxGb3I9e2lkfSBkYW5nZXJvdXNseVNldElubmVySFRNTD17e19faHRtbDogbGFiZWx9fT48L2xhYmVsPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9e2ZpZWxkVHlwZX0gbmFtZT17aWR9IGlkPXtpZH0gdmFsdWU9e3ZhbHVlfSBvbkNoYW5nZT17YWN0aW9ufSBwbGFjZWhvbGRlcj17cGxhY2Vob2xkZXJ9PjwvaW5wdXQ+XG4gICAgICAgIDwvZGl2PlxuICAgIH1cblxuICAgIGlmIChpdGVtLmlzc3VlcnMgJiYgaXRlbS5uYW1lICE9PSBcIm1vbGxpZV93Y19nYXRld2F5X2NyZWRpdGNhcmRcIil7XG4gICAgICAgIHJldHVybiA8ZGl2PjxwPntpdGVtLmNvbnRlbnR9PC9wPjxzZWxlY3QgbmFtZT17aXNzdWVyS2V5fSBkYW5nZXJvdXNseVNldElubmVySFRNTD17IHtfX2h0bWw6IGl0ZW0uaXNzdWVyc30gfSB2YWx1ZT17c2VsZWN0ZWRJc3N1ZXJ9IG9uQ2hhbmdlPXt1cGRhdGVJc3N1ZXJ9Pjwvc2VsZWN0PjwvZGl2PlxuICAgIH1cblxuICAgIGlmKGl0ZW0ubmFtZSA9PT0gXCJtb2xsaWVfd2NfZ2F0ZXdheV9jcmVkaXRjYXJkXCIpe1xuICAgICAgICByZXR1cm4gPGRpdiBkYW5nZXJvdXNseVNldElubmVySFRNTD17IHtfX2h0bWw6IGl0ZW0uY29udGVudH0gfT48L2Rpdj47XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0ubmFtZSA9PT0gXCJtb2xsaWVfd2NfZ2F0ZXdheV9iaWxsaWVcIikge1xuICAgICAgICBjb25zdCBiaWxsaW5nQ29tcGFueUZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmctY29tcGFueScpO1xuICAgICAgICBjb25zdCBzaGlwcGluZ0NvbXBhbnlGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzaGlwcGluZy1jb21wYW55Jyk7XG4gICAgICAgIGNvbnN0IGlzQmlsbGluZ0NvbXBhbnlSZXF1aXJlZCA9IGJpbGxpbmdDb21wYW55RmllbGQ/Lmhhc0F0dHJpYnV0ZSgncmVxdWlyZWQnKTtcbiAgICAgICAgY29uc3QgaXNTaGlwcGluZ0NvbXBhbnlSZXF1aXJlZCA9IHNoaXBwaW5nQ29tcGFueUZpZWxkPy5oYXNBdHRyaWJ1dGUoJ3JlcXVpcmVkJyk7XG5cbiAgICAgICAgaWYgKChiaWxsaW5nQ29tcGFueUZpZWxkICYmIGlzQmlsbGluZ0NvbXBhbnlSZXF1aXJlZCkgfHwgKHNoaXBwaW5nQ29tcGFueUZpZWxkICYmIGlzU2hpcHBpbmdDb21wYW55UmVxdWlyZWQpIHx8IGl0ZW0uaGlkZUNvbXBhbnlGaWVsZCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29tcGFueUZpZWxkID0gaXRlbS5jb21wYW55UGxhY2Vob2xkZXIgPyBpdGVtLmNvbXBhbnlQbGFjZWhvbGRlciA6IFwiQ29tcGFueSBuYW1lXCI7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIDxkaXY+PHA+e2l0ZW0uY29udGVudH08L3A+PC9kaXY+XG4gICAgICAgICAgICAgICAge2ZpZWxkTWFya3VwKFwiYmlsbGluZ19jb21wYW55X2JpbGxpZVwiLFwidGV4dFwiLCBjb21wYW55RmllbGQsIHVwZGF0ZUNvbXBhbnksIGlucHV0Q29tcGFueSl9XG4gICAgICAgICAgICA8Lz5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBjb25zdCBjb3VudHJ5Q29kZXMgPSB7XG4gICAgICAgICAgICBCRTogJyszMnh4eHh4eHh4eCcsXG4gICAgICAgICAgICBOTDogJyszMTZ4eHh4eHh4eCcsXG4gICAgICAgICAgICBERTogJys0OXh4eHh4eHh4eCcsXG4gICAgICAgICAgICBBVDogJys0M3h4eHh4eHh4eCcsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNvdW50cnkgPSBiaWxsaW5nLmJpbGxpbmdEYXRhLmNvdW50cnk7XG4gICAgICAgIGl0ZW0ucGhvbmVQbGFjZWhvbGRlciA9IGNvdW50cnlDb2Rlc1tjb3VudHJ5XSB8fCBjb3VudHJ5Q29kZXNbJ05MJ107XG4gICAgfSwgW2JpbGxpbmcuYmlsbGluZ0RhdGEuY291bnRyeV0pO1xuXG4gICAgaWYgKGl0ZW0ubmFtZSA9PT0gXCJtb2xsaWVfd2NfZ2F0ZXdheV9pbjNcIikge1xuICAgICAgICBjb25zdCBiaXJ0aGRhdGVGaWVsZCA9IGl0ZW0uYmlydGhkYXRlUGxhY2Vob2xkZXIgfHwgXCJCaXJ0aGRhdGVcIjtcbiAgICAgICAgY29uc3QgcGhvbmVGaWVsZCA9IGl0ZW0ucGhvbmVQbGFjZWhvbGRlciB8fCBcIiszMTZ4eHh4eHh4eFwiO1xuICAgICAgICBjb25zdCBwaG9uZUxhYmVsID0gaXRlbS5waG9uZUxhYmVsIHx8IFwiUGhvbmVcIjtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgPGRpdj48cD57aXRlbS5jb250ZW50fTwvcD48L2Rpdj5cbiAgICAgICAgICAgICAgICB7ZmllbGRNYXJrdXAoXCJiaWxsaW5nLWJpcnRoZGF0ZVwiLCBcImRhdGVcIiwgYmlydGhkYXRlRmllbGQsIHVwZGF0ZUJpcnRoZGF0ZSwgaW5wdXRCaXJ0aGRhdGUpfVxuICAgICAgICAgICAgICAgIHshaXNQaG9uZUZpZWxkVmlzaWJsZSAmJiBmaWVsZE1hcmt1cChcImJpbGxpbmctcGhvbmUtaW4zXCIsIFwidGVsXCIsIHBob25lTGFiZWwsIHVwZGF0ZVBob25lLCBpbnB1dFBob25lLCBwaG9uZUZpZWxkKX1cbiAgICAgICAgICAgIDwvPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGlmIChpdGVtLm5hbWUgPT09IFwibW9sbGllX3djX2dhdGV3YXlfcml2ZXJ0eVwiKSB7XG4gICAgICAgIGNvbnN0IGJpcnRoZGF0ZUZpZWxkID0gaXRlbS5iaXJ0aGRhdGVQbGFjZWhvbGRlciB8fCBcIkJpcnRoZGF0ZVwiO1xuICAgICAgICBjb25zdCBwaG9uZUZpZWxkID0gaXRlbS5waG9uZVBsYWNlaG9sZGVyIHx8IFwiKzMxNnh4eHh4eHh4XCI7XG4gICAgICAgIGNvbnN0IHBob25lTGFiZWwgPSBpdGVtLnBob25lTGFiZWwgfHwgXCJQaG9uZVwiO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICA8ZGl2PjxwPntpdGVtLmNvbnRlbnR9PC9wPjwvZGl2PlxuICAgICAgICAgICAgICAgIHtmaWVsZE1hcmt1cChcImJpbGxpbmctYmlydGhkYXRlXCIsIFwiZGF0ZVwiLCBiaXJ0aGRhdGVGaWVsZCwgdXBkYXRlQmlydGhkYXRlLCBpbnB1dEJpcnRoZGF0ZSl9XG4gICAgICAgICAgICAgICAgeyFpc1Bob25lRmllbGRWaXNpYmxlICYmIGZpZWxkTWFya3VwKFwiYmlsbGluZy1waG9uZS1yaXZlcnR5XCIsIFwidGVsXCIsIHBob25lTGFiZWwsIHVwZGF0ZVBob25lLCBpbnB1dFBob25lLCBwaG9uZUZpZWxkKX1cbiAgICAgICAgICAgIDwvPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiA8ZGl2PjxwPntpdGVtLmNvbnRlbnR9PC9wPjwvZGl2PlxufVxuXG5jb25zdCBMYWJlbCA9ICh7IGl0ZW0sIGZpbHRlcnMsIGFqYXhVcmwgfSkgPT4ge1xuICAgIGNvbnN0IGNhcnREYXRhID0gd3AuZGF0YS51c2VTZWxlY3QoKHNlbGVjdCkgPT5cbiAgICAgICAgICAgIHNlbGVjdCgnd2Mvc3RvcmUvY2FydCcpLmdldENhcnREYXRhKCksXG4gICAgICAgIFtdXG4gICAgKTtcbiAgICBjb25zdCBjYXJ0VG90YWxzID0gd3AuZGF0YS51c2VTZWxlY3QoIChzZWxlY3QpID0+IHNlbGVjdCgnd2Mvc3RvcmUvY2FydCcpLmdldENhcnRUb3RhbHMoKSwgWyBdICk7XG4gICAgY29uc3QgY2FydFRvdGFsID0gY2FydFRvdGFscz8udG90YWxfcHJpY2UgfHwgMDtcbiAgICByZXR1cm4gKFxuICAgICAgICA8PlxuICAgICAgICAgICAgPGRpdiBkYW5nZXJvdXNseVNldElubmVySFRNTD17eyBfX2h0bWw6IGl0ZW0ubGFiZWwgfX0vPlxuICAgICAgICAgICAgPE1vbGxpZUdhdGV3YXlVcGRhdGVyXG4gICAgICAgICAgICAgICAgYmlsbGluZz17Y2FydERhdGEuYmlsbGluZ0FkZHJlc3N9XG4gICAgICAgICAgICAgICAgY3VycmVuY3lDb2RlPXt3Y1NldHRpbmdzLmN1cnJlbmN5LmNvZGV9XG4gICAgICAgICAgICAgICAgZmlsdGVycz17ZmlsdGVyc31cbiAgICAgICAgICAgICAgICBhamF4VXJsPXthamF4VXJsfVxuICAgICAgICAgICAgICAgIGNhcnRUb3RhbD17Y2FydFRvdGFsfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC8+XG4gICAgKTtcbn07XG5cbmNvbnN0IG1vbGxpZVBheW1lbnRNZXRob2QgPSAodXNlRWZmZWN0LCBhamF4VXJsLCBmaWx0ZXJzLCBnYXRld2F5RGF0YSwgYXZhaWxhYmxlR2F0ZXdheXMsIGl0ZW0sIGpRdWVyeSwgcmVxdWlyZWRGaWVsZHMsIGlzQ29tcGFueUZpZWxkVmlzaWJsZSwgaXNQaG9uZUZpZWxkVmlzaWJsZSkgPT57XG5cbiAgICBpZiAoaXRlbS5uYW1lID09PSBcIm1vbGxpZV93Y19nYXRld2F5X2NyZWRpdGNhcmRcIikge1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb2xsaWVfY29tcG9uZW50c19yZWFkeV90b19zdWJtaXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBvblN1Ym1pdExvY2FsKClcbiAgICAgICAgfSlcbiAgICB9XG4gICAgZnVuY3Rpb24gY3JlZGl0Y2FyZFNlbGVjdGVkRXZlbnQoKSB7XG4gICAgICAgIGlmIChpdGVtLm5hbWUgPT09IFwibW9sbGllX3djX2dhdGV3YXlfY3JlZGl0Y2FyZFwiKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGlzcGF0Y2hFdmVudChjcmVkaXRDYXJkU2VsZWN0ZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogaXRlbS5uYW1lLFxuICAgICAgICBsYWJlbDo8TGFiZWxcbiAgICAgICAgICAgIGl0ZW09e2l0ZW19XG4gICAgICAgICAgICBhamF4VXJsPXthamF4VXJsfVxuICAgICAgICAgICAgZmlsdGVycz17ZmlsdGVyc31cbiAgICAgICAgLz4sXG4gICAgICAgIGNvbnRlbnQ6IDxNb2xsaWVDb21wb25lbnRcbiAgICAgICAgICAgIGl0ZW09e2l0ZW19XG4gICAgICAgICAgICB1c2VFZmZlY3Q9e3VzZUVmZmVjdH1cbiAgICAgICAgICAgIGFqYXhVcmw9e2FqYXhVcmx9XG4gICAgICAgICAgICBqUXVlcnk9e2pRdWVyeX1cbiAgICAgICAgICAgIHJlcXVpcmVkRmllbGRzPXtyZXF1aXJlZEZpZWxkc31cbiAgICAgICAgICAgIGlzUGhvbmVGaWVsZFZpc2libGU9e2lzUGhvbmVGaWVsZFZpc2libGV9Lz4sXG4gICAgICAgIGVkaXQ6IDxkaXY+e2l0ZW0uZWRpdH08L2Rpdj4sXG4gICAgICAgIHBheW1lbnRNZXRob2RJZDogaXRlbS5wYXltZW50TWV0aG9kSWQsXG4gICAgICAgIGNhbk1ha2VQYXltZW50OiAoe2NhcnRUb3RhbHMsIGJpbGxpbmdEYXRhfSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoaXRlbS5hbGxvd2VkQ291bnRyaWVzKSAmJiAhKGl0ZW0uYWxsb3dlZENvdW50cmllcy5pbmNsdWRlcyhiaWxsaW5nRGF0YS5jb3VudHJ5KSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYXJ0VG90YWxzIDw9IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY3VycmVuY3lDb2RlID0gY2FydFRvdGFscz8uY3VycmVuY3lfY29kZTtcbiAgICAgICAgICAgIGxldCBjb3VudHJ5ID0gYmlsbGluZ0RhdGE/LmNvdW50cnk7XG4gICAgICAgICAgICBpZiAoIWNvdW50cnkpIHtcbiAgICAgICAgICAgICAgICBjb3VudHJ5ID0gd2NTZXR0aW5ncz8uYmFzZUxvY2F0aW9uLmNvdW50cnk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RmlsdGVyS2V5ID0gY3VycmVuY3lDb2RlICsgXCItXCIgKyBjb3VudHJ5O1xuXG4gICAgICAgICAgICBjcmVkaXRjYXJkU2VsZWN0ZWRFdmVudCgpO1xuXG4gICAgICAgICAgICBpZiAoIWNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzLmhhc093blByb3BlcnR5KGN1cnJlbnRGaWx0ZXJLZXkpKSB7XG4gICAgICAgICAgICAgICAgY2FjaGVkQXZhaWxhYmxlR2F0ZXdheXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzLFxuICAgICAgICAgICAgICAgICAgICAuLi5hdmFpbGFibGVHYXRld2F5c1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChhdmFpbGFibGVHYXRld2F5cy5oYXNPd25Qcm9wZXJ0eShjdXJyZW50RmlsdGVyS2V5KSAmJiBhdmFpbGFibGVHYXRld2F5c1tjdXJyZW50RmlsdGVyS2V5XS5oYXNPd25Qcm9wZXJ0eShpdGVtLm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjYWNoZWRBdmFpbGFibGVHYXRld2F5cy5oYXNPd25Qcm9wZXJ0eShjdXJyZW50RmlsdGVyS2V5KSAmJiBjYWNoZWRBdmFpbGFibGVHYXRld2F5c1tjdXJyZW50RmlsdGVyS2V5XS5oYXNPd25Qcm9wZXJ0eShpdGVtLm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSxcbiAgICAgICAgYXJpYUxhYmVsOiBpdGVtLmFyaWFMYWJlbCxcbiAgICAgICAgc3VwcG9ydHM6IHtcbiAgICAgICAgICAgIGZlYXR1cmVzOiBpdGVtLnN1cHBvcnRzLFxuICAgICAgICB9LFxuICAgIH07XG59XG5leHBvcnQgZGVmYXVsdCBtb2xsaWVQYXltZW50TWV0aG9kXG5cbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuXHRcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiaW1wb3J0IG1vbGxpZVBheW1lbnRNZXRob2QgZnJvbSAnLi9ibG9ja3MvbW9sbGllUGF5bWVudE1ldGhvZCdcbmltcG9ydCBBcHBsZVBheUJ1dHRvbkNvbXBvbmVudCBmcm9tICcuL2Jsb2Nrcy9BcHBsZVBheUJ1dHRvbkNvbXBvbmVudCdcbmltcG9ydCBBcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCBmcm9tICcuL2Jsb2Nrcy9BcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCdcblxuKFxuICAgIGZ1bmN0aW9uICh7bW9sbGllQmxvY2tEYXRhLCB3YywgXywgalF1ZXJ5fSkge1xuICAgICAgICBpZiAoXy5pc0VtcHR5KG1vbGxpZUJsb2NrRGF0YSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHtyZWdpc3RlclBheW1lbnRNZXRob2R9ID0gd2Mud2NCbG9ja3NSZWdpc3RyeTtcbiAgICAgICAgY29uc3Qge2RlZmF1bHRGaWVsZHN9ID0gd2Mud2NTZXR0aW5ncy5hbGxTZXR0aW5ncztcbiAgICAgICAgY29uc3Qge2FqYXhVcmwsIGZpbHRlcnMsIGdhdGV3YXlEYXRhLCBhdmFpbGFibGVHYXRld2F5c30gPSBtb2xsaWVCbG9ja0RhdGEuZ2F0ZXdheURhdGE7XG4gICAgICAgIGNvbnN0IHt1c2VFZmZlY3R9ID0gd3AuZWxlbWVudDtcbiAgICAgICAgY29uc3QgaXNBcHBsZVNlc3Npb24gPSB0eXBlb2Ygd2luZG93LkFwcGxlUGF5U2Vzc2lvbiA9PT0gXCJmdW5jdGlvblwiXG5cbiAgICAgICAgZnVuY3Rpb24gZ2V0UGhvbmVGaWVsZCgpIHtcbiAgICAgICAgICAgIGNvbnN0IHBob25lRmllbGREYXRhc2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW2RhdGEtc2hvdy1waG9uZS1maWVsZF0nKTtcbiAgICAgICAgICAgIGlmICghcGhvbmVGaWVsZERhdGFzZXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwaG9uZUZpZWxkRGF0YXNldC5kYXRhc2V0LnNob3dQaG9uZUZpZWxkICE9PSBcImZhbHNlXCJcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbXBhbnlOYW1lU3RyaW5nID0gZGVmYXVsdEZpZWxkcy5jb21wYW55LmxhYmVsXG4gICAgICAgIGNvbnN0IGlzUGhvbmVGaWVsZFZpc2libGUgPSBnZXRQaG9uZUZpZWxkKCk7XG4gICAgICAgIGNvbnN0IHBob25lU3RyaW5nID0gZGVmYXVsdEZpZWxkcy5waG9uZS5sYWJlbFxuICAgICAgICBsZXQgcmVxdWlyZWRGaWVsZHMgPSB7XG4gICAgICAgICAgICAnY29tcGFueU5hbWVTdHJpbmcnOiBjb21wYW55TmFtZVN0cmluZyxcbiAgICAgICAgICAgICdwaG9uZVN0cmluZyc6IHBob25lU3RyaW5nLFxuICAgICAgICB9XG4gICAgICAgIGdhdGV3YXlEYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBsZXQgcmVnaXN0ZXIgPSAoKSA9PiByZWdpc3RlclBheW1lbnRNZXRob2QobW9sbGllUGF5bWVudE1ldGhvZCh1c2VFZmZlY3QsIGFqYXhVcmwsIGZpbHRlcnMsIGdhdGV3YXlEYXRhLCBhdmFpbGFibGVHYXRld2F5cywgaXRlbSwgalF1ZXJ5LCByZXF1aXJlZEZpZWxkcywgaXNQaG9uZUZpZWxkVmlzaWJsZSkpO1xuICAgICAgICAgICAgaWYgKGl0ZW0ubmFtZSA9PT0gJ21vbGxpZV93Y19nYXRld2F5X2FwcGxlcGF5Jykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHtpc0V4cHJlc3NFbmFibGVkfSA9IGl0ZW07XG4gICAgICAgICAgICAgICAgaWYgKChpc0FwcGxlU2Vzc2lvbiAmJiB3aW5kb3cuQXBwbGVQYXlTZXNzaW9uLmNhbk1ha2VQYXltZW50cygpKSkge1xuICAgICAgICAgICAgICAgICAgICByZWdpc3RlcigpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNFeHByZXNzRW5hYmxlZCAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHtyZWdpc3RlckV4cHJlc3NQYXltZW50TWV0aG9kfSA9IHdjLndjQmxvY2tzUmVnaXN0cnk7XG4gICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyRXhwcmVzc1BheW1lbnRNZXRob2Qoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ21vbGxpZV93Y19nYXRld2F5X2FwcGxlcGF5X2V4cHJlc3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdBcHBsZSBQYXkgRXhwcmVzcyBidXR0b24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdBcHBsZSBQYXkgRXhwcmVzcyBidXR0b24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogPEFwcGxlUGF5QnV0dG9uQ29tcG9uZW50Lz4sXG4gICAgICAgICAgICAgICAgICAgICAgICBlZGl0OiA8QXBwbGVQYXlCdXR0b25FZGl0b3JDb21wb25lbnQvPixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyaWFMYWJlbDogJ0FwcGxlIFBheScsXG4gICAgICAgICAgICAgICAgICAgICAgICBjYW5NYWtlUGF5bWVudDogKCkgPT4gdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheW1lbnRNZXRob2RJZDogJ21vbGxpZV93Y19nYXRld2F5X2FwcGxlcGF5JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGV3YXlJZDogJ21vbGxpZV93Y19nYXRld2F5X2FwcGxlcGF5JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBvcnRzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXM6IFsncHJvZHVjdHMnXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogWydoZWlnaHQnLCAnYm9yZGVyUmFkaXVzJ11cbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlZ2lzdGVyKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbikod2luZG93LCB3YylcbiJdLCJuYW1lcyI6WyJjcmVhdGVBcHBsZUVycm9ycyIsImVycm9ycyIsImVycm9yTGlzdCIsIl9pdGVyYXRvciIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiX3N0ZXAiLCJzIiwibiIsImRvbmUiLCJlcnJvciIsInZhbHVlIiwiX2Vycm9yJGNvbnRhY3RGaWVsZCIsImNvbnRhY3RGaWVsZCIsIl9lcnJvciRjb2RlIiwiY29kZSIsIl9lcnJvciRtZXNzYWdlIiwibWVzc2FnZSIsImFwcGxlRXJyb3IiLCJBcHBsZVBheUVycm9yIiwicHVzaCIsImVyciIsImUiLCJmIiwicmVxdWVzdCIsImNvdW50cnlDb2RlIiwiY3VycmVuY3lDb2RlIiwidG90YWxMYWJlbCIsInN1YnRvdGFsIiwic3VwcG9ydGVkTmV0d29ya3MiLCJtZXJjaGFudENhcGFiaWxpdGllcyIsInNoaXBwaW5nVHlwZSIsInJlcXVpcmVkQmlsbGluZ0NvbnRhY3RGaWVsZHMiLCJyZXF1aXJlZFNoaXBwaW5nQ29udGFjdEZpZWxkcyIsInRvdGFsIiwibGFiZWwiLCJhbW91bnQiLCJ0eXBlIiwiQXBwbGVQYXlCdXR0b25Db21wb25lbnQiLCJfcmVmIiwiX3JlZiRidXR0b25BdHRyaWJ1dGVzIiwiYnV0dG9uQXR0cmlidXRlcyIsIm1vbGxpZUFwcGxlUGF5QmxvY2tEYXRhQ2FydCIsIndpbmRvdyIsIm1vbGxpZUJsb2NrRGF0YSIsIm5vbmNlIiwiZG9jdW1lbnQiLCJnZXRFbGVtZW50QnlJZCIsInVwZGF0ZWRDb250YWN0SW5mbyIsInJlZGlyZWN0aW9uVXJsIiwiX21vbGxpZUFwcGxlUGF5QmxvY2tEIiwicHJvZHVjdCIsIl9tb2xsaWVBcHBsZVBheUJsb2NrRDIiLCJuZWVkU2hpcHBpbmciLCJfbW9sbGllQXBwbGVQYXlCbG9ja0QzIiwic2hvcCIsIl9tb2xsaWVBcHBsZVBheUJsb2NrRDQiLCJfbW9sbGllQXBwbGVQYXlCbG9ja0Q1IiwiYWpheFVybCIsInN0eWxlIiwiaGVpZ2h0IiwiY29uY2F0IiwiYm9yZGVyUmFkaXVzIiwiZmluZFNlbGVjdGVkU2hpcHBpbmdNZXRob2QiLCJzaGlwcGluZ1JhdGVzIiwic2hpcHBpbmdSYXRlIiwiZmluZCIsInNoaXBwaW5nTWV0aG9kIiwic2VsZWN0ZWQiLCJhcHBsZUZvcm1hdHRlZFJhdGUiLCJkZXRhaWwiLCJuYW1lIiwiaWRlbnRpZmllciIsInJhdGVfaWQiLCJhcHBsZVBheVNlc3Npb24iLCJfc3RvcmUkZ2V0U2hpcHBpbmdSYXQiLCJzZXNzaW9uIiwiQXBwbGVQYXlTZXNzaW9uIiwic3RvcmUiLCJ3cCIsImRhdGEiLCJzZWxlY3QiLCJnZXRTaGlwcGluZ1JhdGVzIiwic2hpcHBpbmdfcmF0ZXMiLCJzZWxlY3RlZFNoaXBwaW5nTWV0aG9kIiwibGVuZ3RoIiwib25zaGlwcGluZ21ldGhvZHNlbGVjdGVkIiwiZXZlbnQiLCJfdGhpcyIsImpRdWVyeSIsImFqYXgiLCJ1cmwiLCJtZXRob2QiLCJhY3Rpb24iLCJjYWxsZXJQYWdlIiwic2ltcGxpZmllZENvbnRhY3QiLCJzdWNjZXNzIiwiYXBwbGVQYXlTaGlwcGluZ01ldGhvZFVwZGF0ZSIsInRleHRTdGF0dXMiLCJqcVhIUiIsInJlc3BvbnNlIiwiY29tcGxldGVTaGlwcGluZ01ldGhvZFNlbGVjdGlvbiIsImVycm9yVGhyb3duIiwiY29uc29sZSIsIndhcm4iLCJhYm9ydCIsIm9uc2hpcHBpbmdjb250YWN0c2VsZWN0ZWQiLCJfdGhpczIiLCJzaGlwcGluZ0NvbnRhY3QiLCJhcHBsZVBheVNoaXBwaW5nQ29udGFjdFVwZGF0ZSIsIm5ld1NoaXBwaW5nTWV0aG9kcyIsImNvbXBsZXRlU2hpcHBpbmdDb250YWN0U2VsZWN0aW9uIiwib252YWxpZGF0ZW1lcmNoYW50IiwiYXBwbGVQYXlWYWxpZGF0ZU1lcmNoYW50RXZlbnQiLCJ2YWxpZGF0aW9uVXJsIiwidmFsaWRhdGlvblVSTCIsIm1lcmNoYW50U2Vzc2lvbiIsImNvbXBsZXRlTWVyY2hhbnRWYWxpZGF0aW9uIiwiSlNPTiIsInBhcnNlIiwib25wYXltZW50YXV0aG9yaXplZCIsIkFwcGxlUGF5UGF5bWVudCIsIl9BcHBsZVBheVBheW1lbnQkcGF5bSIsInBheW1lbnQiLCJiaWxsaW5nQ29udGFjdCIsInRva2VuIiwiZ2l2ZW5OYW1lIiwiZmFtaWx5TmFtZSIsImFkZHJlc3NMaW5lcyIsInBvc3RhbENvZGUiLCJsb2NhbGl0eSIsImFkbWluaXN0cmF0aXZlQXJlYSIsInBob25lTnVtYmVyIiwiZW1haWxBZGRyZXNzIiwiYXV0aG9yaXphdGlvblJlc3VsdCIsInJlc3VsdCIsImNvbXBsZXRlUGF5bWVudCIsImxvY2F0aW9uIiwiaHJlZiIsImJlZ2luIiwiUmVhY3QiLCJjcmVhdGVFbGVtZW50IiwiaWQiLCJjbGFzc05hbWUiLCJvbkNsaWNrIiwicHJldmVudERlZmF1bHQiLCJBcHBsZVBheUJ1dHRvbkVkaXRvckNvbXBvbmVudCIsImNhY2hlZEF2YWlsYWJsZUdhdGV3YXlzIiwiZm9ybWF0UHJpY2VMaWtlV2MiLCJwcmljZSIsIndjU2V0dGluZ3MiLCJjdXJyZW5jeSIsInByaWNlRm9ybWF0IiwicmVwbGFjZSIsInN5bWJvbCIsInRvRml4ZWQiLCJwcmVjaXNpb24iLCJkZWNpbWFsU2VwYXJhdG9yIiwic2V0QXZhaWxhYmxlR2F0ZXdheXMiLCJjb3VudHJ5IiwiX29iamVjdFNwcmVhZCIsInVzZU1vbGxpZUF2YWlsYWJsZUdhdGV3YXlzIiwiYmlsbGluZyIsImNhcnRUb3RhbCIsImZpbHRlcnMiLCJfd2NTZXR0aW5ncyIsImJhc2VMb2NhdGlvbiIsImVsZW1lbnQiLCJ1c2VFZmZlY3QiLCJjdXJyZW50RmlsdGVyS2V5IiwiaGFzT3duUHJvcGVydHkiLCJmZXRjaCIsImhlYWRlcnMiLCJib2R5IiwiVVJMU2VhcmNoUGFyYW1zIiwiYmlsbGluZ0NvdW50cnkiLCJwYXltZW50TG9jYWxlIiwidGhlbiIsImpzb24iLCJjYXJ0VG90YWxzIiwiZ2V0Q2FydFRvdGFscyIsImRpc3BhdGNoIiwic2V0Q2FydERhdGEiLCJNb2xsaWVHYXRld2F5VXBkYXRlciIsIm9uU3VibWl0TG9jYWwiLCJhY3RpdmVQYXltZW50TWV0aG9kTG9jYWwiLCJjcmVkaXRDYXJkU2VsZWN0ZWQiLCJFdmVudCIsImJ1YmJsZXMiLCJNb2xsaWVDb21wb25lbnQiLCJwcm9wcyIsIm9uU3VibWl0IiwiYWN0aXZlUGF5bWVudE1ldGhvZCIsIml0ZW0iLCJlbWl0UmVzcG9uc2UiLCJldmVudFJlZ2lzdHJhdGlvbiIsInJlcXVpcmVkRmllbGRzIiwic2hpcHBpbmdEYXRhIiwiaXNQaG9uZUZpZWxkVmlzaWJsZSIsInJlc3BvbnNlVHlwZXMiLCJvblBheW1lbnRTZXR1cCIsIm9uQ2hlY2tvdXRWYWxpZGF0aW9uIiwiX3dwJGVsZW1lbnQkdXNlU3RhdGUiLCJ1c2VTdGF0ZSIsIl93cCRlbGVtZW50JHVzZVN0YXRlMiIsIl9zbGljZWRUb0FycmF5Iiwic2VsZWN0ZWRJc3N1ZXIiLCJzZWxlY3RJc3N1ZXIiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTMiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTQiLCJpbnB1dFBob25lIiwic2VsZWN0UGhvbmUiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTUiLCJfd3AkZWxlbWVudCR1c2VTdGF0ZTYiLCJpbnB1dEJpcnRoZGF0ZSIsInNlbGVjdEJpcnRoZGF0ZSIsIl93cCRlbGVtZW50JHVzZVN0YXRlNyIsIl93cCRlbGVtZW50JHVzZVN0YXRlOCIsImlucHV0Q29tcGFueSIsInNlbGVjdENvbXBhbnkiLCJpc3N1ZXJLZXkiLCJjb21wYW55TmFtZVN0cmluZyIsInBob25lU3RyaW5nIiwiZ2V0UGhvbmVGaWVsZCIsInNoaXBwaW5nUGhvbmUiLCJiaWxsaW5nUGhvbmUiLCJ1cGRhdGVUb3RhbExhYmVsIiwibmV3VG90YWwiLCJ0b3RhbFNwYW4iLCJyZXBsYWNlV2l0aCIsInVwZGF0ZVRheGVzTGFiZWwiLCJoaWRlRmVlIiwiZmVlIiwiaGlkZSIsInRvdGFsVGF4IiwiZmVlTWFya3VwIiwicmVwbGFjZUZlZSIsIm5ld0ZlZSIsImluc2VydE5ld0ZlZSIsImFmdGVyIiwiaGFuZGxlRmVlcyIsImRvY3VtZW50RWxlbWVudCIsImRpc3BhdGNoRXZlbnQiLCJjb21wbGV0ZSIsIm9uUHJvY2Vzc2luZ1BheW1lbnQiLCJfZGVmaW5lUHJvcGVydHkiLCJwYXltZW50X21ldGhvZCIsInBheW1lbnRfbWV0aG9kX3RpdGxlIiwidGl0bGUiLCJ0b2tlblZhbCIsInZhbCIsImNhcmRUb2tlbiIsIlNVQ0NFU1MiLCJtZXRhIiwicGF5bWVudE1ldGhvZERhdGEiLCJ1bnN1YnNjcmliZVBheW1lbnRQcm9jZXNzaW5nIiwiY29tcGFueUxhYmVsIiwiaGlkZUNvbXBhbnlGaWVsZCIsImNvbXBhbnlQbGFjZWhvbGRlciIsImlzQ29tcGFueUVtcHR5IiwiYmlsbGluZ0RhdGEiLCJjb21wYW55Iiwic2hpcHBpbmdBZGRyZXNzIiwidW5zdWJzY3JpYmVQcm9jZXNzaW5nIiwiZXJyb3JNZXNzYWdlIiwiX2dldFBob25lRmllbGQkbGFiZWxzIiwiX2dldFBob25lRmllbGQiLCJwaG9uZUxhYmVsIiwibGFiZWxzIiwiaW5uZXJUZXh0IiwicGhvbmVQbGFjZWhvbGRlciIsImlzUGhvbmVFbXB0eSIsInBob25lIiwiaXNCaXJ0aGRhdGVWYWxpZCIsInRvZGF5IiwiRGF0ZSIsImJpcnRoZGF0ZSIsInVwZGF0ZUlzc3VlciIsInRhcmdldCIsInVwZGF0ZUNvbXBhbnkiLCJ1cGRhdGVQaG9uZSIsInVwZGF0ZUJpcnRoZGF0ZSIsImZpZWxkTWFya3VwIiwiZmllbGRUeXBlIiwicGxhY2Vob2xkZXIiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJjbGFzcyIsImh0bWxGb3IiLCJkYW5nZXJvdXNseVNldElubmVySFRNTCIsIl9faHRtbCIsIm9uQ2hhbmdlIiwiaXNzdWVycyIsImNvbnRlbnQiLCJiaWxsaW5nQ29tcGFueUZpZWxkIiwicXVlcnlTZWxlY3RvciIsInNoaXBwaW5nQ29tcGFueUZpZWxkIiwiaXNCaWxsaW5nQ29tcGFueVJlcXVpcmVkIiwiaGFzQXR0cmlidXRlIiwiaXNTaGlwcGluZ0NvbXBhbnlSZXF1aXJlZCIsImNvbXBhbnlGaWVsZCIsIkZyYWdtZW50IiwiY291bnRyeUNvZGVzIiwiQkUiLCJOTCIsIkRFIiwiQVQiLCJiaXJ0aGRhdGVGaWVsZCIsImJpcnRoZGF0ZVBsYWNlaG9sZGVyIiwicGhvbmVGaWVsZCIsIkxhYmVsIiwiX3JlZjIiLCJjYXJ0RGF0YSIsInVzZVNlbGVjdCIsImdldENhcnREYXRhIiwidG90YWxfcHJpY2UiLCJiaWxsaW5nQWRkcmVzcyIsIm1vbGxpZVBheW1lbnRNZXRob2QiLCJnYXRld2F5RGF0YSIsImF2YWlsYWJsZUdhdGV3YXlzIiwiaXNDb21wYW55RmllbGRWaXNpYmxlIiwiYWRkRXZlbnRMaXN0ZW5lciIsImNyZWRpdGNhcmRTZWxlY3RlZEV2ZW50IiwiZWRpdCIsInBheW1lbnRNZXRob2RJZCIsImNhbk1ha2VQYXltZW50IiwiX3JlZjMiLCJfIiwiaXNFbXB0eSIsImFsbG93ZWRDb3VudHJpZXMiLCJpbmNsdWRlcyIsImN1cnJlbmN5X2NvZGUiLCJfd2NTZXR0aW5nczIiLCJhcmlhTGFiZWwiLCJzdXBwb3J0cyIsImZlYXR1cmVzIiwid2MiLCJyZWdpc3RlclBheW1lbnRNZXRob2QiLCJ3Y0Jsb2Nrc1JlZ2lzdHJ5IiwiZGVmYXVsdEZpZWxkcyIsImFsbFNldHRpbmdzIiwiX21vbGxpZUJsb2NrRGF0YSRnYXRlIiwiaXNBcHBsZVNlc3Npb24iLCJwaG9uZUZpZWxkRGF0YXNldCIsImRhdGFzZXQiLCJzaG93UGhvbmVGaWVsZCIsImZvckVhY2giLCJyZWdpc3RlciIsImlzRXhwcmVzc0VuYWJsZWQiLCJjYW5NYWtlUGF5bWVudHMiLCJyZWdpc3RlckV4cHJlc3NQYXltZW50TWV0aG9kIiwiZGVzY3JpcHRpb24iLCJnYXRld2F5SWQiXSwic291cmNlUm9vdCI6IiJ9 -
mollie-payments-for-woocommerce/trunk/readme.txt
r3242454 r3262577 1 1 === Mollie Payments for WooCommerce === 2 2 Contributors: daanvm, danielhuesken, davdebcom, dinamiko, syde, l.vangunst, ndijkstra, robin-mollie, wido, carmen222, inpsyde-maticluznar 3 Tags: mollie, payments, payment gateway, woocommerce, credit card, apple pay, ideal, bancontact, klarna, sofort, woocommerce subscriptions4 Requires at least: 3.83 Tags: mollie, woocommerce, payments, ecommerce, credit card 4 Requires at least: 5.0 5 5 Tested up to: 6.7 6 6 Stable tag: 7.10.0 7 Requires PHP: 7. 27 Requires PHP: 7.4 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 197 197 = Minimum Requirements = 198 198 199 * PHP version 7. 2or greater199 * PHP version 7.4 or greater 200 200 * PHP extensions enabled: cURL, JSON 201 * WordPress 3.8or greater201 * WordPress 5.0 or greater 202 202 * WooCommerce 3.9 or greater 203 203 * Mollie account … … 226 226 227 227 == Changelog == 228 229 = 8.0.0 - 27-03-2025 = 230 231 * Feature Flag - Klarna, Riverty and Billie can be used with Payments API 232 * Feature - Added support for Mollie's new Payments API features 233 * Fixed - Notice for missing value of cardToken 234 * Fixed - ltrim error on Apple Pay notice with php 8.2 (author @kylwes) 235 * Fixed - Logged URL should be same as used in future logic (author @tombroucke) 228 236 229 237 = 7.10.0 - 18-02-2025 = … … 241 249 = 7.9.1 - 22-01-2025 = 242 250 243 * Feature :Style Apple Pay express button via Checkout block244 * Fixed :Notice `_load_textdomain_just_in_time` due to early translation loading245 * Fixed :Company Name input field not saved in Order when Billie was enabled246 * Fixed :Mollie Payment methods may not load on Checkout block247 * Fixed :Mollie Payment methods may disappear from Checkout block when changing billing country248 * Fixed :Mollie Components are not enabled by default on new installations251 * Feature - Style Apple Pay express button via Checkout block 252 * Fixed - Notice `_load_textdomain_just_in_time` due to early translation loading 253 * Fixed - Company Name input field not saved in Order when Billie was enabled 254 * Fixed - Mollie Payment methods may not load on Checkout block 255 * Fixed - Mollie Payment methods may disappear from Checkout block when changing billing country 256 * Fixed - Mollie Components are not enabled by default on new installations 249 257 250 258 = 7.9.0 - 18-11-2024 = … … 257 265 * Fixed - Bank Transfer payment details displayed in one line on order-received page 258 266 259 260 267 = 7.8.2 - 08-09-2024 = 261 268 262 269 * Fixed - Subscription renewal status on-hold instead of active 263 264 270 265 271 = 7.8.1 - 07-09-2024 = -
mollie-payments-for-woocommerce/trunk/src/Activation/ActivationModule.php
r3226701 r3262577 17 17 private $pluginVersion; 18 18 /** 19 * ActivationModule constructor.20 */21 public function __construct($baseFile, $pluginVersion)22 {23 $this->baseFile = $baseFile;24 $this->pluginVersion = $pluginVersion;25 }26 /**27 19 * @param ContainerInterface $container 28 20 * … … 31 23 public function run(ContainerInterface $container): bool 32 24 { 25 $this->pluginVersion = $container->get('shared.plugin_version'); 26 $this->baseFile = \M4W_FILE; 33 27 add_action('init', [$this, 'pluginInit']); 34 28 add_action('admin_init', [$this, 'mollieWcNoticeApiKeyMissing']); -
mollie-payments-for-woocommerce/trunk/src/Assets/AssetsModule.php
r3226701 r3262577 23 23 return \true; 24 24 } 25 public function enqueueBlockCheckoutScripts(Data $dataService, array $gatewayInstances ): void25 public function enqueueBlockCheckoutScripts(Data $dataService, array $gatewayInstances, ContainerInterface $container): void 26 26 { 27 27 if (!has_block('woocommerce/checkout')) { … … 31 31 wp_enqueue_style('mollie-gateway-icons'); 32 32 wp_enqueue_style('mollie-block-custom-field'); 33 \Mollie\WooCommerce\Assets\MollieCheckoutBlocksSupport::localizeWCBlocksData($dataService, $gatewayInstances );33 \Mollie\WooCommerce\Assets\MollieCheckoutBlocksSupport::localizeWCBlocksData($dataService, $gatewayInstances, $container); 34 34 } 35 35 public function registerButtonsBlockScripts(string $pluginUrl, string $pluginPath): void … … 145 145 * Enqueue Frontend only scripts 146 146 * 147 * @param $container Container147 * @param ContainerInterface $container 148 148 * @return void 149 149 */ … … 195 195 $object_name = 'mollieComponentsSettings'; 196 196 $data = ['merchantProfileId' => $merchantProfileId, 'options' => ['locale' => $locale, 'testmode' => $settingsHelper->isTestModeEnabled()], 'enabledGateways' => $gatewayNames, 'componentsSettings' => $mollieComponentsStylesGateways, 'componentsAttributes' => [['name' => 'cardHolder', 'label' => esc_html__('Name on card', 'mollie-payments-for-woocommerce')], ['name' => 'cardNumber', 'label' => esc_html__('Card number', 'mollie-payments-for-woocommerce')], ['name' => 'expiryDate', 'label' => esc_html__('Expiry date', 'mollie-payments-for-woocommerce')], ['name' => 'verificationCode', 'label' => esc_html__('CVC/CVV', 'mollie-payments-for-woocommerce')]], 'messages' => ['defaultErrorMessage' => esc_html__('An unknown error occurred, please check the card fields.', 'mollie-payments-for-woocommerce')], 'isCheckout' => is_checkout(), 'isCheckoutPayPage' => is_checkout_pay_page()]; 197 if (has_block("woocommerce/checkout") ) {197 if (has_block("woocommerce/checkout") && !is_wc_endpoint_url('order-pay')) { 198 198 wp_enqueue_script('mollie-components-blocks'); 199 199 wp_localize_script('mollie-components-blocks', $object_name, $data); … … 288 288 /** @var Settings */ 289 289 $settingsHelper = $container->get('settings.settings_helper'); 290 $gatewayInstances = $container->get(' gateway.instances');291 add_action('woocommerce_blocks_loaded', function () {292 woocommerce_store_api_register_update_callback(['namespace' => 'mollie-payments-for-woocommerce', 'callback' => function () {290 $gatewayInstances = $container->get('__deprecated.gateway_helpers'); 291 add_action('woocommerce_blocks_loaded', static function () { 292 woocommerce_store_api_register_update_callback(['namespace' => 'mollie-payments-for-woocommerce', 'callback' => static function () { 293 293 // Do nothing 294 294 }]); … … 296 296 /** Add support to Mollie blocks for WooCommerce checkout blocks functionality */ 297 297 //https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md#putting-it-all-together 298 add_action('woocommerce_blocks_loaded', function () use ($dataService, $gatewayInstances, $pluginUrl, $pluginPath, $hasBlocksEnabled ) {298 add_action('woocommerce_blocks_loaded', function () use ($dataService, $gatewayInstances, $pluginUrl, $pluginPath, $hasBlocksEnabled, $container) { 299 299 if ($hasBlocksEnabled && is_admin() && class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) { 300 add_action('woocommerce_blocks_payment_method_type_registration', function (PaymentMethodRegistry $paymentMethodRegistry) use ($dataService, $gatewayInstances, $pluginUrl, $pluginPath ) {301 $paymentMethodRegistry->register(new \Mollie\WooCommerce\Assets\MollieCheckoutBlocksSupport($dataService, $gatewayInstances, $this->getPluginUrl($pluginUrl, '/public/js/mollieBlockIndex.min.js'), (string) filemtime($this->getPluginPath($pluginPath, '/public/js/mollieBlockIndex.min.js')) ));300 add_action('woocommerce_blocks_payment_method_type_registration', function (PaymentMethodRegistry $paymentMethodRegistry) use ($dataService, $gatewayInstances, $pluginUrl, $pluginPath, $container) { 301 $paymentMethodRegistry->register(new \Mollie\WooCommerce\Assets\MollieCheckoutBlocksSupport($dataService, $gatewayInstances, $this->getPluginUrl($pluginUrl, '/public/js/mollieBlockIndex.min.js'), (string) filemtime($this->getPluginPath($pluginPath, '/public/js/mollieBlockIndex.min.js')), $container)); 302 302 }); 303 303 } … … 318 318 if ($hasBlocksEnabled) { 319 319 /** @var array */ 320 $gatewayInstances = $container->get(' gateway.instances');320 $gatewayInstances = $container->get('__deprecated.gateway_helpers'); 321 321 self::registerBlockScripts($pluginUrl, $pluginPath); 322 add_action('wp_enqueue_scripts', function () use ($dataService, $gatewayInstances ) {323 $this->enqueueBlockCheckoutScripts($dataService, $gatewayInstances );322 add_action('wp_enqueue_scripts', function () use ($dataService, $gatewayInstances, $container) { 323 $this->enqueueBlockCheckoutScripts($dataService, $gatewayInstances, $container); 324 324 }); 325 325 $this->registerButtonsBlockScripts($pluginUrl, $pluginPath); -
mollie-payments-for-woocommerce/trunk/src/Assets/MollieCheckoutBlocksSupport.php
r3226701 r3262577 4 4 5 5 use Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType; 6 use Mollie\WooCommerce\Gateway\MolliePaymentGateway; 7 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayI; 6 use Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\DefaultFieldsStrategy; 8 7 use Mollie\WooCommerce\PaymentMethods\PaymentMethodI; 9 8 use Mollie\WooCommerce\Shared\Data; 9 use Mollie\Psr\Container\ContainerInterface; 10 10 final class MollieCheckoutBlocksSupport extends AbstractPaymentMethodType 11 11 { … … 22 22 /** @var string $registerScriptVersion */ 23 23 protected $registerScriptVersion; 24 public function __construct(Data $dataService, array $gatewayInstances, string $registerScriptUrl, string $registerScriptVersion) 24 private ContainerInterface $container; 25 public function __construct(Data $dataService, array $gatewayInstances, string $registerScriptUrl, string $registerScriptVersion, ContainerInterface $container) 25 26 { 26 27 $this->dataService = $dataService; … … 28 29 $this->registerScriptUrl = $registerScriptUrl; 29 30 $this->registerScriptVersion = $registerScriptVersion; 31 $this->container = $container; 30 32 } 31 33 public function initialize() … … 40 42 { 41 43 wp_register_script(self::$scriptHandle, $this->registerScriptUrl, ['wc-blocks-registry', 'underscore', 'jquery'], $this->registerScriptVersion, \true); 42 self::localizeWCBlocksData($this->dataService, $this->gatewayInstances );44 self::localizeWCBlocksData($this->dataService, $this->gatewayInstances, $this->container); 43 45 return [self::$scriptHandle]; 44 46 } 45 public static function localizeWCBlocksData($dataService, $gatewayInstances )47 public static function localizeWCBlocksData($dataService, $gatewayInstances, $container) 46 48 { 47 49 wp_enqueue_style('mollie-applepaydirect'); 48 wp_localize_script(self::$scriptHandle, 'mollieBlockData', ['gatewayData' => self::gatewayDataForWCBlocks($dataService, $gatewayInstances ), 'mollieApplePayBlockDataCart' => $dataService->mollieApplePayBlockDataCart()]);50 wp_localize_script(self::$scriptHandle, 'mollieBlockData', ['gatewayData' => self::gatewayDataForWCBlocks($dataService, $gatewayInstances, $container), 'mollieApplePayBlockDataCart' => $dataService->mollieApplePayBlockDataCart()]); 49 51 } 50 public static function gatewayDataForWCBlocks(Data $dataService, array $ gatewayInstances): array52 public static function gatewayDataForWCBlocks(Data $dataService, array $deprecatedGatewayHelpers, ContainerInterface $container): array 51 53 { 52 54 $filters = $dataService->wooCommerceFiltersForCheckout(); … … 54 56 $availablePaymentMethods = []; 55 57 /** 56 * @var MolliePaymentGatewayI$gateway58 * @var $gateway 57 59 * psalm-suppress UnusedForeachValue 58 60 */ … … 65 67 $filterKey = "{$filters['amount']['currency']}-{$filters['billingCountry']}"; 66 68 foreach ($availableGateways as $key => $gateway) { 67 $availablePaymentMethods[$filterKey][$key] = $gateway->paymentMethod()->getProperty('id'); 69 $gatewayId = $gateway->id; 70 $methodId = substr($gatewayId, strrpos($gatewayId, '_') + 1); 71 $availablePaymentMethods[$filterKey][$key] = $methodId; 68 72 } 69 73 } 70 74 $dataToScript = ['ajaxUrl' => admin_url('admin-ajax.php'), 'filters' => ['currency' => isset($filters['amount']['currency']) ? $filters['amount']['currency'] : \false, 'cartTotal' => isset($filters['amount']['value']) ? $filters['amount']['value'] : \false, 'paymentLocale' => isset($filters['locale']) ? $filters['locale'] : \false, 'billingCountry' => isset($filters['billingCountry']) ? $filters['billingCountry'] : \false]]; 75 $paymentGateways = WC()->payment_gateways()->payment_gateways(); 71 76 $gatewayData = []; 72 $isSepaEnabled = isset($gatewayInstances['mollie_wc_gateway_directdebit']) && $gatewayInstances['mollie_wc_gateway_directdebit']->enabled === 'yes'; 73 /** @var MolliePaymentGateway $gateway */ 74 foreach ($gatewayInstances as $gatewayKey => $gateway) { 75 $method = $gateway->paymentMethod(); 77 $isSepaEnabled = isset($deprecatedGatewayHelpers['mollie_wc_gateway_directdebit']) && $deprecatedGatewayHelpers['mollie_wc_gateway_directdebit']->enabled === 'yes'; 78 /** @var PaymentGateway $gateway */ 79 foreach ($paymentGateways as $gatewayKey => $gateway) { 80 if (substr($gateway->id, 0, 18) !== 'mollie_wc_gateway_') { 81 continue; 82 } 83 $deprecatedGateway = $deprecatedGatewayHelpers[$gatewayKey]; 84 $method = $deprecatedGateway->paymentMethod(); 76 85 $gatewayId = is_string($method->getProperty('id')) ? $method->getProperty('id') : ""; 77 86 if ($gateway->enabled !== 'yes' || $gatewayId === 'directdebit' && !is_admin()) { … … 81 90 $issuers = \false; 82 91 if ($method->getProperty('paymentFields') === \true) { 83 $ paymentFieldsService = $method->paymentFieldsService();84 $paymentFieldsS ervice->setStrategy($method);85 $issuers = $ method->paymentFieldsService()->getStrategyMarkup($gateway);92 $className = 'Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\\' . ucfirst($method->getProperty('id')) . 'FieldsStrategy'; 93 $paymentFieldsStrategy = class_exists($className) ? new $className($deprecatedGateway, $gateway->get_description(), $dataService) : new DefaultFieldsStrategy($deprecatedGateway, $gateway->get_description(), $dataService); 94 $issuers = $paymentFieldsStrategy->getFieldMarkup($deprecatedGateway, $dataService); 86 95 } 87 96 if ($gatewayId === 'creditcard') { … … 89 98 $issuers = \false; 90 99 } 91 $title = $method->title( );92 $labelMarkup = "<span style='margin-right: 1em'>{$title}</span>{$gateway-> icon}";100 $title = $method->title($container); 101 $labelMarkup = "<span style='margin-right: 1em'>{$title}</span>{$gateway->get_icon()}"; 93 102 $hasSurcharge = $method->hasSurcharge(); 94 103 $countryCodes = ['BE' => '+32xxxxxxxxx', 'NL' => '+316xxxxxxxx', 'DE' => '+49xxxxxxxxx', 'AT' => '+43xxxxxxxxx']; -
mollie-payments-for-woocommerce/trunk/src/BlockService/CheckoutBlockService.php
r3226701 r3262577 60 60 $filterKey = "{$filters['amount']['currency']}-{$filters['billingCountry']}"; 61 61 foreach ($availableGateways as $key => $gateway) { 62 $availablePaymentMethods[$filterKey][$key] = $gateway->paymentMethod()->getProperty('id');62 $availablePaymentMethods[$filterKey][$key] = str_replace('mollie_wc_gateway_', '', $gateway->id); 63 63 } 64 64 } -
mollie-payments-for-woocommerce/trunk/src/Buttons/ApplePayButton/ResponsesToApple.php
r3191126 r3262577 13 13 protected $logger; 14 14 /** 15 * @var MolliePaymentGatewayI15 * @var 16 16 */ 17 protected $ gateway;17 protected $deprecatedAppleHelper; 18 18 /** 19 19 * ResponsesToApple constructor. 20 20 */ 21 public function __construct(Logger $logger, MolliePaymentGatewayI $appleGateway)21 public function __construct(Logger $logger, $deprecatedAppleHelper) 22 22 { 23 23 $this->logger = $logger; 24 $this-> gateway = $appleGateway;24 $this->deprecatedAppleHelper = $deprecatedAppleHelper; 25 25 } 26 26 /** … … 174 174 { 175 175 $order = wc_get_order($orderId); 176 $redirect_url = $this-> gateway->getReturnRedirectUrlForOrder($order);176 $redirect_url = $this->deprecatedAppleHelper->getReturnRedirectUrlForOrder($order); 177 177 // Add utm_nooverride query string 178 178 $redirect_url = add_query_arg(['utm_nooverride' => 1], $redirect_url); 179 $this->logger->debug(__METHOD__ . sprintf(': Redirect url on return order %s, order %s: %s', $this-> gateway->paymentMethod()->getProperty('id'), $orderId, $redirect_url));179 $this->logger->debug(__METHOD__ . sprintf(': Redirect url on return order %s, order %s: %s', $this->deprecatedAppleHelper->paymentMethod()->getProperty('id'), $orderId, $redirect_url)); 180 180 return $redirect_url; 181 181 } -
mollie-payments-for-woocommerce/trunk/src/Buttons/PayPalButton/PayPalAjaxRequests.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\Buttons\PayPalButton; 5 5 6 use Mollie\Inpsyde\PaymentGateway\PaymentGateway; 6 7 use Mollie\WooCommerce\Gateway\Surcharge; 7 8 use Mollie\WooCommerce\Notice\NoticeInterface; … … 29 30 * @param $gateway 30 31 */ 31 public function __construct( $gateway, NoticeInterface $notice, Logger $logger)32 public function __construct(PaymentGateway $gateway, NoticeInterface $notice, Logger $logger) 32 33 { 33 34 $this->gateway = $gateway; -
mollie-payments-for-woocommerce/trunk/src/Gateway/GatewayModule.php
r3242448 r3262577 7 7 use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController; 8 8 use Automattic\WooCommerce\StoreApi\Exceptions\RouteException; 9 use DateTime;10 9 use Mollie\Inpsyde\Modularity\Module\ExecutableModule; 10 use Mollie\Inpsyde\Modularity\Module\ExtendingModule; 11 11 use Mollie\Inpsyde\Modularity\Module\ModuleClassNameIdTrait; 12 12 use Mollie\Inpsyde\Modularity\Module\ServiceModule; 13 use Mollie\Inpsyde\PaymentGateway\PaymentMethodServiceProviderTrait; 13 14 use Mollie\WooCommerce\BlockService\CheckoutBlockService; 14 use Mollie\WooCommerce\Buttons\ApplePayButton\AppleAjaxRequests;15 15 use Mollie\WooCommerce\Buttons\ApplePayButton\ApplePayDirectHandler; 16 use Mollie\WooCommerce\Buttons\ApplePayButton\ResponsesToApple;17 use Mollie\WooCommerce\Buttons\PayPalButton\DataToPayPal;18 use Mollie\WooCommerce\Buttons\PayPalButton\PayPalAjaxRequests;19 16 use Mollie\WooCommerce\Buttons\PayPalButton\PayPalButtonHandler; 20 17 use Mollie\WooCommerce\Gateway\Voucher\MaybeDisableGateway; 21 use Mollie\WooCommerce\Notice\AdminNotice;22 use Mollie\WooCommerce\Notice\FrontendNotice;23 use Mollie\WooCommerce\Notice\NoticeInterface;24 use Mollie\WooCommerce\Payment\MollieObject;25 use Mollie\WooCommerce\Payment\MollieOrderService;26 use Mollie\WooCommerce\Payment\OrderInstructionsService;27 use Mollie\WooCommerce\Payment\PaymentCheckoutRedirectService;28 use Mollie\WooCommerce\Payment\PaymentFactory;29 use Mollie\WooCommerce\Payment\PaymentFieldsService;30 use Mollie\WooCommerce\Payment\PaymentService;31 18 use Mollie\WooCommerce\PaymentMethods\IconFactory; 32 19 use Mollie\WooCommerce\PaymentMethods\PaymentMethodI; 33 use Mollie\WooCommerce\SDK\Api;34 use Mollie\WooCommerce\SDK\HttpResponse;35 20 use Mollie\WooCommerce\Settings\Settings; 36 21 use Mollie\WooCommerce\Shared\Data; 37 22 use Mollie\WooCommerce\Shared\GatewaySurchargeHandler; 23 use Mollie\WooCommerce\PaymentMethods\Constants; 38 24 use Mollie\WooCommerce\Shared\SharedDataDictionary; 39 use Mollie\WooCommerce\Subscription\MollieSepaRecurringGateway;40 use Mollie\WooCommerce\Subscription\MollieSubscriptionGateway;41 use Mollie\WooCommerce\PaymentMethods\Constants;42 25 use Mollie\Psr\Container\ContainerInterface; 43 use Mollie\Psr\Log\LoggerInterface as Logger; 44 use WP_Post; 45 class GatewayModule implements ServiceModule, ExecutableModule 26 class GatewayModule implements ServiceModule, ExecutableModule, ExtendingModule 46 27 { 47 28 use ModuleClassNameIdTrait; 29 use PaymentMethodServiceProviderTrait; 48 30 public const APPLE_PAY_METHOD_ALLOWED_KEY = 'mollie_apple_pay_method_allowed'; 49 31 public const POST_DATA_KEY = 'post_data'; … … 58 40 const FIELD_IN3_BIRTHDATE = 'billing_birthdate'; 59 41 const GATEWAY_NAME_IN3 = "mollie_wc_gateway_in3"; 60 public function services(): array61 {62 return ['gateway.classnames' => static function (): array {63 return SharedDataDictionary::GATEWAY_CLASSNAMES;64 }, 'gateway.instances' => function (ContainerInterface $container): array {65 return $this->instantiatePaymentMethodGateways($container);66 }, 'gateway.paymentMethods' => static function (ContainerInterface $container): array {67 return (new self())->instantiatePaymentMethods($container);68 }, 'gateway.paymentMethodsEnabledAtMollie' => static function (ContainerInterface $container): array {69 $dataHelper = $container->get('settings.data_helper');70 assert($dataHelper instanceof Data);71 $settings = $container->get('settings.settings_helper');72 assert($settings instanceof Settings);73 $apiKey = $settings->getApiKey();74 $methods = $apiKey ? $dataHelper->getAllPaymentMethods($apiKey) : [];75 $enabledMethods = [];76 foreach ($methods as $method) {77 $enabledMethods[] = $method['id'];78 }79 return $enabledMethods;80 }, 'gateway.listAllMethodsAvailable' => static function (ContainerInterface $container): array {81 $dataHelper = $container->get('settings.data_helper');82 assert($dataHelper instanceof Data);83 $settings = $container->get('settings.settings_helper');84 assert($settings instanceof Settings);85 $apiKey = $settings->getApiKey();86 $methods = $apiKey ? $dataHelper->getAllAvailablePaymentMethods() : [];87 $availableMethods = [];88 $implementedMethods = $container->get('gateway.classnames');89 foreach ($methods as $method) {90 if (in_array('Mollie_WC_Gateway_' . ucfirst($method['id']), $implementedMethods, \true)) {91 $availableMethods[] = $method;92 }93 }94 return $availableMethods;95 }, 'gateway.getPaymentMethodsAfterFeatureFlag' => static function (ContainerInterface $container): array {96 $availablePaymentMethods = $container->get('gateway.listAllMethodsAvailable');97 $klarnaOneFlag = (bool) apply_filters('inpsyde.feature-flags.mollie-woocommerce.klarna_one_enabled', \true);98 if (!$klarnaOneFlag) {99 $availablePaymentMethods = array_filter($availablePaymentMethods, static function ($method) {100 return $method['id'] !== Constants::KLARNA;101 });102 }103 $bancomatpayFlag = (bool) apply_filters('inpsyde.feature-flags.mollie-woocommerce.bancomatpay_enabled', \true);104 if (!$bancomatpayFlag) {105 $availablePaymentMethods = array_filter($availablePaymentMethods, static function ($method) {106 return $method['id'] !== Constants::BANCOMATPAY;107 });108 }109 $almaFlag = (bool) apply_filters('inpsyde.feature-flags.mollie-woocommerce.alma_enabled', \true);110 if (!$almaFlag) {111 $availablePaymentMethods = array_filter($availablePaymentMethods, static function ($method) {112 return $method['id'] !== Constants::ALMA;113 });114 }115 $swishFlag = (bool) apply_filters('inpsyde.feature-flags.mollie-woocommerce.swish_enabled', \true);116 if (!$swishFlag) {117 $availablePaymentMethods = array_filter($availablePaymentMethods, static function ($method) {118 return $method['id'] !== Constants::SWISH;119 });120 }121 return $availablePaymentMethods;122 }, 'gateway.isSDDGatewayEnabled' => static function (ContainerInterface $container): bool {123 $enabledMethods = $container->get('gateway.paymentMethodsEnabledAtMollie');124 return in_array(Constants::DIRECTDEBIT, $enabledMethods, \true);125 }, IconFactory::class => static function (ContainerInterface $container): IconFactory {126 $pluginUrl = $container->get('shared.plugin_url');127 $pluginPath = $container->get('shared.plugin_path');128 return new IconFactory($pluginUrl, $pluginPath);129 }, PaymentService::class => static function (ContainerInterface $container): PaymentService {130 $logger = $container->get(Logger::class);131 assert($logger instanceof Logger);132 $notice = $container->get(AdminNotice::class);133 assert($notice instanceof AdminNotice);134 $paymentFactory = $container->get(PaymentFactory::class);135 assert($paymentFactory instanceof PaymentFactory);136 $data = $container->get('settings.data_helper');137 assert($data instanceof Data);138 $api = $container->get('SDK.api_helper');139 assert($api instanceof Api);140 $settings = $container->get('settings.settings_helper');141 assert($settings instanceof Settings);142 $pluginId = $container->get('shared.plugin_id');143 $paymentCheckoutRedirectService = $container->get(PaymentCheckoutRedirectService::class);144 assert($paymentCheckoutRedirectService instanceof PaymentCheckoutRedirectService);145 $voucherDefaultCategory = $container->get('voucher.defaultCategory');146 return new PaymentService($notice, $logger, $paymentFactory, $data, $api, $settings, $pluginId, $paymentCheckoutRedirectService, $voucherDefaultCategory);147 }, OrderInstructionsService::class => static function (): OrderInstructionsService {148 return new OrderInstructionsService();149 }, PaymentFieldsService::class => static function (ContainerInterface $container): PaymentFieldsService {150 $data = $container->get('settings.data_helper');151 assert($data instanceof Data);152 return new PaymentFieldsService($data);153 }, PaymentCheckoutRedirectService::class => static function (ContainerInterface $container): PaymentCheckoutRedirectService {154 $data = $container->get('settings.data_helper');155 assert($data instanceof Data);156 return new PaymentCheckoutRedirectService($data);157 }, \Mollie\WooCommerce\Gateway\Surcharge::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Gateway\Surcharge {158 return new \Mollie\WooCommerce\Gateway\Surcharge();159 }, MollieOrderService::class => static function (ContainerInterface $container): MollieOrderService {160 $HttpResponseService = $container->get('SDK.HttpResponse');161 assert($HttpResponseService instanceof HttpResponse);162 $logger = $container->get(Logger::class);163 assert($logger instanceof Logger);164 $paymentFactory = $container->get(PaymentFactory::class);165 assert($paymentFactory instanceof PaymentFactory);166 $data = $container->get('settings.data_helper');167 assert($data instanceof Data);168 $pluginId = $container->get('shared.plugin_id');169 return new MollieOrderService($HttpResponseService, $logger, $paymentFactory, $data, $pluginId);170 }, \Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler {171 $settings = $container->get('settings.settings_helper');172 assert($settings instanceof Settings);173 $isSettingsOrderApi = $settings->isOrderApiSetting();174 return new \Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler($isSettingsOrderApi);175 }, 'gateway.isBillieEnabled' => static function (ContainerInterface $container): bool {176 $settings = $container->get('settings.settings_helper');177 assert($settings instanceof Settings);178 $isSettingsOrderApi = $settings->isOrderApiSetting();179 $billie = isset($container->get('gateway.paymentMethods')['billie']) ? $container->get('gateway.paymentMethods')['billie'] : null;180 $isBillieEnabled = \false;181 if ($billie instanceof PaymentMethodI) {182 $isBillieEnabled = $billie->getProperty('enabled') === 'yes';183 }184 return $isSettingsOrderApi && $isBillieEnabled;185 }];186 }187 42 public function run(ContainerInterface $container): bool 188 43 { … … 193 48 }); 194 49 add_filter('woocommerce_payment_gateways', static function ($gateways) use ($container) { 195 $mollieGateways = $container->get('gateway.instances');196 return array_merge($gateways, $mollieGateways);197 });198 add_filter('woocommerce_payment_gateways', static function ($gateways) use ($container) {199 50 $orderMandatoryGatewayDisabler = $container->get(\Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler::class); 200 51 assert($orderMandatoryGatewayDisabler instanceof \Mollie\WooCommerce\Gateway\OrderMandatoryGatewayDisabler); … … 203 54 add_filter('woocommerce_payment_gateways', static function ($gateways) { 204 55 $maybeEnablegatewayHelper = new MaybeDisableGateway(); 56 $gateways = $maybeEnablegatewayHelper->maybeDisableBankTransferGateway($gateways); 205 57 return $maybeEnablegatewayHelper->maybeDisableMealVoucherGateway($gateways); 206 58 }); 207 add_filter('woocommerce_payment_gateways', [$this, 'maybeDisableBankTransferGateway'], 20); 59 add_filter('woocommerce_payment_gateways', static function ($gateways) use ($container) { 60 $deprecatedGatewayHelpers = $container->get('__deprecated.gateway_helpers'); 61 foreach ($gateways as $gateway) { 62 $isMolliegateway = is_string($gateway) && strpos($gateway, 'mollie_wc_gateway_') !== \false || is_object($gateway) && strpos($gateway->id, 'mollie_wc_gateway_') !== \false; 63 if (!$isMolliegateway) { 64 continue; 65 } 66 // Add subscription filters after payment gateways are loaded 67 $isSubscriptiongateway = $gateway->supports('subscriptions'); 68 if ($isSubscriptiongateway) { 69 $deprecatedGatewayHelpers[$gateway->id]->addSubscriptionFilters($gateway); 70 } 71 // Add payment instructions 72 $displayInstructionsService = $container->get('gateway.hooks.displayInstructions'); 73 $displayInstructionsService($gateway); 74 // Add thankyou page actions for gateway 75 $thankyouPageService = $container->get('gateway.hooks.thankyouPage'); 76 if (!has_action('woocommerce_thankyou_' . $gateway->id)) { 77 $thankyouPageService($gateway); 78 } 79 // Add subscription payment hooks 80 $isSubscriptionPaymentService = $container->get('gateway.hooks.isSubscriptionPayment'); 81 $isSubscriptionPaymentService($gateway); 82 } 83 return $gateways; 84 }, 30); 208 85 // Disable SEPA as payment option in WooCommerce checkout 209 86 add_filter('woocommerce_available_payment_gateways', [$this, 'disableSEPAInCheckout'], 11, 1); … … 229 106 assert($surchargeService instanceof \Mollie\WooCommerce\Gateway\Surcharge); 230 107 $this->gatewaySurchargeHandling($surchargeService); 231 $notice = $container->get(AdminNotice::class); 232 assert($notice instanceof AdminNotice); 233 $logger = $container->get(Logger::class); 234 assert($logger instanceof Logger); 235 $pluginUrl = $container->get('shared.plugin_url'); 236 $apiHelper = $container->get('SDK.api_helper'); 237 assert($apiHelper instanceof Api); 238 $settingsHelper = $container->get('settings.settings_helper'); 239 assert($settingsHelper instanceof Settings); 240 $appleGateway = isset($container->get('gateway.instances')['mollie_wc_gateway_applepay']) ? $container->get('gateway.instances')['mollie_wc_gateway_applepay'] : \false; 241 if ($appleGateway) { 242 $this->mollieApplePayDirectHandling($notice, $logger, $apiHelper, $settingsHelper, $appleGateway); 243 } 244 $paypalGateway = isset($container->get('gateway.instances')['mollie_wc_gateway_paypal']) ? $container->get('gateway.instances')['mollie_wc_gateway_paypal'] : \false; 245 if ($paypalGateway) { 246 $this->molliePayPalButtonHandling($paypalGateway, $notice, $logger, $pluginUrl); 247 } 108 $this->paymentButtonsBootstrap($container); 248 109 $maybeDisableVoucher = new MaybeDisableGateway(); 249 110 $dataService = $container->get('settings.data_helper'); … … 272 133 return $fields; 273 134 }, 10, 3); 135 add_action('init', static function () use ($container) { 136 $paymentMethods = $container->get('gateway.paymentMethods'); 137 foreach ($paymentMethods as $paymentMethod) { 138 assert($paymentMethod instanceof PaymentMethodI); 139 $paymentMethod->initializeTranslations(); 140 $paymentMethod->updateSettingsWithDefaults($container); 141 } 142 }); 143 add_filter('woocommerce_get_transaction_url', static function ($return_url, $order, \WC_Payment_Gateway $wcGateway) { 144 if ($return_url || strpos($wcGateway->id, 'mollie_wc_gateway_') === \false) { 145 return $return_url; 146 } 147 $transactionId = $order->get_transaction_id(); 148 $isPaymentApi = substr($transactionId, 0, 3) === 'tr_'; 149 $resource = $transactionId && !$isPaymentApi ? 'orders' : 'payments'; 150 return 'https://my.mollie.com/dashboard/' . $resource . '/' . trim($transactionId) . '?utm_source=woocommerce&utm_medium=plugin&utm_campaign=partner'; 151 }, 10, 3); 274 152 return \true; 153 } 154 public function services(): array 155 { 156 static $services; 157 if ($services === null) { 158 $services = require_once __DIR__ . '/inc/services.php'; 159 } 160 return $services(); 161 } 162 /** 163 * @inheritDoc 164 */ 165 public function extensions(): array 166 { 167 static $extensions; 168 if ($extensions === null) { 169 $extensions = require_once __DIR__ . '/inc/extensions.php'; 170 } 171 return $extensions(); 275 172 } 276 173 /** … … 292 189 printf('<p style="border-bottom:solid 1px #eee;padding-bottom:13px;">%s</p>', wp_kses($meta, $allowedTags)); 293 190 }, $screen, 'side', 'high'); 294 }295 /**296 * Disable Bank Transfer Gateway297 *298 * @param ?array $gateways299 * @return array300 */301 public function maybeDisableBankTransferGateway(?array $gateways): array302 {303 if (!is_array($gateways)) {304 return [];305 }306 $isWcApiRequest = (bool) filter_input(\INPUT_GET, 'wc-api', \FILTER_SANITIZE_SPECIAL_CHARS);307 $bankTransferSettings = get_option('mollie_wc_gateway_banktransfer_settings', \false);308 //If the setting is active is forced Payment API so we need to filter the gateway when order is in pay-page309 // as it might have been created with Orders API310 $isActiveExpiryDate = $bankTransferSettings && isset($bankTransferSettings['activate_expiry_days_setting']) && $bankTransferSettings['activate_expiry_days_setting'] === "yes" && isset($bankTransferSettings['order_dueDate']) && $bankTransferSettings['order_dueDate'] > 0;311 /*312 * There is only one case where we want to filter the gateway and it's when the313 * pay-page render the available payments methods AND the setting is enabled314 *315 * For any other case we want to be sure bank transfer gateway is included.316 */317 if ($isWcApiRequest || !$isActiveExpiryDate || is_checkout() && !is_wc_endpoint_url('order-pay') || !wp_doing_ajax() && !is_wc_endpoint_url('order-pay') || is_admin()) {318 return $gateways;319 }320 $bankTransferGatewayClassName = 'mollie_wc_gateway_banktransfer';321 unset($gateways[$bankTransferGatewayClassName]);322 return $gateways;323 191 } 324 192 public function gatewaySurchargeHandling(\Mollie\WooCommerce\Gateway\Surcharge $surcharge) … … 376 244 } 377 245 /** 378 * Bootstrap the ApplePay button logic if feature enabled 379 */ 380 public function mollieApplePayDirectHandling(NoticeInterface $notice, Logger $logger, Api $apiHelper, Settings $settingsHelper, MollieSubscriptionGateway $appleGateway) 381 { 382 $buttonEnabledCart = mollieWooCommerceIsApplePayDirectEnabled('cart'); 383 $buttonEnabledProduct = mollieWooCommerceIsApplePayDirectEnabled('product'); 384 if ($buttonEnabledCart || $buttonEnabledProduct) { 385 $notices = new AdminNotice(); 386 $responseTemplates = new ResponsesToApple($logger, $appleGateway); 387 $ajaxRequests = new AppleAjaxRequests($responseTemplates, $notice, $logger, $apiHelper, $settingsHelper); 388 $applePayHandler = new ApplePayDirectHandler($notices, $ajaxRequests); 389 $applePayHandler->bootstrap($buttonEnabledProduct, $buttonEnabledCart); 390 } 391 } 392 /** 393 * Bootstrap the Mollie_WC_Gateway_PayPal button logic if feature enabled 394 */ 395 public function molliePayPalButtonHandling($gateway, NoticeInterface $notice, Logger $logger, string $pluginUrl) 396 { 397 $enabledInProduct = mollieWooCommerceIsPayPalButtonEnabled('product'); 398 $enabledInCart = mollieWooCommerceIsPayPalButtonEnabled('cart'); 399 $shouldBuildIt = $enabledInProduct || $enabledInCart; 400 if ($shouldBuildIt) { 401 $ajaxRequests = new PayPalAjaxRequests($gateway, $notice, $logger); 402 $data = new DataToPayPal($pluginUrl); 403 $payPalHandler = new PayPalButtonHandler($ajaxRequests, $data); 404 $payPalHandler->bootstrap($enabledInProduct, $enabledInCart); 405 } 406 } 407 public function instantiatePaymentMethodGateways(ContainerInterface $container): array 408 { 409 $logger = $container->get(Logger::class); 410 assert($logger instanceof Logger); 411 $notice = $container->get(FrontendNotice::class); 412 assert($notice instanceof FrontendNotice); 413 $paymentService = $container->get(PaymentService::class); 414 assert($paymentService instanceof PaymentService); 415 $mollieOrderService = $container->get(MollieOrderService::class); 416 assert($mollieOrderService instanceof MollieOrderService); 417 $HttpResponseService = $container->get('SDK.HttpResponse'); 418 assert($HttpResponseService instanceof HttpResponse); 419 $settingsHelper = $container->get('settings.settings_helper'); 420 assert($settingsHelper instanceof Settings); 421 $apiHelper = $container->get('SDK.api_helper'); 422 assert($apiHelper instanceof Api); 423 $paymentMethods = $container->get('gateway.paymentMethods'); 424 $data = $container->get('settings.data_helper'); 425 assert($data instanceof Data); 426 $orderInstructionsService = new OrderInstructionsService(); 427 $mollieObject = $container->get(MollieObject::class); 428 assert($mollieObject instanceof MollieObject); 429 $paymentFactory = $container->get(PaymentFactory::class); 430 assert($paymentFactory instanceof PaymentFactory); 431 $pluginId = $container->get('shared.plugin_id'); 432 $gateways = []; 433 if (empty($paymentMethods)) { 434 return $gateways; 435 } 436 foreach ($paymentMethods as $paymentMethod) { 437 $paymentMethodId = $paymentMethod->getIdFromConfig(); 438 if (!in_array($paymentMethodId, $container->get('gateway.paymentMethodsEnabledAtMollie'))) { 439 continue; 440 } 441 $isSepa = $paymentMethod->getProperty('SEPA'); 442 $key = 'mollie_wc_gateway_' . $paymentMethodId; 443 if ($isSepa) { 444 $directDebit = $paymentMethods[Constants::DIRECTDEBIT]; 445 $gateways[$key] = new MollieSepaRecurringGateway($directDebit, $paymentMethod, $paymentService, $orderInstructionsService, $mollieOrderService, $data, $logger, $notice, $HttpResponseService, $settingsHelper, $mollieObject, $paymentFactory, $pluginId, $apiHelper); 446 } elseif ($paymentMethod->getProperty('Subscription')) { 447 $gateways[$key] = new MollieSubscriptionGateway($paymentMethod, $paymentService, $orderInstructionsService, $mollieOrderService, $data, $logger, $notice, $HttpResponseService, $settingsHelper, $mollieObject, $paymentFactory, $pluginId, $apiHelper); 448 } else { 449 $gateways[$key] = new \Mollie\WooCommerce\Gateway\MolliePaymentGateway($paymentMethod, $paymentService, $orderInstructionsService, $mollieOrderService, $data, $logger, $notice, $HttpResponseService, $mollieObject, $paymentFactory, $pluginId); 450 } 451 } 452 return $gateways; 453 } 454 /** 455 * @param $container 246 * @param ContainerInterface $container 247 * @return void 248 * @throws \Psr\Container\ContainerExceptionInterface 249 * @throws \Psr\Container\NotFoundExceptionInterface 250 */ 251 public function paymentButtonsBootstrap(ContainerInterface $container): void 252 { 253 $applePayDirectHandler = $container->get(ApplePayDirectHandler::class); 254 if ($applePayDirectHandler instanceof ApplePayDirectHandler) { 255 $buttonEnabledCart = mollieWooCommerceIsApplePayDirectEnabled('cart'); 256 $buttonEnabledProduct = mollieWooCommerceIsApplePayDirectEnabled('product'); 257 if ($buttonEnabledCart || $buttonEnabledProduct) { 258 $applePayDirectHandler->bootstrap($buttonEnabledProduct, $buttonEnabledCart); 259 } 260 } 261 $paypalButtonHandler = $container->get(PayPalButtonHandler::class); 262 if ($paypalButtonHandler instanceof PayPalButtonHandler) { 263 $enabledInProduct = mollieWooCommerceIsPayPalButtonEnabled('product'); 264 $enabledInCart = mollieWooCommerceIsPayPalButtonEnabled('cart'); 265 $shouldBuildIt = $enabledInProduct || $enabledInCart; 266 if ($shouldBuildIt) { 267 $paypalButtonHandler->bootstrap($enabledInProduct, $enabledInCart); 268 } 269 } 270 } 271 /** 272 * This instantiates all payment methods that we have implemented 273 * disregards if they are available at Mollie or not 274 * 456 275 * @return array 457 276 */ 458 protected function instantiatePaymentMethods( $container): array277 protected function instantiatePaymentMethods(): array 459 278 { 460 279 $paymentMethods = []; 461 $listAllAvailablePaymentMethods = $container->get('gateway.getPaymentMethodsAfterFeatureFlag'); 462 $iconFactory = $container->get(IconFactory::class); 463 assert($iconFactory instanceof IconFactory); 464 $settingsHelper = $container->get('settings.settings_helper'); 465 assert($settingsHelper instanceof Settings); 466 $surchargeService = $container->get(\Mollie\WooCommerce\Gateway\Surcharge::class); 467 assert($surchargeService instanceof \Mollie\WooCommerce\Gateway\Surcharge); 468 $paymentFieldsService = $container->get(PaymentFieldsService::class); 469 assert($paymentFieldsService instanceof PaymentFieldsService); 470 foreach ($listAllAvailablePaymentMethods as $paymentMethodAvailable) { 471 $paymentMethodId = $paymentMethodAvailable['id']; 472 $paymentMethods[$paymentMethodId] = $this->buildPaymentMethod($paymentMethodId, $iconFactory, $settingsHelper, $paymentFieldsService, $surchargeService, $paymentMethodAvailable); 280 $allGatewayClassNames = SharedDataDictionary::GATEWAY_CLASSNAMES; 281 foreach ($allGatewayClassNames as $gatewayClassName) { 282 $parts = explode('_', $gatewayClassName); 283 $methodId = strtolower(end($parts)); 284 $paymentMethods[$methodId] = $this->buildPaymentMethod($methodId); 473 285 } 474 286 //I need DirectDebit to create SEPA gateway 475 287 if (!in_array(Constants::DIRECTDEBIT, array_keys($paymentMethods), \true)) { 476 $ paymentMethodId = Constants::DIRECTDEBIT;477 $paymentMethods[$ paymentMethodId] = $this->buildPaymentMethod($paymentMethodId, $iconFactory, $settingsHelper, $paymentFieldsService, $surchargeService, []);288 $methodId = Constants::DIRECTDEBIT; 289 $paymentMethods[$methodId] = $this->buildPaymentMethod($methodId); 478 290 } 479 291 return $paymentMethods; 292 } 293 /** 294 * @param string $id 295 * @param IconFactory $iconFactory 296 * @param Settings $settingsHelper 297 * @param Surcharge $surchargeService 298 * @param array $paymentMethods 299 * @return PaymentMethodI | array 300 */ 301 public function buildPaymentMethod(string $id) 302 { 303 $transformedId = ucfirst($id); 304 $paymentMethodClassName = 'Mollie\WooCommerce\PaymentMethods\\' . $transformedId; 305 return new $paymentMethodClassName(); 480 306 } 481 307 public function in3FieldsMandatory($fields, $errors) … … 503 329 } 504 330 /** 505 * @param string $id 506 * @param IconFactory $iconFactory 507 * @param Settings $settingsHelper 508 * @param PaymentFieldsService $paymentFieldsService 509 * @param Surcharge $surchargeService 510 * @param array $paymentMethods 511 * @return PaymentMethodI | array 512 */ 513 public function buildPaymentMethod(string $id, IconFactory $iconFactory, Settings $settingsHelper, PaymentFieldsService $paymentFieldsService, \Mollie\WooCommerce\Gateway\Surcharge $surchargeService, array $apiMethod) 514 { 515 $transformedId = ucfirst($id); 516 $paymentMethodClassName = 'Mollie\WooCommerce\PaymentMethods\\' . $transformedId; 517 $paymentMethod = new $paymentMethodClassName($iconFactory, $settingsHelper, $paymentFieldsService, $surchargeService, $apiMethod); 518 return $paymentMethod; 331 * Some payment methods require mandatory fields, this function will add them to the checkout fields array 332 * @param $fields 333 * @param string $gatewayName 334 * @param string $field 335 * @param $errors 336 * @return mixed 337 */ 338 public function addPaymentMethodMandatoryFields($fields, string $gatewayName, string $field, string $fieldLabel, $errors) 339 { 340 if ($fields['payment_method'] !== $gatewayName) { 341 return $fields; 342 } 343 if (!isset($fields[$field])) { 344 $fieldPosted = filter_input(\INPUT_POST, $field, \FILTER_SANITIZE_SPECIAL_CHARS) ?? \false; 345 if ($fieldPosted) { 346 $fields[$field] = $fieldPosted; 347 } else { 348 $errors->add('validation', sprintf( 349 /* translators: Placeholder 1: field name. */ 350 __('%s is a required field.', 'woocommerce'), 351 "<strong>{$fieldLabel}</strong>" 352 )); 353 } 354 } 355 return $fields; 519 356 } 520 357 public function addPaymentMethodMandatoryFieldsPhoneVerification($fields, string $gatewayName, string $field, string $fieldLabel, $errors) -
mollie-payments-for-woocommerce/trunk/src/Gateway/OrderMandatoryGatewayDisabler.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\Gateway; 5 5 6 use Mollie\Inpsyde\PaymentGateway\PaymentGateway; 6 7 class OrderMandatoryGatewayDisabler 7 8 { … … 10 11 */ 11 12 protected $isSettingsOrderApi; 13 private array $paymentMethods; 12 14 /** 13 15 * OrderMandatoryGatewayDisabler constructor. 14 16 */ 15 public function __construct(bool $isSettingsOrderApi )17 public function __construct(bool $isSettingsOrderApi, array $paymentMethods) 16 18 { 17 19 $this->isSettingsOrderApi = $isSettingsOrderApi; 20 $this->paymentMethods = $paymentMethods; 18 21 } 19 22 /** … … 36 39 return $gateways; 37 40 } 38 return array_filter($gateways, static function ($gateway) { 39 return !$gateway instanceof \Mollie\WooCommerce\Gateway\MolliePaymentGateway || !$gateway->paymentMethod()->getProperty('orderMandatory'); 41 $paymentMethods = $this->paymentMethods; 42 return array_filter($gateways, static function ($gateway) use ($paymentMethods) { 43 if (!mollieWooCommerceIsMollieGateway($gateway)) { 44 return \true; 45 } 46 $gatewayId = $gateway->id; 47 $methodId = substr($gatewayId, strrpos($gatewayId, '_') + 1); 48 $method = $paymentMethods[$methodId] ?? null; 49 return !$method->getProperty('orderMandatory'); 40 50 }); 41 51 } -
mollie-payments-for-woocommerce/trunk/src/Gateway/Voucher/MaybeDisableGateway.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\Gateway\Voucher; 5 5 6 use Mollie\WooCommerce\Gateway\MolliePaymentGateway; 7 use Mollie\WooCommerce\Payment\PaymentService; 6 use Mollie\Inpsyde\PaymentGateway\PaymentGateway; 7 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler; 8 use Mollie\WooCommerce\Payment\PaymentProcessor; 8 9 use Mollie\WooCommerce\PaymentMethods\Voucher; 9 10 class MaybeDisableGateway 10 11 { 12 /** 13 * Disable Bank Transfer Gateway 14 * 15 * @param ?array $gateways 16 * @return array 17 */ 18 public function maybeDisableBankTransferGateway(?array $gateways): array 19 { 20 if (!is_array($gateways)) { 21 return []; 22 } 23 $isWcApiRequest = (bool) filter_input(\INPUT_GET, 'wc-api', \FILTER_SANITIZE_SPECIAL_CHARS); 24 $bankTransferSettings = get_option('mollie_wc_gateway_banktransfer_settings', \false); 25 //If the setting is active is forced Payment API so we need to filter the gateway when order is in pay-page 26 // as it might have been created with Orders API 27 $isActiveExpiryDate = $bankTransferSettings && isset($bankTransferSettings['activate_expiry_days_setting']) && $bankTransferSettings['activate_expiry_days_setting'] === "yes" && isset($bankTransferSettings['order_dueDate']) && $bankTransferSettings['order_dueDate'] > 0; 28 /* 29 * There is only one case where we want to filter the gateway and it's when the 30 * pay-page render the available payments methods AND the setting is enabled 31 * 32 * For any other case we want to be sure bank transfer gateway is included. 33 */ 34 if ($isWcApiRequest || !$isActiveExpiryDate || is_checkout() && !is_wc_endpoint_url('order-pay') || !wp_doing_ajax() && !is_wc_endpoint_url('order-pay') || is_admin()) { 35 return $gateways; 36 } 37 $bankTransferGatewayClassName = 'mollie_wc_gateway_banktransfer'; 38 unset($gateways[$bankTransferGatewayClassName]); 39 return $gateways; 40 } 11 41 /** 12 42 * Disable Voucher Gateway if no categories associated with any product … … 24 54 } 25 55 $isWcApiRequest = (bool) filter_input(\INPUT_GET, 'wc-api', \FILTER_SANITIZE_SPECIAL_CHARS); 56 $isCheckoutPage = is_checkout(); 57 $isOrderPayPage = is_wc_endpoint_url('order-pay'); 26 58 // To exclude we are in Checkout or Order Pay page. These are the other options where gateways are required. 27 $notInCheckoutOrPayPage = $isWcApiRequest || !doing_action('woocommerce_payment_gateways') || !wp_doing_ajax() && ! is_wc_endpoint_url('order-pay');59 $notInCheckoutOrPayPage = $isWcApiRequest || !doing_action('woocommerce_payment_gateways') || !wp_doing_ajax() && !$isOrderPayPage && !$isCheckoutPage; 28 60 $notHasBlocks = !has_block('woocommerce/checkout'); 29 61 /* … … 39 71 $mealVoucherGatewayIndex = \false; 40 72 foreach ($gateways as $key => $gateway) { 41 if (! $gateway instanceof MolliePaymentGateway) {73 if (!mollieWooCommerceIsMollieGateway($gateway)) { 42 74 continue; 43 75 } … … 47 79 } 48 80 $productsWithCategory = $this->numberProductsWithCategory(); 49 $paymentAPISetting = get_option('mollie-payments-for-woocommerce_api_switch') === Payment Service::PAYMENT_METHOD_TYPE_PAYMENT;81 $paymentAPISetting = get_option('mollie-payments-for-woocommerce_api_switch') === PaymentProcessor::PAYMENT_METHOD_TYPE_PAYMENT; 50 82 if ($mealVoucherGatewayIndex !== \false && ($productsWithCategory === 0 || $paymentAPISetting)) { 51 83 unset($gateways[$mealVoucherGatewayIndex]); -
mollie-payments-for-woocommerce/trunk/src/Gateway/Voucher/VoucherModule.php
r3164004 r3262577 50 50 public function run(ContainerInterface $container): bool 51 51 { 52 $gatewayInstances = $container->get(' gateway.instances');52 $gatewayInstances = $container->get('__deprecated.gateway_helpers'); 53 53 $voucherGateway = $gatewayInstances['mollie_wc_gateway_voucher'] ?? \false; 54 54 $voucher = $voucherGateway && $voucherGateway->enabled === 'yes'; -
mollie-payments-for-woocommerce/trunk/src/Payment/MollieObject.php
r3226701 r3262577 7 7 use Mollie\Api\Resources\Order; 8 8 use Mollie\Api\Resources\Payment; 9 use Mollie\WooCommerce\ Gateway\MolliePaymentGateway;9 use Mollie\WooCommerce\Payment\Request\RequestFactory; 10 10 use Mollie\WooCommerce\PaymentMethods\Voucher; 11 11 use Mollie\WooCommerce\SDK\Api; 12 12 use Mollie\WooCommerce\Settings\Settings; 13 use Mollie\WooCommerce\Shared\SharedDataDictionary; 13 14 use WC_Order; 14 15 use WC_Payment_Gateway; 15 16 use Mollie\Psr\Log\LoggerInterface as Logger; 16 use stdClass;17 17 class MollieObject 18 18 { 19 public const MAXIMAL_LENGTH_ADDRESS = 100;20 public const MAXIMAL_LENGTH_POSTALCODE = 20;21 public const MAXIMAL_LENGTH_CITY = 200;22 public const MAXIMAL_LENGTH_REGION = 200;23 19 protected $data; 24 20 /** … … 34 30 * @var Logger 35 31 */ 36 protected $logger;32 protected Logger $logger; 37 33 /** 38 34 * @var PaymentFactory 39 35 */ 40 protected $paymentFactory;36 protected \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory; 41 37 protected $dataService; 42 38 protected $apiHelper; 43 protected $settingsHelper;39 protected Settings $settingsHelper; 44 40 protected $dataHelper; 45 41 /** … … 47 43 */ 48 44 protected $pluginId; 49 public function __construct($data, Logger $logger, \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory, Api $apiHelper, Settings $settingsHelper, string $pluginId) 45 /** 46 * @var null 47 */ 48 private $paymentMethod; 49 protected RequestFactory $requestFactory; 50 public function __construct($data, Logger $logger, \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory, Api $apiHelper, Settings $settingsHelper, string $pluginId, RequestFactory $requestFactory) 50 51 { 51 52 $this->data = $data; … … 57 58 $base_location = wc_get_base_location(); 58 59 static::$shop_country = $base_location['country']; 60 $this->paymentMethod = null; 61 $this->requestFactory = $requestFactory; 59 62 } 60 63 public function data() … … 131 134 protected function getPaymentRequestData($order, $customerId, $voucherDefaultCategory = Voucher::NO_CATEGORY) 132 135 { 136 } 137 /** 138 * @param \WC_Order $order 139 * @param string $new_status 140 * @param string $note 141 * @param bool $restore_stock 142 */ 143 public function updateOrderStatus(\WC_Order $order, $new_status, $note = '', $restore_stock = \true) 144 { 145 $order->update_status($new_status, $note); 146 switch ($new_status) { 147 case SharedDataDictionary::STATUS_ON_HOLD: 148 if ($restore_stock === \true) { 149 if (!$order->get_meta('_order_stock_reduced', \true)) { 150 // Reduce order stock 151 wc_reduce_stock_levels($order->get_id()); 152 $this->logger->debug(__METHOD__ . ": Stock for order {$order->get_id()} reduced."); 153 } 154 } 155 break; 156 case SharedDataDictionary::STATUS_PENDING: 157 case SharedDataDictionary::STATUS_FAILED: 158 case SharedDataDictionary::STATUS_CANCELLED: 159 if ($order->get_meta('_order_stock_reduced', \true)) { 160 // Restore order stock 161 $this->dataHelper->restoreOrderStock($order); 162 $this->logger->debug(__METHOD__ . " Stock for order {$order->get_id()} restored."); 163 } 164 break; 165 } 133 166 } 134 167 /** … … 497 530 } 498 531 } 499 protected function addSequenceTypeForSubscriptionsFirstPayments($orderId, $gateway, $paymentRequestData): array500 {501 if ($this->dataHelper->isSubscription($orderId) || $this->dataHelper->isWcSubscription($orderId)) {502 $disable_automatic_payments = apply_filters($this->pluginId . '_is_automatic_payment_disabled', \false);503 $supports_subscriptions = $gateway->supports('subscriptions');504 if ($supports_subscriptions == \true && $disable_automatic_payments == \false) {505 $paymentRequestData = $this->addSequenceTypeFirst($paymentRequestData);506 }507 }508 return $paymentRequestData;509 }510 public function addSequenceTypeFirst($paymentRequestData)511 {512 }513 532 /** 514 533 * @param $order … … 540 559 { 541 560 if (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($orderId)) { 542 if ( $gateway instanceof MolliePaymentGateway) {543 $ gateway->paymentService()->updateOrderStatus($order, $newOrderStatus, sprintf(561 if (mollieWooCommerceIsMollieGateway($gateway->id)) { 562 $this->updateOrderStatus($order, $newOrderStatus, sprintf( 544 563 /* translators: Placeholder 1: payment method title, placeholder 2: payment ID */ 545 564 __('%1$s renewal payment failed via Mollie (%2$s). You will need to manually review the payment and adjust product stocks if you use them.', 'mollie-payments-for-woocommerce'), … … 554 573 $emails['WC_Email_Failed_Order']->trigger($orderId); 555 574 } 556 } elseif ( $gateway instanceof MolliePaymentGateway) {557 $ gateway->paymentService()->updateOrderStatus($order, $newOrderStatus, sprintf(575 } elseif (mollieWooCommerceIsMollieGateway($gateway->id)) { 576 $this->updateOrderStatus($order, $newOrderStatus, sprintf( 558 577 /* translators: Placeholder 1: payment method title, placeholder 2: payment ID */ 559 578 __('%1$s payment failed via Mollie (%2$s).', 'mollie-payments-for-woocommerce'), … … 594 613 } 595 614 } 596 /**597 * Get the url to return to on Mollie return598 * saves the return redirect and failed redirect, so we save the page language in case there is one set599 * For example 'http://mollie-wc.docker.myhost/wc-api/mollie_return/?order_id=89&key=wc_order_eFZyH8jki6fge'600 *601 * @param WC_Order $order The order processed602 *603 * @return string The url with order id and key as params604 */605 public function getReturnUrl($order, $returnUrl)606 {607 $returnUrl = untrailingslashit($returnUrl);608 $returnUrl = $this->asciiDomainName($returnUrl);609 $orderId = $order->get_id();610 $orderKey = $order->get_order_key();611 $onMollieReturn = 'onMollieReturn';612 $returnUrl = $this->appendOrderArgumentsToUrl($orderId, $orderKey, $returnUrl, $onMollieReturn);613 $returnUrl = untrailingslashit($returnUrl);614 $this->logger->debug(" Order {$orderId} returnUrl: {$returnUrl}", [\true]);615 return apply_filters($this->pluginId . '_return_url', $returnUrl, $order);616 }617 /**618 * Get the webhook url619 * For example 'http://mollie-wc.docker.myhost/wc-api/mollie_return/mollie_wc_gateway_bancontact/?order_id=89&key=wc_order_eFZyH8jki6fge'620 *621 * @param WC_Order $order The order processed622 *623 * @return string The url with gateway and order id and key as params624 */625 public function getWebhookUrl($order, $gatewayId)626 {627 $webhookUrl = WC()->api_request_url($gatewayId);628 $webhookUrl = untrailingslashit($webhookUrl);629 $webhookUrl = $this->asciiDomainName($webhookUrl);630 $orderId = $order->get_id();631 $orderKey = $order->get_order_key();632 $webhookUrl = $this->appendOrderArgumentsToUrl($orderId, $orderKey, $webhookUrl);633 $webhookUrl = untrailingslashit($webhookUrl);634 $this->logger->debug(" Order {$orderId} webhookUrl: {$webhookUrl}", [\true]);635 return apply_filters($this->pluginId . '_webhook_url', $webhookUrl, $order);636 }637 /**638 * @param $url639 *640 * @return string641 */642 protected function asciiDomainName($url): string643 {644 $parsed = wp_parse_url($url);645 $scheme = isset($parsed['scheme']) ? $parsed['scheme'] : '';646 $domain = isset($parsed['host']) ? $parsed['host'] : \false;647 $query = isset($parsed['query']) ? $parsed['query'] : '';648 $path = isset($parsed['path']) ? $parsed['path'] : '';649 if (!$domain) {650 return $url;651 }652 if (function_exists('idn_to_ascii')) {653 $domain = $this->idnEncodeDomain($domain);654 $url = $scheme . "://" . $domain . $path . '?' . $query;655 }656 return $url;657 }658 /**659 * @param $order_id660 * @param $order_key661 * @param $webhook_url662 * @param string $filterFlag663 *664 * @return string665 */666 protected function appendOrderArgumentsToUrl($order_id, $order_key, $webhook_url, $filterFlag = '')667 {668 $webhook_url = add_query_arg(['order_id' => $order_id, 'key' => $order_key, 'filter_flag' => $filterFlag], $webhook_url);669 return $webhook_url;670 }671 /**672 * @param $domain673 * @return false|mixed|string674 */675 protected function idnEncodeDomain($domain)676 {677 if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) {678 $domain = idn_to_ascii($domain, \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46) ? idn_to_ascii($domain, \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46) : $domain;679 } else {680 $domain = idn_to_ascii($domain) ? idn_to_ascii($domain) : $domain;681 }682 return $domain;683 }684 protected function getPaymentDescription($order, $option)685 {686 $description = !$option ? '' : trim($option);687 $description = !$description ? '{orderNumber}' : $description;688 switch ($description) {689 // Support for old deprecated options.690 // TODO: remove when deprecated691 case '{orderNumber}':692 $description = _x('Order {orderNumber}', 'Payment description for {orderNumber}', 'mollie-payments-for-woocommerce');693 $description = $this->replaceTagsDescription($order, $description);694 break;695 case '{storeName}':696 $description = _x('StoreName {storeName}', 'Payment description for {storeName}', 'mollie-payments-for-woocommerce');697 $description = $this->replaceTagsDescription($order, $description);698 break;699 case '{customer.firstname}':700 $description = _x('Customer Firstname {customer.firstname}', 'Payment description for {customer.firstname}', 'mollie-payments-for-woocommerce');701 $description = $this->replaceTagsDescription($order, $description);702 break;703 case '{customer.lastname}':704 $description = _x('Customer Lastname {customer.lastname}', 'Payment description for {customer.lastname}', 'mollie-payments-for-woocommerce');705 $description = $this->replaceTagsDescription($order, $description);706 break;707 case '{customer.company}':708 $description = _x('Customer Company {customer.company}', 'Payment description for {customer.company}', 'mollie-payments-for-woocommerce');709 $description = $this->replaceTagsDescription($order, $description);710 break;711 // Support for custom string with interpolation.712 default:713 // Replace available description tags.714 $description = $this->replaceTagsDescription($order, $description);715 break;716 }717 // Fall back on default if description turns out empty.718 return !$description ? __('Order', 'woocommerce') . ' ' . $order->get_order_number() : $description;719 }720 /**721 * @param $order722 * @param $description723 * @return array|string|string[]724 */725 protected function replaceTagsDescription($order, $description)726 {727 $replacement_tags = ['{orderNumber}' => $order->get_order_number(), '{storeName}' => get_bloginfo('name'), '{customer.firstname}' => $order->get_billing_first_name(), '{customer.lastname}' => $order->get_billing_last_name(), '{customer.company}' => $order->get_billing_company()];728 foreach ($replacement_tags as $tag => $replacement) {729 $description = str_replace($tag, $replacement, $description);730 }731 return $description;732 }733 /**734 * @param $order735 * @return stdClass736 */737 protected function createBillingAddress($order)738 {739 // Setup billing and shipping objects740 $billingAddress = new stdClass();741 // Get user details742 $billingAddress->givenName = ctype_space($order->get_billing_first_name()) ? null : $order->get_billing_first_name();743 $billingAddress->familyName = ctype_space($order->get_billing_last_name()) ? null : $order->get_billing_last_name();744 $billingAddress->email = ctype_space($order->get_billing_email()) ? null : $order->get_billing_email();745 // Create billingAddress object746 $billingAddress->streetAndNumber = ctype_space($order->get_billing_address_1()) ? null : $this->maximalFieldLengths($order->get_billing_address_1(), self::MAXIMAL_LENGTH_ADDRESS);747 $billingAddress->streetAdditional = ctype_space($order->get_billing_address_2()) ? null : $this->maximalFieldLengths($order->get_billing_address_2(), self::MAXIMAL_LENGTH_ADDRESS);748 $billingAddress->postalCode = ctype_space($order->get_billing_postcode()) ? null : $this->maximalFieldLengths($order->get_billing_postcode(), self::MAXIMAL_LENGTH_POSTALCODE);749 $billingAddress->city = ctype_space($order->get_billing_city()) ? null : $this->maximalFieldLengths($order->get_billing_city(), self::MAXIMAL_LENGTH_CITY);750 $billingAddress->region = ctype_space($order->get_billing_state()) ? null : $this->maximalFieldLengths($order->get_billing_state(), self::MAXIMAL_LENGTH_REGION);751 $billingAddress->country = ctype_space($order->get_billing_country()) ? null : $this->maximalFieldLengths($order->get_billing_country(), self::MAXIMAL_LENGTH_REGION);752 $billingAddress->organizationName = $this->billingCompanyField($order);753 $phone = $this->getPhoneNumber($order);754 $billingAddress->phone = ctype_space($phone) ? null : $this->getFormattedPhoneNumber($phone);755 return $billingAddress;756 }757 protected function getPhoneNumber($order)758 {759 $phone = !empty($order->get_billing_phone()) ? $order->get_billing_phone() : $order->get_shipping_phone();760 if (empty($phone)) {761 //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized762 $phone = wc_clean(wp_unslash($_POST['billing_phone'] ?? ''));763 }764 return $phone;765 }766 protected function getFormattedPhoneNumber(string $phone)767 {768 //remove whitespaces and all non numerical characters except +769 $phone = preg_replace('/[^0-9+]+/', '', $phone);770 if (!is_string($phone)) {771 return null;772 }773 //check if phone starts with 06 and replace with +316774 $phone = transformPhoneToNLFormat($phone);775 //check that $phone is in E164 format or can be changed by api776 if (is_string($phone) && preg_match('/^\+[1-9]\d{10,13}$|^[1-9]\d{9,13}$/', $phone)) {777 return $phone;778 }779 return null;780 }781 /**782 * @param $order783 * @return string|null784 */785 public function billingCompanyField($order): ?string786 {787 if (!trim($order->get_billing_company())) {788 return $this->checkBillieCompanyField($order);789 }790 return $this->maximalFieldLengths($order->get_billing_company(), self::MAXIMAL_LENGTH_ADDRESS);791 }792 private function checkBillieCompanyField($order)793 {794 $gateway = wc_get_payment_gateway_by_order($order);795 if (!$gateway || !$gateway->id) {796 return null;797 }798 $isBillieMethodId = $gateway->id === 'mollie_wc_gateway_billie';799 if ($isBillieMethodId) {800 //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized801 $fieldPosted = wc_clean(wp_unslash($_POST["billing_company_billie"] ?? ''));802 $company = ($fieldPosted ?: $order->get_billing_company()) ?: $order->get_shipping_company();803 return $company ? $this->maximalFieldLengths($company, self::MAXIMAL_LENGTH_ADDRESS) : null;804 }805 return null;806 }807 /**808 * @param $order809 * @return stdClass810 */811 protected function createShippingAddress($order)812 {813 $shippingAddress = new stdClass();814 // Get user details815 $shippingAddress->givenName = ctype_space($order->get_shipping_first_name()) ? null : $order->get_shipping_first_name();816 $shippingAddress->familyName = ctype_space($order->get_shipping_last_name()) ? null : $order->get_shipping_last_name();817 $shippingAddress->email = ctype_space($order->get_billing_email()) ? null : $order->get_billing_email();818 // WooCommerce doesn't have a shipping email819 // Create shippingAddress object820 $shippingAddress->streetAndNumber = ctype_space($order->get_shipping_address_1()) ? null : $this->maximalFieldLengths($order->get_shipping_address_1(), self::MAXIMAL_LENGTH_ADDRESS);821 $shippingAddress->streetAdditional = ctype_space($order->get_shipping_address_2()) ? null : $this->maximalFieldLengths($order->get_shipping_address_2(), self::MAXIMAL_LENGTH_ADDRESS);822 $shippingAddress->postalCode = ctype_space($order->get_shipping_postcode()) ? null : $this->maximalFieldLengths($order->get_shipping_postcode(), self::MAXIMAL_LENGTH_POSTALCODE);823 $shippingAddress->city = ctype_space($order->get_shipping_city()) ? null : $this->maximalFieldLengths($order->get_shipping_city(), self::MAXIMAL_LENGTH_CITY);824 $shippingAddress->region = ctype_space($order->get_shipping_state()) ? null : $this->maximalFieldLengths($order->get_shipping_state(), self::MAXIMAL_LENGTH_REGION);825 $shippingAddress->country = ctype_space($order->get_shipping_country()) ? null : $this->maximalFieldLengths($order->get_shipping_country(), self::MAXIMAL_LENGTH_REGION);826 return $shippingAddress;827 }828 /**829 * Method that shortens the field to a certain length830 *831 * @param string $field832 * @param int $maximalLength833 *834 * @return null|string835 */836 protected function maximalFieldLengths($field, $maximalLength)837 {838 if (!is_string($field)) {839 return null;840 }841 if (is_int($maximalLength) && strlen($field) > $maximalLength) {842 $field = substr($field, 0, $maximalLength);843 $field = !$field ? null : $field;844 }845 return $field;846 }847 615 } -
mollie-payments-for-woocommerce/trunk/src/Payment/MollieOrder.php
r3226701 r3262577 5 5 6 6 use Exception; 7 use Mollie\Inpsyde\PaymentGateway\PaymentGateway; 7 8 use Mollie\Api\Exceptions\ApiException; 8 9 use Mollie\Api\Resources\Payment; 9 10 use Mollie\Api\Resources\Order; 10 11 use Mollie\Api\Resources\Refund; 11 use Mollie\WooCommerce\Gateway\MolliePaymentGateway; 12 use Mollie\WooCommerce\Gateway\Refund\OrderItemsRefunder; 13 use Mollie\WooCommerce\Gateway\Refund\PartialRefundException; 14 use Mollie\WooCommerce\Payment\Request\RequestFactory; 12 15 use Mollie\WooCommerce\PaymentMethods\Voucher; 13 16 use Mollie\WooCommerce\SDK\Api; 17 use Mollie\WooCommerce\Settings\Settings; 18 use Mollie\WooCommerce\Shared\Data; 14 19 use Mollie\WooCommerce\Shared\SharedDataDictionary; 20 use Mollie\Psr\Log\LoggerInterface as Logger; 15 21 use Mollie\Psr\Log\LogLevel; 16 22 use WC_Order; … … 26 32 protected static $shop_country; 27 33 /** 28 * @var OrderLines29 */30 protected $orderLines;31 /**32 34 * @var OrderItemsRefunder 33 35 */ … … 39 41 * @param $data 40 42 */ 41 public function __construct( \Mollie\WooCommerce\Payment\OrderItemsRefunder $orderItemsRefunder, $data, $pluginId, Api $apiHelper, $settingsHelper, $dataHelper, $logger, \Mollie\WooCommerce\Payment\OrderLines $orderLines)43 public function __construct(OrderItemsRefunder $orderItemsRefunder, $data, string $pluginId, Api $apiHelper, Settings $settingsHelper, Data $dataHelper, Logger $logger, RequestFactory $requestFactory) 42 44 { 43 45 $this->data = $data; … … 46 48 $this->apiHelper = $apiHelper; 47 49 $this->settingsHelper = $settingsHelper; 50 $this->logger = $logger; 51 $this->requestFactory = $requestFactory; 48 52 $this->dataHelper = $dataHelper; 49 $this->logger = $logger;50 $this->orderLines = $orderLines;51 53 } 52 54 public function getPaymentObject($paymentId, $testMode = \false, $useCache = \true) … … 70 72 public function getPaymentRequestData($order, $customerId, $voucherDefaultCategory = Voucher::NO_CATEGORY) 71 73 { 72 $settingsHelper = $this->settingsHelper; 73 $paymentLocale = $settingsHelper->getPaymentLocale(); 74 $storeCustomer = $settingsHelper->shouldStoreCustomer(); 75 $gateway = wc_get_payment_gateway_by_order($order); 76 if (!$gateway || !$gateway instanceof MolliePaymentGateway) { 77 return ['result' => 'failure']; 78 } 79 $gatewayId = $gateway->id; 80 $selectedIssuer = $gateway->getSelectedIssuer(); 81 $returnUrl = $gateway->get_return_url($order); 82 $returnUrl = $this->getReturnUrl($order, $returnUrl); 83 $webhookUrl = $this->getWebhookUrl($order, $gatewayId); 84 $isPayPalExpressOrder = $order->get_meta('_mollie_payment_method_button') === 'PayPalButton'; 85 $billingAddress = null; 86 if (!$isPayPalExpressOrder) { 87 $billingAddress = $this->createBillingAddress($order); 88 $shippingAddress = $this->createShippingAddress($order); 89 } 90 // Generate order lines for Mollie Orders 91 $orderLinesHelper = $this->orderLines; 92 $orderLines = $orderLinesHelper->order_lines($order, $voucherDefaultCategory); 93 // Build the Mollie order data 94 $paymentRequestData = ['amount' => ['currency' => $this->dataHelper->getOrderCurrency($order), 'value' => $this->dataHelper->formatCurrencyValue($order->get_total(), $this->dataHelper->getOrderCurrency($order))], 'redirectUrl' => $returnUrl, 'webhookUrl' => $webhookUrl, 'method' => $gateway->paymentMethod()->getProperty('id'), 'payment' => ['issuer' => $selectedIssuer], 'locale' => $paymentLocale, 'billingAddress' => $billingAddress, 'metadata' => apply_filters($this->pluginId . '_payment_object_metadata', ['order_id' => $order->get_id(), 'order_number' => $order->get_order_number()]), 'lines' => $orderLines['lines'], 'orderNumber' => $order->get_order_number()]; 95 $paymentRequestData = $this->addSequenceTypeForSubscriptionsFirstPayments($order->get_id(), $gateway, $paymentRequestData); 96 // Only add shippingAddress if all required fields are set 97 if (!empty($shippingAddress->streetAndNumber) && !empty($shippingAddress->postalCode) && !empty($shippingAddress->city) && !empty($shippingAddress->country)) { 98 $paymentRequestData['shippingAddress'] = $shippingAddress; 99 } 100 // Only store customer at Mollie if setting is enabled 101 if ($storeCustomer) { 102 $paymentRequestData['payment']['customerId'] = $customerId; 103 } 104 $cardToken = mollieWooCommerceCardToken(); 105 if ($cardToken && isset($paymentRequestData['payment'])) { 106 $paymentRequestData['payment']['cardToken'] = $cardToken; 107 } 108 //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 109 $applePayToken = wc_clean(wp_unslash($_POST["token"] ?? '')); 110 if ($applePayToken && isset($paymentRequestData['payment'])) { 111 $encodedApplePayToken = wp_json_encode($applePayToken); 112 $paymentRequestData['payment']['applePayPaymentToken'] = $encodedApplePayToken; 113 } 114 $customerBirthdate = $this->getCustomerBirthdate($order); 115 if ($customerBirthdate) { 116 $paymentRequestData['consumerDateOfBirth'] = $customerBirthdate; 117 } 118 return $paymentRequestData; 74 return $this->requestFactory->createRequest('order', $order, $customerId); 119 75 } 120 76 public function setActiveMolliePayment($orderId) … … 162 118 $ibanDetails = []; 163 119 if (isset($payment->_embedded->payments[0]->id)) { 164 $actualPayment = new \Mollie\WooCommerce\Payment\MolliePayment($payment->_embedded->payments[0]->id, $this->pluginId, $this->apiHelper, $this->settingsHelper, $this->dataHelper, $this->logger );120 $actualPayment = new \Mollie\WooCommerce\Payment\MolliePayment($payment->_embedded->payments[0]->id, $this->pluginId, $this->apiHelper, $this->settingsHelper, $this->dataHelper, $this->logger, $this->requestFactory); 165 121 $actualPayment = $actualPayment->getPaymentObject($actualPayment->data); 166 122 /** … … 171 127 } 172 128 return $ibanDetails; 173 }174 public function addSequenceTypeFirst($paymentRequestData)175 {176 $paymentRequestData['payment']['sequenceType'] = 'first';177 return $paymentRequestData;178 129 } 179 130 /** … … 462 413 try { 463 414 return $this->orderItemsRefunder->refund($order, $items, $paymentObject, $reason); 464 } catch ( \Mollie\WooCommerce\Payment\PartialRefundException $exception) {415 } catch (PartialRefundException $exception) { 465 416 $this->logger->debug(__METHOD__ . ' - ' . $exception->getMessage()); 466 417 return $this->refund_amount($order, $amount, $paymentObject, $reason); … … 596 547 { 597 548 $gateway = wc_get_payment_gateway_by_order($order); 598 if (!$this->isOrderPaymentStartedByOtherGateway($order) && is_a($gateway, MolliePaymentGateway::class)) {599 $ gateway->paymentService()->updateOrderStatus($order, $newOrderStatus);549 if (!$this->isOrderPaymentStartedByOtherGateway($order) && is_a($gateway, PaymentGateway::class)) { 550 $this->updateOrderStatus($order, $newOrderStatus); 600 551 } else { 601 552 $this->informNotUpdatingStatus($gateway->id, $order); … … 669 620 unset($items[$item->get_id()]); 670 621 } 671 protected function getCustomerBirthdate($order) 672 { 673 $gateway = wc_get_payment_gateway_by_order($order); 674 if (!$gateway || !isset($gateway->id)) { 675 return null; 676 } 677 if (strpos($gateway->id, 'mollie_wc_gateway_') === \false) { 678 return null; 679 } 680 $additionalFields = $gateway->paymentMethod()->getProperty('additionalFields'); 681 $methodId = $additionalFields && in_array('birthdate', $additionalFields, \true); 682 if ($methodId) { 683 $optionName = 'billing_birthdate_' . $gateway->paymentMethod()->getProperty('id'); 684 //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 685 $fieldPosted = wc_clean(wp_unslash($_POST[$optionName] ?? '')); 686 if ($fieldPosted === '' || !is_string($fieldPosted)) { 687 return null; 688 } 689 $order->update_meta_data($optionName, $fieldPosted); 690 $order->save(); 691 $format = "Y-m-d"; 692 return gmdate($format, (int) strtotime($fieldPosted)); 693 } 694 return null; 622 public function setOrder($data) 623 { 624 $this->data = $data; 695 625 } 696 626 } -
mollie-payments-for-woocommerce/trunk/src/Payment/MollieOrderService.php
r3242448 r3262577 4 4 namespace Mollie\WooCommerce\Payment; 5 5 6 use Mollie\Inpsyde\PaymentGateway\PaymentGateway; 6 7 use Mollie\Api\Exceptions\ApiException; 7 8 use Mollie\Api\Resources\Order; 8 9 use Mollie\Api\Resources\Payment; 9 10 use Mollie\WooCommerce\Gateway\AbstractGateway; 10 use Mollie\WooCommerce\Gateway\MolliePaymentGateway ;11 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler; 11 12 use Mollie\WooCommerce\SDK\HttpResponse; 12 13 use Mollie\WooCommerce\Shared\Data; 13 14 use Mollie\WooCommerce\Shared\SharedDataDictionary; 15 use Mollie\Psr\Container\ContainerInterface; 14 16 use Mollie\Psr\Log\LoggerInterface as Logger; 15 17 use Mollie\Psr\Log\LogLevel; … … 35 37 protected $data; 36 38 protected $pluginId; 37 /** 38 * PaymentService constructor. 39 */ 40 public function __construct(HttpResponse $httpResponse, Logger $logger, \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory, Data $data, string $pluginId) 39 private ContainerInterface $container; 40 /** 41 * MollieOrderService constructor. 42 */ 43 public function __construct(HttpResponse $httpResponse, Logger $logger, \Mollie\WooCommerce\Payment\PaymentFactory $paymentFactory, Data $data, string $pluginId, ContainerInterface $container) 41 44 { 42 45 $this->httpResponse = $httpResponse; … … 45 48 $this->data = $data; 46 49 $this->pluginId = $pluginId; 50 $this->container = $container; 47 51 } 48 52 public function setGateway($gateway) … … 77 81 } 78 82 $gateway = wc_get_payment_gateway_by_order($order); 79 if (! $gateway instanceof MolliePaymentGateway) {83 if (!mollieWooCommerceIsMollieGateway($gateway->id)) { 80 84 return; 81 85 } … … 98 102 return; 99 103 } 100 $payment = $payment_object->getPaymentObject($payment_object->data(), $test_mode, $use_cache =\false);104 $payment = $payment_object->getPaymentObject($payment_object->data(), $test_mode, \false); 101 105 // Payment not found 102 106 if (!$payment) { 103 107 $this->httpResponse->setHttpResponseCode(404); 104 108 $this->logger->debug(__METHOD__ . ": payment object {$payment_object_id} not found.", [\true]); 105 return;106 }107 if (in_array($payment->method, ['klarna', 'klarnapaylater', 'klarnasliceit', 'klarnapaynow'], \true) && strpos($paymentId, 'tr_') === 0) {108 $this->httpResponse->setHttpResponseCode(200);109 $this->logger->debug($this->gateway->id . ": not respond on transaction webhooks for this payment method. Payment ID {$payment->id}, order ID {$order_id}");110 109 return; 111 110 } … … 125 124 // TODO David: move to payment object? 126 125 // Add a debug message that order was already paid for 127 $this-> gateway->handlePaidOrderWebhook($order, $payment);126 $this->handlePaidOrderWebhook($order, $payment); 128 127 // Check and process a possible refund or chargeback 129 128 $this->processRefunds($order, $payment); … … 155 154 } 156 155 /** 156 * @param \WC_Order $order 157 * @param $payment 158 */ 159 public function handlePaidOrderWebhook(\WC_Order $order, $payment) 160 { 161 // Duplicate webhook call 162 $this->httpResponse->setHttpResponseCode(204); 163 $order = wc_get_order($order); 164 $order_id = $order->get_id(); 165 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ": Order does not need a payment by Mollie (payment {$payment->id}).", [\true]); 166 } 167 /** 157 168 * @param WC_Order $order 158 169 * … … 162 173 { 163 174 $order_id = $order->get_id(); 175 $gateway = wc_get_payment_gateway_by_order($order); 176 $paymentMethod = $this->container->get('payment_gateway.getPaymentMethod')($gateway->id); 164 177 // Check whether the order is processed and paid via another gateway 165 178 if ($this->isOrderPaidByOtherGateway($order)) { 166 $this->logger->debug(__METHOD__ . ' ' . $ this->gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: no, previously processed by other (non-Mollie) gateway.', [\true]);179 $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: no, previously processed by other (non-Mollie) gateway.', [\true]); 167 180 return \false; 168 181 } 169 182 // Check whether the order is processed and paid via Mollie 170 183 if (!$this->isOrderPaidAndProcessed($order)) { 171 $this->logger->debug(__METHOD__ . ' ' . $ this->gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, order not previously processed by Mollie gateway.', [\true]);184 $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, order not previously processed by Mollie gateway.', [\true]); 172 185 return \true; 173 186 } 187 if ('1' === $order->get_meta('_mollie_authorized')) { 188 $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, order is authorized.'); 189 return \true; 190 } 174 191 if ($order->needs_payment()) { 175 $this->logger->debug(__METHOD__ . ' ' . $ this->gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, WooCommerce thinks order needs payment.', [\true]);192 $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, WooCommerce thinks order needs payment.', [\true]); 176 193 return \true; 177 194 } 178 195 // Has initial order status 'on-hold' 179 if ($ this->gateway->paymentMethod()->getInitialOrderStatus() === SharedDataDictionary::STATUS_ON_HOLD && $order->has_status(SharedDataDictionary::STATUS_ON_HOLD)) {180 $this->logger->debug(__METHOD__ . ' ' . $ this->gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, has status On-Hold. ', [\true]);196 if ($paymentMethod->getInitialOrderStatus() === SharedDataDictionary::STATUS_ON_HOLD && $order->has_status(SharedDataDictionary::STATUS_ON_HOLD)) { 197 $this->logger->debug(__METHOD__ . ' ' . $gateway->id . ': Order ' . $order_id . ' orderNeedsPayment check: yes, has status On-Hold. ', [\true]); 181 198 return \true; 182 199 } … … 498 515 { 499 516 $payment_method_title = ''; 500 if (!$this->gateway instanceof MolliePaymentGateway) { 501 return $payment_method_title; 502 } 503 if ($payment->method === $this->gateway->paymentMethod()->getProperty('id')) { 517 if ($payment->method === $this->gateway->id) { 504 518 $payment_method_title = $this->gateway->method_title; 505 519 } -
mollie-payments-for-woocommerce/trunk/src/Payment/MolliePayment.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\Payment; 5 5 6 use Mollie\Inpsyde\PaymentGateway\PaymentGateway; 6 7 use Mollie\Api\Exceptions\ApiException; 7 use Mollie\Api\Resources\Order;8 8 use Mollie\Api\Resources\Payment; 9 9 use Mollie\Api\Resources\Refund; 10 use Mollie\WooCommerce\Gateway\MolliePaymentGateway; 11 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayI; 10 use Mollie\WooCommerce\Payment\Request\RequestFactory; 12 11 use Mollie\WooCommerce\PaymentMethods\Voucher; 13 12 use Mollie\WooCommerce\SDK\Api; 13 use Mollie\WooCommerce\Settings\Settings; 14 use Mollie\WooCommerce\Shared\Data; 14 15 use Mollie\WooCommerce\Shared\SharedDataDictionary; 16 use Mollie\Psr\Log\LoggerInterface as Logger; 15 17 use Mollie\Psr\Log\LogLevel; 16 18 use WC_Order; 17 use WC_Payment_Gateway;18 19 use WC_Subscriptions_Manager; 19 20 use WP_Error; … … 22 23 public const ACTION_AFTER_REFUND_PAYMENT_CREATED = 'mollie-payments-for-woocommerce' . '_refund_payment_created'; 23 24 protected $pluginId; 24 public function __construct($data, $pluginId, Api $apiHelper, $settingsHelper, $dataHelper, $logger)25 public function __construct($data, string $pluginId, Api $apiHelper, Settings $settingsHelper, Data $dataHelper, Logger $logger, RequestFactory $requestFactory) 25 26 { 26 27 $this->data = $data; … … 28 29 $this->apiHelper = $apiHelper; 29 30 $this->settingsHelper = $settingsHelper; 31 $this->logger = $logger; 32 $this->requestFactory = $requestFactory; 30 33 $this->dataHelper = $dataHelper; 31 $this->logger = $logger;32 34 } 33 35 public function getPaymentObject($paymentId, $testMode = \false, $useCache = \true) … … 53 55 public function getPaymentRequestData($order, $customerId, $voucherDefaultCategory = Voucher::NO_CATEGORY) 54 56 { 55 $settingsHelper = $this->settingsHelper; 56 $optionName = $this->pluginId . '_' . 'api_payment_description'; 57 $option = get_option($optionName); 58 $paymentDescription = $this->getPaymentDescription($order, $option); 59 $paymentLocale = $settingsHelper->getPaymentLocale(); 60 $storeCustomer = $settingsHelper->shouldStoreCustomer(); 61 $gateway = wc_get_payment_gateway_by_order($order); 62 if (!$gateway || !$gateway instanceof MolliePaymentGateway) { 63 return ['result' => 'failure']; 64 } 65 $gatewayId = $gateway->id; 66 $selectedIssuer = $gateway->getSelectedIssuer(); 67 $returnUrl = $gateway->get_return_url($order); 68 $returnUrl = $this->getReturnUrl($order, $returnUrl); 69 $webhookUrl = $this->getWebhookUrl($order, $gatewayId); 70 $orderId = $order->get_id(); 71 $paymentRequestData = ['amount' => ['currency' => $this->dataHelper->getOrderCurrency($order), 'value' => $this->dataHelper->formatCurrencyValue($order->get_total(), $this->dataHelper->getOrderCurrency($order))], 'description' => $paymentDescription, 'redirectUrl' => $returnUrl, 'webhookUrl' => $webhookUrl, 'method' => $gateway->paymentMethod()->getProperty('id'), 'issuer' => $selectedIssuer, 'locale' => $paymentLocale, 'metadata' => apply_filters($this->pluginId . '_payment_object_metadata', ['order_id' => $order->get_id()])]; 72 $paymentRequestData = $this->addSequenceTypeForSubscriptionsFirstPayments($order->get_id(), $gateway, $paymentRequestData); 73 if ($storeCustomer) { 74 $paymentRequestData['customerId'] = $customerId; 75 } 76 $cardToken = mollieWooCommerceCardToken(); 77 if ($cardToken) { 78 $paymentRequestData['cardToken'] = $cardToken; 79 } 80 //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 81 $applePayToken = wc_clean(wp_unslash($_POST["token"] ?? '')); 82 if ($applePayToken) { 83 $encodedApplePayToken = wp_json_encode($applePayToken); 84 $paymentRequestData['applePayPaymentToken'] = $encodedApplePayToken; 85 } 86 $paymentRequestData = $this->addCustomRequestFields($order, $paymentRequestData, $gateway); 87 return $paymentRequestData; 88 } 89 public function addSequenceTypeFirst($paymentRequestData) 90 { 91 $paymentRequestData['sequenceType'] = 'first'; 92 return $paymentRequestData; 57 return $this->requestFactory->createRequest('payment', $order, $customerId); 93 58 } 94 59 /** … … 152 117 /** 153 118 * @param \WC_Order $order 154 * @param \Mollie\Api\Resources\Payment $payment119 * @param Payment $payment 155 120 * @param string $paymentMethodTitle 156 121 */ … … 190 155 // Add messages to log 191 156 $this->logger->debug(__METHOD__ . ' payment at Mollie not paid, so no processing for order ' . $orderId); 157 } 158 } 159 /** 160 * @param \WC_Order $order 161 * @param Payment $payment 162 * @param string $paymentMethodTitle 163 */ 164 public function onWebhookAuthorized(WC_Order $order, Payment $payment, $paymentMethodTitle) 165 { 166 // Get order ID in the correct way depending on WooCommerce version 167 $orderId = $order->get_id(); 168 if ($payment->isAuthorized()) { 169 // Add messages to log 170 $this->logger->debug(__METHOD__ . ' called for order ' . $orderId); 171 // WooCommerce 2.2.0 has the option to store the Payment transaction id. 172 $order->payment_complete($payment->id); 173 // Add messages to log 174 $this->logger->debug(__METHOD__ . ' WooCommerce payment_complete() processed and returned to ' . __METHOD__ . ' for order ' . $orderId); 175 $order->add_order_note(sprintf( 176 /* translators: Placeholder 1: payment method title, placeholder 2: payment ID */ 177 __('Order authorized using %1$s payment (%2$s). Set order to completed in WooCommerce when you have shipped the products, to capture the payment. Do this within 28 days, or the order will expire. To handle individual order lines, process the order via the Mollie Dashboard.', 'mollie-payments-for-woocommerce'), 178 $paymentMethodTitle, 179 $payment->id . ($payment->mode === 'test' ? ' - ' . __('test mode', 'mollie-payments-for-woocommerce') : '') 180 )); 181 //check for webhook that order is Authorized on Paid webhook 182 $order->update_meta_data('_mollie_authorized', '1'); 183 // Mark the order as processed and paid via Mollie 184 $this->setOrderPaidAndProcessed($order); 185 // Remove (old) cancelled payments from this order 186 $this->unsetCancelledMolliePaymentId($orderId); 187 // Add messages to log 188 $this->logger->debug(__METHOD__ . ' processing order status update via Mollie plugin fully completed for order ' . $orderId); 189 // Subscription processing 190 $this->deleteSubscriptionFromPending($order); 191 } else { 192 // Add messages to log 193 $this->logger->debug(__METHOD__ . ' order at Mollie not authorized, so no processing for order ' . $orderId); 192 194 } 193 195 } … … 371 373 /** 372 374 * @param WC_Order $order 373 * @param MolliePaymentGatewayI$gateway375 * @param PaymentGateway $gateway 374 376 * @param $newOrderStatus 375 377 * @param $orderId … … 377 379 protected function maybeUpdateStatus(WC_Order $order, $gateway, $newOrderStatus) 378 380 { 379 if ($this->isOrderPaymentStartedByOtherGateway($order) || !is_a($gateway, MolliePaymentGateway::class)) {381 if ($this->isOrderPaymentStartedByOtherGateway($order) || !is_a($gateway, PaymentGateway::class)) { 380 382 $this->informNotUpdatingStatus($gateway->id, $order); 381 383 return; 382 384 } 383 $gateway->paymentService()->updateOrderStatus($order, $newOrderStatus); 384 } 385 protected function addCustomRequestFields($order, array $paymentRequestData, MolliePaymentGateway $gateway) 386 { 387 if ($gateway->paymentMethod()->hasProperty('paymentAPIfields')) { 388 $paymentAPIfields = $gateway->paymentMethod()->getProperty('paymentAPIfields'); 389 foreach ($paymentAPIfields as $field) { 390 if (!method_exists($this, 'create' . ucfirst($field))) { 391 continue; 392 } 393 $value = $this->{'create' . ucfirst($field)}($order); 394 if ($value) { 395 $paymentRequestData[$field] = $value; 396 } 397 } 398 } 399 return $paymentRequestData; 385 $this->updateOrderStatus($order, $newOrderStatus); 386 } 387 public function setPayment($data) 388 { 389 $this->data = $data; 400 390 } 401 391 } -
mollie-payments-for-woocommerce/trunk/src/Payment/MollieSubscription.php
r3164004 r3262577 4 4 5 5 use Mollie\Api\Types\SequenceType; 6 use Mollie\WooCommerce\Gateway\MolliePaymentGateway; 6 use Mollie\WooCommerce\Payment\Request\Middleware\MiddlewareHandler; 7 use Mollie\WooCommerce\Payment\Request\Middleware\PaymentDescriptionMiddleware; 8 use Mollie\WooCommerce\PaymentMethods\AbstractPaymentMethod; 7 9 use Mollie\WooCommerce\SDK\Api; 8 use Mollie\WooCommerce\Subscription\MollieSubscriptionGateway; 10 use Mollie\WooCommerce\Subscription\MollieSubscriptionGatewayHandler; 11 use Mollie\Psr\Log\LoggerInterface as Logger; 9 12 class MollieSubscription extends \Mollie\WooCommerce\Payment\MollieObject 10 13 { 11 14 protected $pluginId; 12 15 /** 16 * @var mixed 17 */ 18 private AbstractPaymentMethod $paymentMethod; 19 protected MiddlewareHandler $middleware; 20 /** 13 21 * Molliesubscription constructor. 14 22 * 15 23 */ 16 public function __construct($pluginId, Api $apiHelper, $settingsHelper, $dataHelper, $logger)24 public function __construct($pluginId, Api $apiHelper, $settingsHelper, $dataHelper, Logger $logger, AbstractPaymentMethod $paymentMethod, $middlewareHandler) 17 25 { 18 26 $this->pluginId = $pluginId; … … 21 29 $this->dataHelper = $dataHelper; 22 30 $this->logger = $logger; 31 $this->paymentMethod = $paymentMethod; 32 $this->middleware = $middlewareHandler; 23 33 } 24 34 /** … … 31 41 $paymentLocale = $this->settingsHelper->getPaymentLocale(); 32 42 $gateway = wc_get_payment_gateway_by_order($order); 33 if (!$gateway || ! $gateway instanceof MolliePaymentGateway) {43 if (!$gateway || !mollieWooCommerceIsMollieGateway($gateway->id)) { 34 44 return ['result' => 'failure']; 35 45 } 36 46 $gatewayId = $gateway->id; 47 $methodId = substr($gatewayId, strrpos($gatewayId, '_') + 1); 37 48 $optionName = $this->pluginId . '_api_payment_description'; 38 49 $option = get_option($optionName); 39 50 $paymentDescription = $this->getRecurringPaymentDescription($order, $option, $initialPaymentUsedOrderAPI); 40 $selectedIssuer = $gateway->getSelectedIssuer(); 41 $returnUrl = $gateway->get_return_url($order); 42 $returnUrl = $this->getReturnUrl($order, $returnUrl); 43 $webhookUrl = $this->getWebhookUrl($order, $gatewayId); 44 return array_filter(['amount' => ['currency' => $this->dataHelper->getOrderCurrency($order), 'value' => $this->dataHelper->formatCurrencyValue($order->get_total(), $this->dataHelper->getOrderCurrency($order))], 'description' => $paymentDescription, 'redirectUrl' => $returnUrl, 'webhookUrl' => $webhookUrl, 'method' => $gateway->paymentMethod()->getProperty('id'), 'issuer' => $selectedIssuer, 'locale' => $paymentLocale, 'metadata' => ['order_id' => $order->get_id()], 'sequenceType' => 'recurring', 'customerId' => $customerId]); 51 $requestData = array_filter(['amount' => ['currency' => $this->dataHelper->getOrderCurrency($order), 'value' => $this->dataHelper->formatCurrencyValue($order->get_total(), $this->dataHelper->getOrderCurrency($order))], 'description' => $paymentDescription, 'method' => $methodId, 'locale' => $paymentLocale, 'metadata' => ['order_id' => $order->get_id()], 'sequenceType' => SequenceType::SEQUENCETYPE_RECURRING, 'customerId' => $customerId]); 52 $context = 'payment'; 53 return $this->middleware->handle($requestData, $order, $context); 45 54 } 46 55 protected function getRecurringPaymentDescription($order, $option, $initialPaymentUsedOrderAPI) … … 56 65 return $description; 57 66 } 58 return $this->getPaymentDescription($order, $option); 67 $middleware = new PaymentDescriptionMiddleware($this->dataHelper); 68 $requestData = []; 69 $context = 'payment'; 70 $result = $middleware->__invoke($requestData, $order, $context, static function ($requestData) { 71 return $requestData; 72 }); 73 return $result['description']; 59 74 } 60 75 /** … … 62 77 * 63 78 * @param bool $status 64 * @param MollieSubscriptionGateway $subscriptionGateway79 * @param MollieSubscriptionGatewayHandler $deprecatedSubscriptionHelper 65 80 * @return bool 66 81 */ 67 public function isAvailableForSubscriptions(bool $status, MollieSubscriptionGateway $subscriptionGateway, $orderTotal): bool82 public function isAvailableForSubscriptions(bool $status, MollieSubscriptionGatewayHandler $deprecatedSubscriptionHelper, $orderTotal, $gateway): bool 68 83 { 69 84 $subscriptionPluginActive = class_exists('WC_Subscriptions') && class_exists('WC_Subscriptions_Admin'); … … 71 86 return $status; 72 87 } 73 $currency = $ subscriptionGateway->getCurrencyFromOrder();74 $billingCountry = $ subscriptionGateway->getBillingCountry();75 $paymentLocale = $ subscriptionGateway->dataService()->getPaymentLocale();88 $currency = $deprecatedSubscriptionHelper->getCurrencyFromOrder(); 89 $billingCountry = $deprecatedSubscriptionHelper->getBillingCountry(); 90 $paymentLocale = $deprecatedSubscriptionHelper->dataService()->getPaymentLocale(); 76 91 // Check recurring totals against recurring payment methods for future renewal payments 77 $recurringTotal = $ subscriptionGateway->get_recurring_total();92 $recurringTotal = $deprecatedSubscriptionHelper->get_recurring_total(); 78 93 // See get_available_payment_gateways() in woocommerce-subscriptions/includes/gateways/class-wc-subscriptions-payment-gateways.php 79 94 $acceptManualRenewals = 'yes' === get_option(\WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals', 'no'); 80 $supportsSubscriptions = $ subscriptionGateway->supports('subscriptions');95 $supportsSubscriptions = $gateway->supports('subscriptions'); 81 96 if ($acceptManualRenewals === \true || !$supportsSubscriptions || empty($recurringTotal)) { 82 97 return $status; … … 85 100 // First check recurring payment methods CC and SDD 86 101 $filters = $this->buildFilters($currency, $recurring_total, $billingCountry, SequenceType::SEQUENCETYPE_RECURRING, $paymentLocale); 87 $status = $ subscriptionGateway->isAvailableMethodInCheckout($filters);102 $status = $deprecatedSubscriptionHelper->isAvailableMethodInCheckout($filters); 88 103 } 89 104 // Check available first payment methods with today's order total, but ignore SSD gateway (not shown in checkout) 90 if ($ subscriptionGateway->paymentMethod()->getProperty('id') === 'mollie_wc_gateway_directdebit') {105 if ($deprecatedSubscriptionHelper->paymentMethod()->getProperty('id') === 'mollie_wc_gateway_directdebit') { 91 106 return $status; 92 107 } 93 108 $filters = $this->buildFilters($currency, $orderTotal, $billingCountry, SequenceType::SEQUENCETYPE_FIRST, $paymentLocale); 94 return $ subscriptionGateway->isAvailableMethodInCheckout($filters);109 return $deprecatedSubscriptionHelper->isAvailableMethodInCheckout($filters); 95 110 } 96 111 /** -
mollie-payments-for-woocommerce/trunk/src/Payment/OrderLines.php
r3226701 r3262577 106 106 } 107 107 $this->currency = $this->dataHelper->getOrderCurrency($this->order); 108 $mollie_order_item = ['sku' => $this->get_item_reference($product), 'name' => $this->get_item_name($cart_item), 'quantity' => $this->get_item_quantity($cart_item), 'vatRate' => round($this->get_item_vatRate($cart_item, $product), 2), 'unitPrice' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_price($cart_item), $this->currency)], 'totalAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_total_amount($cart_item), $this->currency)], 'vatAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_tax_amount($cart_item), $this->currency)], 'discountAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_discount_amount($cart_item), $this->currency)], 'metadata' => ['order_item_id' => $cart_item->get_id()]]; 108 $mollie_order_item = ['sku' => $this->get_item_reference($product), 'type' => $product->is_virtual() ? 'digital' : 'physical', 'name' => $this->get_item_name($cart_item), 'quantity' => $this->get_item_quantity($cart_item), 'vatRate' => round($this->get_item_vatRate($cart_item, $product), 2), 'unitPrice' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_price($cart_item), $this->currency)], 'totalAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_total_amount($cart_item), $this->currency)], 'vatAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_tax_amount($cart_item), $this->currency)], 'discountAmount' => ['currency' => $this->currency, 'value' => $this->dataHelper->formatCurrencyValue($this->get_item_discount_amount($cart_item), $this->currency)], 'metadata' => ['order_item_id' => $cart_item->get_id()], 'productUrl' => $product->get_permalink()]; 109 if ($product->get_image_id()) { 110 $productImage = wp_get_attachment_image_src($product->get_image_id(), 'full'); 111 if (isset($productImage[0])) { 112 $mollie_order_item['imageUrl'] = $productImage[0]; 113 } 114 } 109 115 if ($isMealVoucherEnabled && $this->get_item_category($product, $voucherDefaultCategory) != "no_category") { 110 116 $mollie_order_item['category'] = $this->get_item_category($product, $voucherDefaultCategory); -
mollie-payments-for-woocommerce/trunk/src/Payment/PaymentCheckoutRedirectService.php
r3164004 r3262577 19 19 protected $dataHelper; 20 20 /** 21 * Payment Service constructor.21 * PaymentCheckoutRedirectService constructor. 22 22 */ 23 23 public function __construct($dataHelper) -
mollie-payments-for-woocommerce/trunk/src/Payment/PaymentFactory.php
r3164004 r3262577 11 11 class PaymentFactory 12 12 { 13 /** 14 * @var Data 15 */ 16 protected $dataHelper; 17 /** 18 * @var Api 19 */ 20 protected $apiHelper; 21 protected $settingsHelper; 22 /** 23 * @var string 24 */ 25 protected $pluginId; 26 protected $logger; 27 /** 28 * @var OrderLines 29 */ 30 protected $orderLines; 13 private $mollieOrderFactory; 14 private $molliePaymentFactory; 31 15 /** 32 16 * PaymentFactory constructor. 33 17 */ 34 public function __construct( Data $dataHelper, Api $apiHelper, Settings $settingsHelper, string $pluginId, $logger, \Mollie\WooCommerce\Payment\OrderLines $orderLines)18 public function __construct(callable $mollieOrderFactory, callable $molliePaymentFactory) 35 19 { 36 $this->dataHelper = $dataHelper; 37 $this->apiHelper = $apiHelper; 38 $this->settingsHelper = $settingsHelper; 39 $this->pluginId = $pluginId; 40 $this->logger = $logger; 41 $this->orderLines = $orderLines; 20 $this->mollieOrderFactory = $mollieOrderFactory; 21 $this->molliePaymentFactory = $molliePaymentFactory; 42 22 } 43 23 /** … … 49 29 { 50 30 if (!is_object($data) && $data === 'order' || is_string($data) && strpos($data, 'ord_') !== \false || is_object($data) && $data->resource === 'order') { 51 $refundLineItemsBuilder = new \Mollie\WooCommerce\Payment\RefundLineItemsBuilder($this->dataHelper); 52 $apiKey = $this->settingsHelper->getApiKey(); 53 $orderItemsRefunded = new \Mollie\WooCommerce\Payment\OrderItemsRefunder($refundLineItemsBuilder, $this->dataHelper, $this->apiHelper->getApiClient($apiKey)->orders); 54 return new \Mollie\WooCommerce\Payment\MollieOrder($orderItemsRefunded, $data, $this->pluginId, $this->apiHelper, $this->settingsHelper, $this->dataHelper, $this->logger, $this->orderLines); 31 $mollieOrder = ($this->mollieOrderFactory)(); 32 $mollieOrder->setOrder($data); 33 return $mollieOrder; 55 34 } 56 35 if (!is_object($data) && $data === 'payment' || !is_object($data) && strpos($data, 'tr_') !== \false || is_object($data) && $data->resource === 'payment') { 57 return new \Mollie\WooCommerce\Payment\MolliePayment($data, $this->pluginId, $this->apiHelper, $this->settingsHelper, $this->dataHelper, $this->logger); 36 $molliePayment = ($this->molliePaymentFactory)(); 37 $molliePayment->setPayment($data); 38 return $molliePayment; 58 39 } 59 40 return \false; -
mollie-payments-for-woocommerce/trunk/src/Payment/PaymentModule.php
r3164004 r3262577 10 10 use Mollie\Api\Exceptions\ApiException; 11 11 use Mollie\Api\Resources\Refund; 12 use Mollie\WooCommerce\Gateway\MolliePaymentGateway; 13 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayI; 12 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler; 13 use Mollie\WooCommerce\Gateway\Refund\OrderItemsRefunder; 14 use Mollie\WooCommerce\MerchantCapture\Capture\Action\CapturePayment; 15 use Mollie\WooCommerce\PaymentMethods\InstructionStrategies\OrderInstructionsManager; 14 16 use Mollie\WooCommerce\SDK\Api; 15 17 use Mollie\WooCommerce\SDK\HttpResponse; 16 18 use Mollie\WooCommerce\Settings\Settings; 17 use Mollie\WooCommerce\Shared\Data;18 19 use Mollie\WooCommerce\Shared\SharedDataDictionary; 19 20 use Mollie\Psr\Container\ContainerInterface; 20 21 use Mollie\Psr\Log\LoggerInterface as Logger; 21 use Mollie\Psr\Log\LogLevel;22 22 use RuntimeException; 23 23 use WC_Order; … … 43 43 */ 44 44 protected $gatewayClassnames; 45 /** 46 * @var ContainerInterface 47 */ 48 protected $container; 45 49 public function services(): array 46 50 { 47 return [\Mollie\WooCommerce\Payment\OrderLines::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Payment\OrderLines { 48 $data = $container->get('settings.data_helper'); 49 $pluginId = $container->get('shared.plugin_id'); 50 return new \Mollie\WooCommerce\Payment\OrderLines($data, $pluginId); 51 }, \Mollie\WooCommerce\Payment\PaymentFactory::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Payment\PaymentFactory { 52 $settingsHelper = $container->get('settings.settings_helper'); 53 assert($settingsHelper instanceof Settings); 54 $apiHelper = $container->get('SDK.api_helper'); 55 assert($apiHelper instanceof Api); 56 $data = $container->get('settings.data_helper'); 57 assert($data instanceof Data); 58 $pluginId = $container->get('shared.plugin_id'); 59 $logger = $container->get(Logger::class); 60 assert($logger instanceof Logger); 61 $orderLines = $container->get(\Mollie\WooCommerce\Payment\OrderLines::class); 62 return new \Mollie\WooCommerce\Payment\PaymentFactory($data, $apiHelper, $settingsHelper, $pluginId, $logger, $orderLines); 63 }, \Mollie\WooCommerce\Payment\MollieObject::class => static function (ContainerInterface $container): \Mollie\WooCommerce\Payment\MollieObject { 64 $logger = $container->get(Logger::class); 65 assert($logger instanceof Logger); 66 $data = $container->get('settings.data_helper'); 67 assert($data instanceof Data); 68 $apiHelper = $container->get('SDK.api_helper'); 69 assert($apiHelper instanceof Api); 70 $pluginId = $container->get('shared.plugin_id'); 71 $paymentFactory = $container->get(\Mollie\WooCommerce\Payment\PaymentFactory::class); 72 assert($paymentFactory instanceof \Mollie\WooCommerce\Payment\PaymentFactory); 73 $settingsHelper = $container->get('settings.settings_helper'); 74 assert($settingsHelper instanceof Settings); 75 return new \Mollie\WooCommerce\Payment\MollieObject($data, $logger, $paymentFactory, $apiHelper, $settingsHelper, $pluginId); 76 }]; 51 static $services; 52 if ($services === null) { 53 $services = require_once __DIR__ . '/inc/services.php'; 54 } 55 return $services(); 77 56 } 78 57 public function run(ContainerInterface $container): bool … … 88 67 $this->pluginId = $container->get('shared.plugin_id'); 89 68 $this->gatewayClassnames = $container->get('gateway.classnames'); 69 $this->container = $container; 90 70 // Listen to return URL call 91 add_action('woocommerce_api_mollie_return', [$this, 'onMollieReturn']); 92 add_action('template_redirect', [$this, 'mollieReturnRedirect']); 71 add_action('woocommerce_api_mollie_return', function () use ($container) { 72 $this->onMollieReturn($container); 73 }, 10, 1); 74 add_action('template_redirect', function () use ($container) { 75 $this->mollieReturnRedirect($container); 76 }); 93 77 // Show Mollie instructions on order details page 94 add_action('woocommerce_order_details_after_order_table', [$this, 'onOrderDetails'], 10, 1); 78 add_action('woocommerce_order_details_after_order_table', function (WC_Order $order) use ($container) { 79 $this->onOrderDetails($order, $container); 80 }, 10, 1); 95 81 // Cancel order at Mollie (for Orders API/Klarna) 96 82 add_action('woocommerce_order_status_cancelled', [$this, 'cancelOrderAtMollie']); … … 102 88 $this->handleExpiryDateCancelation($paymentMethods); 103 89 }, 10, 2); 104 add_action( \Mollie\WooCommerce\Payment\OrderItemsRefunder::ACTION_AFTER_REFUND_ORDER_ITEMS, [$this, 'addOrderNoteForRefundCreated'], 10, 3);105 add_action( \Mollie\WooCommerce\Payment\OrderItemsRefunder::ACTION_AFTER_CANCELED_ORDER_ITEMS, [$this, 'addOrderNoteForCancelledLineItems'], 10, 2);90 add_action(OrderItemsRefunder::ACTION_AFTER_REFUND_ORDER_ITEMS, [$this, 'addOrderNoteForRefundCreated'], 10, 3); 91 add_action(OrderItemsRefunder::ACTION_AFTER_CANCELED_ORDER_ITEMS, [$this, 'addOrderNoteForCancelledLineItems'], 10, 2); 106 92 return \true; 107 93 } … … 184 170 * 185 171 */ 186 public function onMollieReturn( )172 public function onMollieReturn($container) 187 173 { 188 174 try { … … 195 181 $gateway = wc_get_payment_gateway_by_order($order); 196 182 $orderId = $order->get_id(); 183 $oldGatewayInstances = $container->get('__deprecated.gateway_helpers'); 184 $mollieGatewayHelper = $oldGatewayInstances[$gateway->id]; 197 185 if (!$gateway) { 198 186 $gatewayName = $order->get_payment_method(); … … 201 189 return; 202 190 } 203 if (! $gateway instanceof MolliePaymentGateway) {191 if (!mollieWooCommerceIsMollieGateway($gateway->id)) { 204 192 $this->httpResponse->setHttpResponseCode(400); 205 $this->logger->debug(__METHOD__ . ": Invalid gateway {get_class({$gateway})} for this plugin. Order {$orderId}."); 206 return; 207 } 208 $redirect_url = $gateway->getReturnRedirectUrlForOrder($order); 193 $gatewayClass = get_class($gateway); 194 $this->logger->debug(__METHOD__ . ": Invalid gateway {$gatewayClass} for this plugin. Order {$orderId}."); 195 return; 196 } 197 $redirect_url = $mollieGatewayHelper->getReturnRedirectUrlForOrder($order); 209 198 // Add utm_nooverride query string 210 199 $redirect_url = add_query_arg(['utm_nooverride' => 1], $redirect_url); … … 217 206 * 218 207 */ 219 public function mollieReturnRedirect( )208 public function mollieReturnRedirect($container) 220 209 { 221 210 if (isset($_GET['filter_flag'])) { 222 211 $filterFlag = sanitize_text_field(wp_unslash($_GET['filter_flag'])); 223 212 if ($filterFlag === 'onMollieReturn') { 224 self::onMollieReturn( );213 self::onMollieReturn($container); 225 214 } 226 215 } … … 229 218 * @param WC_Order $order 230 219 */ 231 public function onOrderDetails(WC_Order $order )220 public function onOrderDetails(WC_Order $order, ContainerInterface $container) 232 221 { 233 222 if (is_order_received_page()) { … … 236 225 * Instructions already displayed on top of order received page by $gateway->thankyou_page() 237 226 * 238 * @see MolliePaymentGateway ::thankyou_page227 * @see MolliePaymentGatewayHandler::thankyou_page 239 228 */ 240 229 return; 241 230 } 242 231 $gateway = wc_get_payment_gateway_by_order($order); 243 if (!$gateway || !$gateway instanceof MolliePaymentGateway) { 244 return; 245 } 246 /** @var MolliePaymentGatewayI $gateway */ 247 $gateway->displayInstructions($order); 232 if (!$gateway || !mollieWooCommerceIsMollieGateway($gateway->id)) { 233 return; 234 } 235 assert($gateway instanceof \WC_Payment_Gateway); 236 $instructionsManager = $container->get(OrderInstructionsManager::class); 237 $oldGatewayInstances = $container->get('__deprecated.gateway_helpers'); 238 $mollieGatewayHelper = $oldGatewayInstances[$gateway->id]; 239 $instructionsManager->displayInstructions($gateway, $mollieGatewayHelper, $order); 248 240 } 249 241 /** … … 264 256 } 265 257 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Try to process completed order for a potential capture at Mollie.'); 266 // Does WooCommerce order contain a Mollie Order? 267 $mollie_order_id = ($mollie_order_id = $order->get_meta('_mollie_order_id', \true)) ? $mollie_order_id : \false; 268 // Is it a payment? you cannot ship a payment 269 if ($mollie_order_id === \false || substr($mollie_order_id, 0, 3) === 'tr_') { 270 $message = _x('Processing a payment, no capture needed', 'Order note info', 'mollie-payments-for-woocommerce'); 258 $mollie_transaction_id = ($mollie_transaction_id = $order->get_meta('_mollie_order_id', \true)) ? $mollie_transaction_id : \false; 259 if (!$mollie_transaction_id) { 260 $mollie_transaction_id = ($mollie_transaction_id = $order->get_meta('_mollie_payment_id', \true)) ? $mollie_transaction_id : \false; 261 } 262 if (empty($mollie_transaction_id)) { 263 $message = _x('Order contains Mollie payment method, but not a valid Mollie Transaction ID. Processing shipment & capture failed.', 'Order note info', 'mollie-payments-for-woocommerce'); 271 264 $order->add_order_note($message); 272 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Processing a payment, no capture needed.'); 273 return; 265 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' Order contains Mollie payment method, but not a valid Mollie Transaction ID. Processing shipment & capture failed.'); 274 266 } 275 267 $apiKey = $this->settingsHelper->getApiKey(); 276 268 try { 277 // Get the order from the Mollie API 278 $mollie_order = $this->apiHelper->getApiClient($apiKey)->orders->get($mollie_order_id); 269 // Get the order or payment from the Mollie API 270 if (substr($mollie_transaction_id, 0, 3) === 'tr_') { 271 $mollie_transaction = $this->apiHelper->getApiClient($apiKey)->payments->get($mollie_transaction_id); 272 $mollie_transaction_type = 'Payment'; 273 } else { 274 $mollie_transaction = $this->apiHelper->getApiClient($apiKey)->orders->get($mollie_transaction_id); 275 $mollie_transaction_type = 'Order'; 276 } 279 277 // Check that order is Paid or Authorized and can be captured 280 if ($mollie_ order->isCanceled()) {281 $message = _x(' Orderalready canceled at Mollie, can not be shipped/captured.', 'Order note info', 'mollie-payments-for-woocommerce');278 if ($mollie_transaction->isCanceled()) { 279 $message = _x('Transaction already canceled at Mollie, can not be shipped/captured.', 'Order note info', 'mollie-payments-for-woocommerce'); 282 280 $order->add_order_note($message); 283 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Orderalready canceled at Mollie, can not be shipped/captured.');281 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - ' . $mollie_transaction_type . ' already canceled at Mollie, can not be shipped/captured.'); 284 282 return; 285 283 } 286 if ( $mollie_order->isCompleted()) {287 $message = _x(' Orderalready completed at Mollie, can not be shipped/captured.', 'Order note info', 'mollie-payments-for-woocommerce');284 if (method_exists($mollie_transaction, 'isCompleted') && $mollie_transaction->isCompleted()) { 285 $message = _x('Transaction already completed at Mollie, can not be shipped/captured.', 'Order note info', 'mollie-payments-for-woocommerce'); 288 286 $order->add_order_note($message); 289 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Orderalready completed at Mollie, can not be shipped/captured.');287 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - ' . $mollie_transaction_type . ' already completed at Mollie, can not be shipped/captured.'); 290 288 return; 291 289 } 292 if ($mollie_order->isPaid() || $mollie_order->isAuthorized()) { 293 $this->apiHelper->getApiClient($apiKey)->orders->get($mollie_order_id)->shipAll(); 290 if ($mollie_transaction->isPaid() || $mollie_transaction->isAuthorized()) { 291 if (substr($mollie_transaction_id, 0, 3) === 'tr_') { 292 if ($mollie_transaction->isAuthorized()) { 293 $this->container->get(CapturePayment::class)($order_id); 294 } else { 295 $message = _x('Payment status is already paid at Mollie, can not be captured.', 'Order note info', 'mollie-payments-for-woocommerce'); 296 $order->add_order_note($message); 297 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Payment already completed at Mollie, can not be captured.'); 298 } 299 return; 300 } 301 $this->apiHelper->getApiClient($apiKey)->orders->get($mollie_transaction_id)->shipAll(); 294 302 $message = _x('Order successfully updated to shipped at Mollie, capture of funds underway.', 'Order note info', 'mollie-payments-for-woocommerce'); 295 303 $order->add_order_note($message); … … 297 305 return; 298 306 } 299 $message = _x(' Ordernot paid or authorized at Mollie yet, can not be shipped.', 'Order note info', 'mollie-payments-for-woocommerce');307 $message = _x('Transaction not paid or authorized at Mollie yet, can not be shipped.', 'Order note info', 'mollie-payments-for-woocommerce'); 300 308 $order->add_order_note($message); 301 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Ordernot paid or authorized at Mollie yet, can not be shipped.');309 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - ' . $mollie_transaction_type . ' not paid or authorized at Mollie yet, can not be shipped.'); 302 310 } catch (ApiException $e) { 303 311 $this->logger->debug(__METHOD__ . ' - ' . $order_id . ' - Processing shipment & capture failed, error: ' . $e->getMessage()); -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/AbstractPaymentMethod.php
r3226701 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods; 5 5 6 use Mollie\WooCommerce\Gateway\MolliePaymentGateway; 6 use Mollie\Inpsyde\PaymentGateway\Icon; 7 use Mollie\Inpsyde\PaymentGateway\IconProviderInterface; 8 use Mollie\Inpsyde\PaymentGateway\Method\CustomSettingsFields; 9 use Mollie\Inpsyde\PaymentGateway\Method\CustomSettingsFieldsDefinition; 10 use Mollie\Inpsyde\PaymentGateway\Method\DefaultPaymentMethodDefinitionTrait; 11 use Mollie\Inpsyde\PaymentGateway\Method\PaymentMethodDefinition; 12 use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface; 13 use Mollie\Inpsyde\PaymentGateway\PaymentProcessorInterface; 14 use Mollie\Inpsyde\PaymentGateway\PaymentRequestValidatorInterface; 15 use Mollie\Inpsyde\PaymentGateway\RefundProcessorInterface; 16 use Mollie\Inpsyde\PaymentGateway\StaticIconProvider; 7 17 use Mollie\WooCommerce\Gateway\Surcharge; 8 use Mollie\WooCommerce\Payment\Payment FieldsService;9 use Mollie\WooCommerce\Settings\ Settings;18 use Mollie\WooCommerce\Payment\PaymentProcessor; 19 use Mollie\WooCommerce\Settings\General\MultiCountrySettingsField; 10 20 use Mollie\WooCommerce\Shared\SharedDataDictionary; 11 abstract class AbstractPaymentMethod implements \Mollie\WooCommerce\PaymentMethods\PaymentMethodI 21 use Mollie\Psr\Container\ContainerInterface; 22 use Mollie\WooCommerce\PaymentMethods\Icon\GatewayIconsRenderer; 23 use Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\NoopPaymentFieldsRenderer; 24 use Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\DefaultFieldsStrategy; 25 abstract class AbstractPaymentMethod implements \Mollie\WooCommerce\PaymentMethods\PaymentMethodI, PaymentMethodDefinition 12 26 { 13 /** 14 * @var string 15 */ 16 protected $id; 27 use DefaultPaymentMethodDefinitionTrait; 17 28 /** 18 29 * @var string[] … … 23 34 */ 24 35 protected $settings = []; 25 /**26 * @var IconFactory27 */28 protected $iconFactory;29 /**30 * @var Settings31 */32 protected $settingsHelper;33 /**34 * @var PaymentFieldsService35 */36 protected $paymentFieldsService;37 /**38 * @var Surcharge39 */40 36 protected $surcharge; 41 37 /** 42 * @var array43 */44 private $apiPaymentMethod;45 /**46 38 * @var bool 47 39 */ 48 40 protected bool $translationsInitialized = \false; 49 public function __construct(\Mollie\WooCommerce\PaymentMethods\IconFactory $iconFactory, Settings $settingsHelper, PaymentFieldsService $paymentFieldsService, Surcharge $surcharge, array $apiPaymentMethod) 50 { 51 $this->id = $this->getIdFromConfig(); 52 $this->iconFactory = $iconFactory; 53 $this->settingsHelper = $settingsHelper; 54 $this->paymentFieldsService = $paymentFieldsService; 55 $this->surcharge = $surcharge; 41 public function __construct() 42 { 56 43 $this->config = $this->getConfig(); 57 44 $this->settings = $this->getSettings(); 58 $this->apiPaymentMethod = $apiPaymentMethod; 59 add_action('init', [$this, 'initializeTranslations']); 60 add_action('init', [$this, 'updateSettingsWithDefaults']); 61 } 62 public function title(): string 63 { 64 $useApiTitle = apply_filters('mollie_wc_gateway_use_api_title', $this->isUseApiTitleChecked(), $this->id); 45 $this->surcharge = new Surcharge(); 46 } 47 public function title(ContainerInterface $container): string 48 { 49 $useApiTitle = apply_filters('mollie_wc_gateway_use_api_title', $this->isUseApiTitleChecked(), $this->getIdFromConfig()); 65 50 $title = $this->getProperty('title'); 66 51 //new installations should use the api title 67 52 if ($useApiTitle || $title === \false) { 68 return $this->getApiTitle( );53 return $this->getApiTitle($container); 69 54 } 70 55 return $title; … … 76 61 public function getIdFromConfig(): string 77 62 { 78 return $this->getConfig()['id']; 63 $config = $this->getConfig(); 64 return $config['id']; 79 65 } 80 66 public function getUploadedImage() … … 113 99 } 114 100 /** 115 * Payment method custom icon url116 * @return string117 */118 public function getIconUrl(): string119 {120 if ($uploadedImageUrl = $this->getUploadedImage()) {121 return $this->iconFactory->getExternalIconHtml($uploadedImageUrl);122 }123 $useAPIImage = apply_filters('mollie_wc_gateway_use_api_icon', $this->isUseApiTitleChecked(), $this->id);124 if (isset($this->apiPaymentMethod["image"]) && property_exists($this->apiPaymentMethod["image"], "svg") && !$this->isCreditCardSelectorEnabled() && $useAPIImage) {125 return $this->iconFactory->getExternalIconHtml($this->apiPaymentMethod["image"]->svg);126 }127 return $this->iconFactory->getIconUrl($this->getIdFromConfig());128 }129 /**130 101 * Check if payment method should show any icon 131 102 * @return bool … … 135 106 $defaultIconSetting = \true; 136 107 return $this->hasProperty('display_logo') ? $this->getProperty('display_logo') === 'yes' : $defaultIconSetting; 137 }138 /**139 * Settings that apply to all payment methods140 * @return array141 */142 public function getSharedFormFields()143 {144 $defaultTitle = $this->getApiTitle();145 return $this->settingsHelper->generalFormFields($defaultTitle, $this->config['defaultDescription'], $this->config['confirmationDelayed']);146 }147 /**148 * Settings specific to every payment method149 * @return mixed150 */151 public function getAllFormFields()152 {153 return $this->getFormFields($this->getSharedFormFields());154 }155 /**156 * Sets the gateway's payment fields strategy based on payment method157 * @param $gateway158 * @return void159 */160 public function paymentFieldsStrategy($gateway)161 {162 $this->paymentFieldsService->setStrategy($this);163 $this->paymentFieldsService->executeStrategy($gateway);164 }165 /**166 * @return PaymentFieldsService167 */168 public function paymentFieldsService(): PaymentFieldsService169 {170 return $this->paymentFieldsService;171 108 } 172 109 /** … … 194 131 public function getSettings(): array 195 132 { 196 $optionName = 'mollie_wc_gateway_' . $this-> id. '_settings';133 $optionName = 'mollie_wc_gateway_' . $this->getIdFromConfig() . '_settings'; 197 134 $settings = get_option($optionName, \false); 198 135 if (!$settings) { … … 205 142 * @return array 206 143 */ 207 public function updateSettingsWithDefaults( ): array208 { 209 $optionName = 'mollie_wc_gateway_' . $this-> id. '_settings';144 public function updateSettingsWithDefaults(ContainerInterface $container): array 145 { 146 $optionName = 'mollie_wc_gateway_' . $this->getIdFromConfig() . '_settings'; 210 147 $settings = get_option($optionName, \false); 211 148 if (!$settings) { 212 $settings = $this->defaultSettings( );149 $settings = $this->defaultSettings($container); 213 150 update_option($optionName, $settings, \true); 214 151 } 215 152 return $settings; 216 }217 /**218 * Order status for cancelled payments setting219 *220 * @return string|null221 */222 public function getOrderStatusCancelledPayments()223 {224 return $this->settingsHelper->getOrderStatusCancelledPayments();225 153 } 226 154 /** … … 268 196 * @return array 269 197 */ 270 public function defaultSettings(): array 271 { 272 $fields = $this->getAllFormFields(); 198 public function defaultSettings(ContainerInterface $container): array 199 { 200 $defaultTitle = $this->getApiTitle($container); 201 $settingsHelper = $container->get('settings.settings_helper'); 202 $generalFormFields = $settingsHelper->generalFormFields($defaultTitle, $this->config['defaultDescription'], $this->config['confirmationDelayed']); 203 $fields = $this->getFormFields($generalFormFields); 273 204 //remove setting title fields 274 205 $fields = array_filter($fields, static function ($field) { … … 280 211 return array_combine(array_keys($fields), array_column($fields, 'default')) ?: []; 281 212 } 282 /** 283 * Update the payment method's settings 284 * @param string $optionName 285 * @param string $newValue 286 * @return void 287 */ 288 public function updateMethodOption(string $optionName, string $newValue) 289 { 290 $settingName = 'mollie_wc_gateway_' . $this->id . '_settings'; 291 $settings = get_option($settingName, \false); 292 $settings[$optionName] = $newValue; 293 update_option($settingName, $settings, \true); 294 } 295 private function getApiTitle() 296 { 297 $apiTitle = $this->apiPaymentMethod['description'] ?? null; 213 private function getApiTitle(ContainerInterface $container): string 214 { 215 $apiMethod = $container->get('gateway.getPaymentMethodsAfterFeatureFlag')[$this->getIdFromConfig()]; 216 $apiTitle = $apiMethod['description'] ?? null; 298 217 return $apiTitle ?: $this->config['defaultTitle']; 299 218 } … … 310 229 return $savedTitle === $this->config['defaultTitle']; 311 230 } 231 public function id(): string 232 { 233 return 'mollie_wc_gateway_' . $this->getIdFromConfig(); 234 } 235 public function paymentProcessor(ContainerInterface $container): PaymentProcessorInterface 236 { 237 return $container->get(PaymentProcessor::class); 238 } 239 public function paymentRequestValidator(ContainerInterface $container): PaymentRequestValidatorInterface 240 { 241 return $container->get('payment_gateways.noop_payment_request_validator'); 242 } 243 public function methodTitle(ContainerInterface $container): string 244 { 245 return 'Mollie - ' . $this->title($container); 246 } 247 public function description(ContainerInterface $container): string 248 { 249 $description = $this->getProcessedDescription(); 250 return empty($description) ? '' : $description; 251 } 252 public function methodDescription(ContainerInterface $container): string 253 { 254 return $this->getProperty('settingsDescription'); 255 } 256 /** 257 * @inheritDoc 258 */ 259 public function availabilityCallback(ContainerInterface $container): callable 260 { 261 $gatewayInstances = $container->get('__deprecated.gateway_helpers'); 262 $gatewayId = $this->id(); 263 return static function ($gateway) use ($gatewayInstances, $gatewayId) { 264 return $gatewayInstances[$gatewayId]->is_available($gateway); 265 }; 266 } 267 public function supports(ContainerInterface $container): array 268 { 269 $supports = $this->getProperty('supports'); 270 $isSepa = $this->getProperty('SEPA') === \true; 271 $isSubscription = $this->getProperty('Subscription') === \true; 272 $subscriptionHooks = $container->get('gateway.subscriptionsSupports'); 273 if ($isSepa || $isSubscription) { 274 $supports = array_merge($supports, $subscriptionHooks); 275 } 276 return $supports; 277 } 278 public function refundProcessor(ContainerInterface $container): RefundProcessorInterface 279 { 280 $supports = $this->getProperty('supports'); 281 $supportsRefunds = $supports && in_array('refunds', $supports, \true); 282 if ($supportsRefunds) { 283 return $container->get('payment_gateway.getRefundProcessor')($this->getIdFromConfig()); 284 } 285 return $container->get('payment_gateways.noop_refund_processor'); 286 } 287 public function paymentMethodIconProvider(ContainerInterface $container): IconProviderInterface 288 { 289 $iconFactory = $container->get(\Mollie\WooCommerce\PaymentMethods\IconFactory::class); 290 $url = $iconFactory->getIconUrl($this->getIdFromConfig()); 291 if ($uploadedImageUrl = $this->getUploadedImage()) { 292 $url = $iconFactory->getExternalIconHtml($uploadedImageUrl); 293 } 294 $useAPIImage = apply_filters('mollie_wc_gateway_use_api_icon', $this->isUseApiTitleChecked(), $this->getIdFromConfig()); 295 if (isset($this->apiPaymentMethod["image"]) && property_exists($this->apiPaymentMethod["image"], "svg") && !$this->isCreditCardSelectorEnabled() && $useAPIImage) { 296 $url = $iconFactory->getExternalIconHtml($this->apiPaymentMethod["image"]->svg); 297 } 298 $alt = $this->getIdFromConfig() . ' icon'; 299 $icon = new Icon($this->getIdFromConfig(), $url, $alt); 300 return new StaticIconProvider($icon); 301 } 302 public function gatewayIconsRenderer(ContainerInterface $container): \Mollie\Inpsyde\PaymentGateway\GatewayIconsRendererInterface 303 { 304 return new GatewayIconsRenderer($this, $this->paymentMethodIconProvider($container)); 305 } 306 public function paymentFieldsRenderer(ContainerInterface $container): PaymentFieldsRendererInterface 307 { 308 $oldGatewayInstances = $container->get('__deprecated.gateway_helpers'); 309 //not all payment methods have a gateway 310 if (!isset($oldGatewayInstances[$this->id()])) { 311 return new NoopPaymentFieldsRenderer(); 312 } 313 $gatewayDescription = $container->get('payment_gateway.' . $this->id() . '.description'); 314 $dataHelper = $container->get('settings.data_helper'); 315 $deprecatedGatewayHelper = $oldGatewayInstances[$this->id()]; 316 if (!$this->getProperty('paymentFields')) { 317 return new DefaultFieldsStrategy($deprecatedGatewayHelper, $gatewayDescription, $dataHelper); 318 } else { 319 $className = 'Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\\' . ucfirst($this->getIdFromConfig()) . 'FieldsStrategy'; 320 return class_exists($className) ? new $className($deprecatedGatewayHelper, $gatewayDescription, $dataHelper) : new DefaultFieldsStrategy($deprecatedGatewayHelper, $gatewayDescription, $dataHelper); 321 } 322 } 323 public function hasFields(ContainerInterface $container): bool 324 { 325 $hasFields = $this->hasPaymentFields(); 326 if ($hasFields) { 327 return \true; 328 } 329 /* Override show issuers dropdown? */ 330 $dropdownEnabled = $this->getProperty('issuers_dropdown_shown') === 'yes'; 331 if ($dropdownEnabled) { 332 return \true; 333 } 334 return \false; 335 } 336 public function formFields(ContainerInterface $container): array 337 { 338 $defaultTitle = $this->getApiTitle($container); 339 $settingsHelper = $container->get('settings.settings_helper'); 340 $generalFormFields = $settingsHelper->generalFormFields($defaultTitle, $this->config['defaultDescription'], $this->config['confirmationDelayed']); 341 return $this->getFormFields($generalFormFields); 342 } 343 public function optionKey(ContainerInterface $container): string 344 { 345 return $this->id() . '_settings'; 346 } 347 public function registerBlocks(ContainerInterface $container): bool 348 { 349 //we handle it outside for the moment 350 return \false; 351 } 352 public function orderButtonText(ContainerInterface $container): string 353 { 354 return ''; 355 } 356 public function customSettings(): CustomSettingsFieldsDefinition 357 { 358 return new CustomSettingsFields(['multi_select_countries' => function () { 359 return new MultiCountrySettingsField($this); 360 }], []); 361 } 362 public function icon(ContainerInterface $container): string 363 { 364 return ''; 365 } 312 366 } -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Alma.php
r3226701 r3262577 8 8 protected function getConfig(): array 9 9 { 10 return ['id' => 'alma', 'defaultTitle' => 'Alma', 'settingsDescription' => '', 'defaultDescription' => '', 'paymentFields' => \false, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \false, 'confirmationDelayed' => \false, 'SEPA' => \false, 'paymentAPIfields' => [' billingAddress', 'shippingAddress'], 'docs' => 'https://www.mollie.com/gb/payments/alma'];10 return ['id' => 'alma', 'defaultTitle' => 'Alma', 'settingsDescription' => '', 'defaultDescription' => '', 'paymentFields' => \false, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \false, 'confirmationDelayed' => \false, 'SEPA' => \false, 'paymentAPIfields' => ['AddressMiddleware'], 'docs' => 'https://www.mollie.com/gb/payments/alma']; 11 11 } 12 12 // Replace translatable strings after the 'after_setup_theme' hook -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Applepay.php
r3226701 r3262577 24 24 $checkout_page_id = wc_get_page_id('checkout'); 25 25 $edit_checkout_page_link = get_edit_post_link($checkout_page_id); 26 $notice = ['notice' => ['title' => sprintf( 27 /* translators: Placeholder 1: link url */ 28 __('<p>The appearance of the Apple Pay button can be controlled in the <a href="%1$s">Checkout page editor</a>.</p>', 'mollie-payments-for-woocommerce'), 29 esc_url($edit_checkout_page_link) 30 ), 'type' => 'title', 'class' => 'notice notice-warning', 'css' => 'padding:20px;']]; 26 if ($edit_checkout_page_link) { 27 $notice = ['notice' => ['title' => sprintf( 28 /* translators: Placeholder 1: link url */ 29 __('<p>The appearance of the Apple Pay button can be controlled in the <a href="%1$s">Checkout page editor</a>.</p>', 'mollie-payments-for-woocommerce'), 30 esc_url($edit_checkout_page_link) 31 ), 'type' => 'title', 'class' => 'notice notice-warning', 'css' => 'padding:20px;']]; 32 } else { 33 $notice = []; 34 } 31 35 $paymentMethodFormFieds = ['mollie_apple_pay_button_enabled_cart' => ['title' => __('Enable Apple Pay Button on Cart page', 'mollie-payments-for-woocommerce'), 'desc' => __('Enable the Apple Pay direct buy button on the Cart page', 'mollie-payments-for-woocommerce'), 'type' => 'checkbox', 'default' => 'no'], 'mollie_apple_pay_button_enabled_product' => ['title' => __('Enable Apple Pay Button on Product page', 'mollie-payments-for-woocommerce'), 'desc' => __('Enable the Apple Pay direct buy button on the Product page', 'mollie-payments-for-woocommerce'), 'type' => 'checkbox', 'default' => 'no'], 'mollie_apple_pay_button_enabled_express_checkout' => ['title' => __('Enable Apple Pay Express Button on Checkout page', 'mollie-payments-for-woocommerce'), 'desc' => __('Enable the Apple Pay direct buy button on the Express Buttons section of the Checkout page', 'mollie-payments-for-woocommerce'), 'type' => 'checkbox', 'default' => 'no']]; 32 36 return array_merge($notice, $generalFormFields, $paymentMethodFormFieds); -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Billie.php
r3226701 r3262577 18 18 protected function getConfig(): array 19 19 { 20 return ['id' => 'billie', 'defaultTitle' => 'Billie', 'settingsDescription' => 'To accept payments via Billie, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \true, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \true, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => \true, 'errorMessage' => 'Company field is empty. The company field is required.', 'companyPlaceholder' => 'Please enter your company name here.', 'docs' => 'https://www.mollie.com/gb/payments/billie'];20 return ['id' => 'billie', 'defaultTitle' => 'Billie', 'settingsDescription' => 'To accept payments via Billie, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \true, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \true, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => !apply_filters('inpsyde.feature-flags.mollie-woocommerce.billie_payments_api', \true), 'paymentCaptureMode' => 'manual', 'errorMessage' => 'Company field is empty. The company field is required.', 'companyPlaceholder' => 'Please enter your company name here.', 'docs' => 'https://www.mollie.com/gb/payments/billie']; 21 21 } 22 22 // Replace translatable strings after the 'after_setup_theme' hook -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Klarna.php
r3226701 r3262577 8 8 protected function getConfig(): array 9 9 { 10 return ['id' => 'klarna', 'defaultTitle' => 'Pay with Klarna', 'settingsDescription' => 'To accept payments via Klarna, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \false, 'instructions' => \false, 'supports' => ['products', 'refunds'], ' filtersOnBuild' => \false, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => \true, 'docs' => 'https://www.mollie.com/gb/payments/klarna'];10 return ['id' => 'klarna', 'defaultTitle' => 'Pay with Klarna', 'settingsDescription' => 'To accept payments via Klarna, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \false, 'instructions' => \false, 'supports' => ['products', 'refunds'], 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => !apply_filters('inpsyde.feature-flags.mollie-woocommerce.klarna_payments_api', \true), 'paymentCaptureMode' => 'manual', 'docs' => 'https://www.mollie.com/gb/payments/klarna']; 11 11 } 12 12 public function initializeTranslations(): void -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/BancomatpayFieldsStrategy.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies; 5 5 6 class BancomatpayFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI 6 use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface; 7 class BancomatpayFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface 7 8 { 8 9 const FIELD_PHONE = "billing_phone_bancomatpay"; 9 public function execute($gateway, $dataHelper)10 public function renderFields(): string 10 11 { 11 12 $showPhoneField = \false; … … 21 22 } 22 23 if ($showPhoneField) { 23 $this->phoneNumber($phoneValue);24 return $this->gatewayDescription . $this->phoneNumber($phoneValue); 24 25 } 26 return $this->gatewayDescription; 25 27 } 26 28 protected function getOrderIdOnPayForOrderPage() … … 33 35 { 34 36 $phoneValue = $phoneValue ?: ''; 35 ?> 36 <p class="form-row form-row-wide" id="billing_phone_field"> 37 <label for="<?php 38 echo esc_attr(self::FIELD_PHONE); 39 ?>" class=""><?php 40 echo esc_html__('Phone', 'mollie-payments-for-woocommerce'); 41 ?> 42 <abbr class="required" title="required">*</abbr> 43 </label> 44 <span class="woocommerce-input-wrapper"> 45 <input type="tel" class="input-text " name="<?php 46 echo esc_attr(self::FIELD_PHONE); 47 ?>" id="<?php 48 echo esc_attr(self::FIELD_PHONE); 49 ?>" 50 placeholder="+39xxxxxxxxx" 51 value="<?php 52 echo esc_attr($phoneValue); 53 ?>" autocomplete="phone"> 54 </span> 55 </p> 56 <?php 37 return ' 38 <p class="form-row form-row-wide" id="billing_phone_field"> 39 <label for="' . esc_attr(self::FIELD_PHONE) . '" class="">' . esc_html__('Phone', 'mollie-payments-for-woocommerce') . ' 40 <abbr class="required" title="required">*</abbr> 41 </label> 42 <span class="woocommerce-input-wrapper"> 43 <input type="tel" class="input-text" name="' . esc_attr(self::FIELD_PHONE) . '" id="' . esc_attr(self::FIELD_PHONE) . '" 44 placeholder="+39xxxxxxxxx" 45 value="' . esc_attr($phoneValue) . '" autocomplete="phone"> 46 </span> 47 </p>'; 57 48 } 58 49 public function getFieldMarkup($gateway, $dataHelper) -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/BillieFieldsStrategy.php
r3226701 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies; 5 5 6 class BillieFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI 6 use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface; 7 class BillieFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface 7 8 { 8 9 public const FIELD_COMPANY = 'billing_company_billie'; 9 public function execute($gateway, $dataHelper)10 public function renderFields(): string 10 11 { 11 12 $showCompanyField = \false; … … 20 21 } 21 22 if ($showCompanyField) { 22 $this->company();23 return $this->gatewayDescription . $this->company(); 23 24 } 25 return $this->gatewayDescription; 24 26 } 25 27 protected function getOrderIdOnPayForOrderPage() … … 31 33 protected function company() 32 34 { 33 ?> 34 <p class="form-row form-row-wide" id="billing_company_field"> 35 <label for="<?php 36 echo esc_attr(self::FIELD_COMPANY); 37 ?>" class=""><?php 38 echo esc_html__('Company', 'mollie-payments-for-woocommerce'); 39 ?> 40 <abbr class="required" title="required">*</abbr> 41 </label> 42 <span class="woocommerce-input-wrapper"> 43 <input type="tel" class="input-text " name="<?php 44 echo esc_attr(self::FIELD_COMPANY); 45 ?>" id="<?php 46 echo esc_attr(self::FIELD_COMPANY); 47 ?>" 48 placeholder="Company name" 49 value="" autocomplete="organization"> 35 return ' 36 <p class="form-row form-row-wide" id="billing_company_field"> 37 <label for="' . esc_attr(self::FIELD_COMPANY) . '" class="">' . esc_html__('Company', 'mollie-payments-for-woocommerce') . ' 38 <abbr class="required" title="required">*</abbr> 39 </label> 40 <span class="woocommerce-input-wrapper"> 41 <input type="tel" class="input-text" name="' . esc_attr(self::FIELD_COMPANY) . '" id="' . esc_attr(self::FIELD_COMPANY) . '" 42 placeholder="Company name" 43 value="" autocomplete="organization"> 50 44 </span> 51 </p> 52 <?php 45 </p>'; 53 46 } 54 47 public function getFieldMarkup($gateway, $dataHelper) 55 48 { 56 return "";49 return ''; 57 50 } 58 51 /** -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/CreditcardFieldsStrategy.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies; 5 5 6 use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface; 6 7 use Mollie\WooCommerce\PaymentMethods\PaymentMethodI; 7 class CreditcardFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI8 class CreditcardFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface 8 9 { 9 public function execute($gateway, $dataHelper)10 public function renderFields(): string 10 11 { 11 if (!$this->isMollieComponentsEnabled($ gateway->paymentMethod())) {12 return ;12 if (!$this->isMollieComponentsEnabled($this->deprecatedHelperGateway->paymentMethod())) { 13 return $this->gatewayDescription; 13 14 } 14 $gateway->has_fields = \true;15 15 $allowedHtml = $this->svgAllowedHtml(); 16 ?> 17 <div class="mollie-components"></div> 18 <p class="mollie-components-description"> 19 <?php 20 printf( 21 /* translators: Placeholder 1: Lock icon. Placeholder 2: Mollie logo. */ 22 esc_html(__('%1$s Secure payments provided by %2$s', 'mollie-payments-for-woocommerce')), 23 wp_kses($this->lockIcon($dataHelper), $allowedHtml), 24 wp_kses($this->mollieLogo($dataHelper), $allowedHtml) 25 ); 26 ?> 27 </p> 28 <?php 16 $output = $this->gatewayDescription; 17 $output .= '<div class="mollie-components"></div>'; 18 $output .= '<p class="mollie-components-description">'; 19 $output .= sprintf(esc_html__('%1$s Secure payments provided by %2$s', 'mollie-payments-for-woocommerce'), wp_kses($this->lockIcon($this->dataHelper), $allowedHtml), wp_kses($this->mollieLogo($this->dataHelper), $allowedHtml)); 20 $output .= '</p>'; 21 return $output; 29 22 } 30 23 public function getFieldMarkup($gateway, $dataHelper) … … 40 33 protected function isMollieComponentsEnabled(PaymentMethodI $paymentMethod): bool 41 34 { 42 return $paymentMethod->hasPaymentFields(); 35 $hasComponentsEnabled = $paymentMethod->getProperty('mollie_components_enabled'); 36 return $hasComponentsEnabled === 'yes'; 43 37 } 44 38 protected function lockIcon($dataHelper) -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/DefaultFieldsStrategy.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies; 5 5 6 class DefaultFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI 6 use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface; 7 class DefaultFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface 7 8 { 8 public function execute($gateway, $dataHelper)9 public function renderFields(): string 9 10 { 11 return $this->gatewayDescription; 10 12 } 11 13 public function getFieldMarkup($gateway, $dataHelper) 12 14 { 15 return ''; 13 16 } 14 17 } -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/GiftcardFieldsStrategy.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies; 5 5 6 class GiftcardFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI 6 use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface; 7 class GiftcardFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface 7 8 { 8 9 use \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\IssuersDropdownBehavior; 9 public function execute($gateway, $dataHelper)10 public function renderFields(): string 10 11 { 11 if (!$this->dropDownEnabled($ gateway)) {12 return ;12 if (!$this->dropDownEnabled($this->deprecatedHelperGateway)) { 13 return $this->gatewayDescription; 13 14 } 14 $issuers = $this->getIssuers($ gateway, $dataHelper);15 $issuers = $this->getIssuers($this->deprecatedHelperGateway, $this->dataHelper); 15 16 if (empty($issuers)) { 16 return ;17 return $this->gatewayDescription; 17 18 } 18 $selectedIssuer = $ gateway->getSelectedIssuer();19 $selectedIssuer = $this->getSelectedIssuer($this->deprecatedHelperGateway); 19 20 $html = ''; 20 21 // If only one gift card issuers is available, show it without a dropdown … … 28 29 } 29 30 //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 30 echo wpautop(wptexturize($html)); 31 return; 31 return $this->gatewayDescription . wpautop(wptexturize($html)); 32 32 } 33 $this->renderIssuers($gateway, $issuers, $selectedIssuer);33 return $this->gatewayDescription . $this->renderIssuers($this->deprecatedHelperGateway, $issuers, $selectedIssuer); 34 34 } 35 35 public function getFieldMarkup($gateway, $dataHelper) … … 39 39 } 40 40 $issuers = $this->getIssuers($gateway, $dataHelper); 41 $selectedIssuer = $ gateway->getSelectedIssuer();41 $selectedIssuer = $this->getSelectedIssuer($gateway); 42 42 $markup = $this->dropdownOptions($gateway, $issuers, $selectedIssuer); 43 43 return $markup; -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/In3FieldsStrategy.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies; 5 5 6 class In3FieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI 6 use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface; 7 class In3FieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface 7 8 { 8 9 use \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategiesTrait; 9 10 const FIELD_BIRTHDATE = "billing_birthdate_in3"; 10 11 const FIELD_PHONE = "billing_phone_in3"; 11 public function execute($gateway, $dataHelper)12 public function renderFields(): string 12 13 { 13 14 $showBirthdateField = \false; … … 16 17 $phoneValue = \false; 17 18 $birthValue = \false; 19 $html = $this->gatewayDescription; 18 20 if (is_checkout_pay_page()) { 19 21 $showBirthdateField = \true; … … 30 32 } 31 33 if ($showPhoneField) { 32 $ this->phoneNumber($phoneValue);34 $html .= $this->phoneNumber($phoneValue); 33 35 } 34 36 if ($showBirthdateField) { 35 $ this->dateOfBirth($birthValue);37 $html .= $this->dateOfBirth($birthValue); 36 38 } 39 return $html; 37 40 } 38 41 protected function phoneNumber($phoneValue) 39 42 { 40 43 $phoneValue = $phoneValue ?: ''; 41 ?> 42 <p class="form-row form-row-wide" id="billing_phone_field"> 43 <label for="<?php 44 echo esc_attr(self::FIELD_PHONE); 45 ?>" class=""><?php 46 echo esc_html__('Phone', 'mollie-payments-for-woocommerce'); 47 ?> 48 </label> 49 <span class="woocommerce-input-wrapper"> 50 <input type="tel" class="input-text " name="<?php 51 echo esc_attr(self::FIELD_PHONE); 52 ?>" id="<?php 53 echo esc_attr(self::FIELD_PHONE); 54 ?>" 55 placeholder="+316xxxxxxxx" 56 value="<?php 57 echo esc_attr($phoneValue); 58 ?>" autocomplete="phone"> 59 </span> 60 </p> 61 <?php 44 $html = '<p class="form-row form-row-wide" id="billing_phone_field">'; 45 $html .= '<label for="' . esc_attr(self::FIELD_PHONE) . '" class="">' . esc_html__('Phone', 'mollie-payments-for-woocommerce') . '</label>'; 46 $html .= '<span class="woocommerce-input-wrapper">'; 47 $html .= '<input type="tel" class="input-text " name="' . esc_attr(self::FIELD_PHONE) . '" id="' . esc_attr(self::FIELD_PHONE) . '" placeholder="+316xxxxxxxx" value="' . esc_attr($phoneValue) . '" autocomplete="phone">'; 48 $html .= '</span></p>'; 49 return $html; 62 50 } 63 51 public function getFieldMarkup($gateway, $dataHelper) -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/IssuersDropdownBehavior.php
r3164004 r3262577 21 21 return $dataHelper->getMethodIssuers($apiKey, $testMode, $gateway->paymentMethod()->getProperty('id')); 22 22 } 23 /** 24 * @return string|NULL 25 */ 26 public function getSelectedIssuer($gateway): ?string 27 { 28 $issuer_id = 'mollie-payments-for-woocommerce' . '_issuer_' . $gateway->paymentMethod()->getIdFromConfig(); 29 //phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 30 $postedIssuer = wc_clean(wp_unslash($_POST[$issuer_id] ?? '')); 31 return !empty($postedIssuer) ? $postedIssuer : null; 32 } 23 33 public function renderIssuers($gateway, $issuers, $selectedIssuer) 24 34 { 25 35 $html = $this->issuersDropdownMarkup($gateway, $issuers, $selectedIssuer); 26 echowp_kses($html, ['select' => ['name' => [], 'id' => [], 'class' => []], 'option' => ['value' => [], 'selected' => []]]);36 return wp_kses($html, ['select' => ['name' => [], 'id' => [], 'class' => []], 'option' => ['value' => [], 'selected' => []]]); 27 37 } 28 38 /** -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/KbcFieldsStrategy.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies; 5 5 6 class KbcFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI 6 use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface; 7 class KbcFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface 7 8 { 8 9 use \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\IssuersDropdownBehavior; 9 public function execute($gateway, $dataHelper)10 public function renderFields(): string 10 11 { 11 if (!$this->dropDownEnabled($ gateway)) {12 return ;12 if (!$this->dropDownEnabled($this->deprecatedHelperGateway)) { 13 return $this->gatewayDescription; 13 14 } 14 $issuers = $this->getIssuers($ gateway, $dataHelper);15 $selectedIssuer = $ gateway->getSelectedIssuer();16 $this->renderIssuers($gateway, $issuers, $selectedIssuer);15 $issuers = $this->getIssuers($this->deprecatedHelperGateway, $this->dataHelper); 16 $selectedIssuer = $this->getSelectedIssuer($this->deprecatedHelperGateway); 17 return $this->gatewayDescription . $this->renderIssuers($this->deprecatedHelperGateway, $issuers, $selectedIssuer); 17 18 } 18 19 public function getFieldMarkup($gateway, $dataHelper) 19 20 { 20 21 if (!$this->dropDownEnabled($gateway)) { 21 return "";22 return ''; 22 23 } 23 24 $issuers = $this->getIssuers($gateway, $dataHelper); 24 $selectedIssuer = $ gateway->getSelectedIssuer();25 $selectedIssuer = $this->getSelectedIssuer($gateway); 25 26 $markup = $this->dropdownOptions($gateway, $issuers, $selectedIssuer); 26 27 return $markup; -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategiesTrait.php
r3164004 r3262577 14 14 { 15 15 $birthValue = $birthValue ?: ''; 16 ?> 17 <p class="form-row form-row-wide" id="billing_birthdate_field"> 18 <label for="<?php 19 echo esc_attr(self::FIELD_BIRTHDATE); 20 ?>" class=""><?php 21 echo esc_html__('Birthdate', 'mollie-payments-for-woocommerce'); 22 ?> 23 </label> 24 <span class="woocommerce-input-wrapper"> 25 <input type="date" class="input-text " name="<?php 26 echo esc_attr(self::FIELD_BIRTHDATE); 27 ?>" 28 id="<?php 29 echo esc_attr(self::FIELD_BIRTHDATE); 30 ?>" value="<?php 31 echo esc_attr($birthValue); 32 ?>" 33 autocomplete="birthdate"></span> 34 </p> 35 <?php 16 $html = '<p class="form-row form-row-wide" id="billing_birthdate_field">'; 17 $html .= '<label for="' . esc_attr(self::FIELD_BIRTHDATE) . '" class="">' . esc_html__('Birthdate', 'mollie-payments-for-woocommerce') . '</label>'; 18 $html .= '<span class="woocommerce-input-wrapper">'; 19 $html .= '<input type="date" class="input-text " name="' . esc_attr(self::FIELD_BIRTHDATE) . '" id="' . esc_attr(self::FIELD_BIRTHDATE) . '" value="' . esc_attr($birthValue) . '" autocomplete="birthdate">'; 20 $html .= '</span></p>'; 21 return $html; 36 22 } 37 23 } -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategyI.php
r3164004 r3262577 6 6 interface PaymentFieldsStrategyI 7 7 { 8 public function execute($ gateway, $dataHelper);8 public function execute($deprecatedHelperDeprecatedHelperGateway, $gatewayDescription, $dataHelper): string; 9 9 } -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentFieldsStrategies/RivertyFieldsStrategy.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies; 5 5 6 class RivertyFieldsStrategy implements \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategyI 6 use Mollie\Inpsyde\PaymentGateway\PaymentFieldsRendererInterface; 7 class RivertyFieldsStrategy extends \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\AbstractPaymentFieldsRenderer implements PaymentFieldsRendererInterface 7 8 { 8 9 use \Mollie\WooCommerce\PaymentMethods\PaymentFieldsStrategies\PaymentFieldsStrategiesTrait; 9 10 const FIELD_BIRTHDATE = "billing_birthdate_riverty"; 10 11 const FIELD_PHONE = "billing_phone_riverty"; 11 public function execute($gateway, $dataHelper)12 public function renderFields(): string 12 13 { 13 14 $showBirthdateField = \false; … … 16 17 $phoneValue = \false; 17 18 $birthValue = \false; 19 $html = $this->gatewayDescription; 18 20 if (is_checkout_pay_page()) { 19 21 $showBirthdateField = \true; … … 30 32 } 31 33 if ($showPhoneField) { 32 $ this->phoneNumber($phoneValue);34 $html .= $this->phoneNumber($phoneValue); 33 35 } 34 36 if ($showBirthdateField) { 35 $ this->dateOfBirth($birthValue);37 $html .= $this->dateOfBirth($birthValue); 36 38 } 39 return $html; 37 40 } 38 41 protected function phoneNumber($phoneValue) … … 42 45 $countryCodes = ['BE' => '+32xxxxxxxxx', 'NL' => '+316xxxxxxxx', 'DE' => '+49xxxxxxxxx', 'AT' => '+43xxxxxxxxx']; 43 46 $placeholder = in_array($country, array_keys($countryCodes)) ? $countryCodes[$country] : $countryCodes['NL']; 44 ?> 45 <p class="form-row form-row-wide" id="billing_phone_field"> 46 <label for="<?php 47 echo esc_attr(self::FIELD_PHONE); 48 ?>" class=""><?php 49 echo esc_html__('Phone', 'mollie-payments-for-woocommerce'); 50 ?> 51 </label> 52 <span class="woocommerce-input-wrapper"> 53 <input type="tel" class="input-text " name="<?php 54 echo esc_attr(self::FIELD_PHONE); 55 ?>" id="<?php 56 echo esc_attr(self::FIELD_PHONE); 57 ?>" 58 placeholder="<?php 59 echo esc_attr($placeholder); 60 ?>" 61 value="<?php 62 echo esc_attr($phoneValue); 63 ?>" autocomplete="phone"> 64 </span> 65 </p> 66 <?php 47 $html = '<p class="form-row form-row-wide" id="billing_phone_field">'; 48 $html .= '<label for="' . esc_attr(self::FIELD_PHONE) . '" class="">' . esc_html__('Phone', 'mollie-payments-for-woocommerce') . '</label>'; 49 $html .= '<span class="woocommerce-input-wrapper">'; 50 $html .= '<input type="tel" class="input-text " name="' . esc_attr(self::FIELD_PHONE) . '" id="' . esc_attr(self::FIELD_PHONE) . '" placeholder="' . esc_attr($placeholder) . '" value="' . esc_attr($phoneValue) . '" autocomplete="phone">'; 51 $html .= '</span></p>'; 52 return $html; 67 53 } 68 54 public function getFieldMarkup($gateway, $dataHelper) -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentMethodI.php
r3164004 r3262577 4 4 namespace Mollie\WooCommerce\PaymentMethods; 5 5 6 use Mollie\ WooCommerce\Payment\PaymentFieldsService;6 use Mollie\Psr\Container\ContainerInterface; 7 7 interface PaymentMethodI 8 8 { 9 9 public function getProperty(string $propertyName); 10 10 public function hasProperty(string $propertyName): bool; 11 public function title(): string;12 public function hasPaymentFields(): bool;13 public function getProcessedDescriptionForBlock(): string;14 public function paymentFieldsService(): PaymentFieldsService;15 public function hasSurcharge(): bool;16 11 } -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/PaymentMethodsIconUrl.php
r3191126 r3262577 96 96 return \false; 97 97 } 98 if (!isset($gatewaySettings['iconFileUrl']) &&!is_string($gatewaySettings['iconFileUrl'])) {98 if (!isset($gatewaySettings['iconFileUrl']) || !is_string($gatewaySettings['iconFileUrl'])) { 99 99 return \false; 100 100 } -
mollie-payments-for-woocommerce/trunk/src/PaymentMethods/Riverty.php
r3226701 r3262577 9 9 protected function getConfig(): array 10 10 { 11 return ['id' => 'riverty', 'defaultTitle' => 'Riverty', 'settingsDescription' => 'To accept payments via Riverty, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \true, 'additionalFields' => ['birthdate', 'phone'], 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \true, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => \true, 'phonePlaceholder' => 'Please enter your phone here. +316xxxxxxxx', 'mollie-payments-for-woocommerce', 'birthdatePlaceholder' => 'Please enter your birthdate here.', 'mollie-payments-for-woocommerce', 'docs' => 'https://www.mollie.com/gb/payments/riverty'];11 return ['id' => 'riverty', 'defaultTitle' => 'Riverty', 'settingsDescription' => 'To accept payments via Riverty, all default WooCommerce checkout fields should be enabled and required.', 'defaultDescription' => '', 'paymentFields' => \true, 'additionalFields' => ['birthdate', 'phone'], 'instructions' => \false, 'supports' => ['products', 'refunds'], 'filtersOnBuild' => \true, 'confirmationDelayed' => \false, 'SEPA' => \false, 'orderMandatory' => !apply_filters('inpsyde.feature-flags.mollie-woocommerce.riverty_payments_api', \true), 'paymentCaptureMode' => 'manual', 'phonePlaceholder' => 'Please enter your phone here. +316xxxxxxxx', 'mollie-payments-for-woocommerce', 'birthdatePlaceholder' => 'Please enter your birthdate here.', 'mollie-payments-for-woocommerce', 'docs' => 'https://www.mollie.com/gb/payments/riverty']; 12 12 } 13 13 // Replace translatable strings after the 'after_setup_theme' hook -
mollie-payments-for-woocommerce/trunk/src/Settings/General/MollieGeneralSettings.php
r3164004 r3262577 3 3 namespace Mollie\WooCommerce\Settings\General; 4 4 5 use Mollie\WooCommerce\Gateway\MolliePaymentGateway ;5 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler; 6 6 use Mollie\WooCommerce\Gateway\Surcharge; 7 7 use Mollie\WooCommerce\Shared\SharedDataDictionary; … … 26 26 __('Payment method description that the customer will see on your checkout. Default <code>%s</code>', 'mollie-payments-for-woocommerce'), 27 27 $defaultDescription 28 ), 'default' => $defaultDescription, 'desc_tip' => \true], 'sales' => ['id' => $defaultTitle . '_' . 'title', 'title' => __('Sales countries', 'mollie-payments-for-woocommerce'), 'type' => 'title'], 'allowed_countries' => ['title' => __('Sell to specific countries', 'mollie-payments-for-woocommerce'), 'desc' => '', 'css' => 'min-width: 350px;', 'default' => [], 'type' => 'multi_select_countries'], 'surcharge' => ['id' => $defaultTitle . '_' . 'surcharge', 'title' => sprintf( 28 ), 'default' => $defaultDescription, 'desc_tip' => \true], 'sales' => ['id' => $defaultTitle . '_' . 'title', 'title' => __('Sales countries', 'mollie-payments-for-woocommerce'), 'type' => 'title'], 'allowed_countries' => ['title' => __('Sell to specific countries', 'mollie-payments-for-woocommerce'), 'desc' => '', 'css' => 'min-width: 350px;', 'default' => [], 'type' => 'multi_select_countries', 'sanitize_callback' => static function ($value) { 29 return is_array($value) ? array_map('wc_clean', array_map('stripslashes', $value)) : ''; 30 }], 'surcharge' => ['id' => $defaultTitle . '_' . 'surcharge', 'title' => sprintf( 29 31 /* translators: Placeholder 1: Gateway title */ 30 32 __('%s surcharge', 'mollie-payments-for-woocommerce'), -
mollie-payments-for-woocommerce/trunk/src/Settings/MollieSettingsPage.php
r3226701 r3262577 10 10 use Mollie\WooCommerce\Settings\Page\PagePaymentMethods; 11 11 use Mollie\WooCommerce\Shared\Data; 12 use Mollie\Psr\Container\ContainerInterface; 12 13 use WC_Admin_Settings; 13 14 use WC_Settings_Page; … … 21 22 protected bool $isTestModeEnabled; 22 23 protected Data $dataHelper; 23 public function __construct(\Mollie\WooCommerce\Settings\Settings $settings, string $pluginPath, string $pluginUrl, array $mollieGateways, array $paymentMethods, bool $isTestModeEnabled, Data $dataHelper) 24 protected ContainerInterface $container; 25 public function __construct(\Mollie\WooCommerce\Settings\Settings $settings, string $pluginPath, string $pluginUrl, array $mollieGateways, array $paymentMethods, bool $isTestModeEnabled, Data $dataHelper, ContainerInterface $container) 24 26 { 25 27 $this->id = 'mollie_settings'; … … 32 34 $this->dataHelper = $dataHelper; 33 35 $this->paymentMethods = $paymentMethods; 36 $this->container = $container; 34 37 $this->registerContentFieldType(); 35 38 $this->outputSections(); … … 105 108 foreach ($this->pages() as $pageClass) { 106 109 /** @var AbstractPage $page */ 107 $page = new $pageClass($this->settings, $this->pluginUrl, $this->pages(), $defaultSection, $connectionStatus, $this->isTestModeEnabled, $this->mollieGateways, $this->paymentMethods, $this->dataHelper );110 $page = new $pageClass($this->settings, $this->pluginUrl, $this->pages(), $defaultSection, $connectionStatus, $this->isTestModeEnabled, $this->mollieGateways, $this->paymentMethods, $this->dataHelper, $this->container); 108 111 if ($page::slug() === $defaultSection) { 109 112 $mollieSettings = $this->hideKeysIntoStars($page->settings()); -
mollie-payments-for-woocommerce/trunk/src/Settings/Page/AbstractPage.php
r3191126 r3262577 7 7 use Mollie\WooCommerce\Settings\Settings; 8 8 use Mollie\WooCommerce\Shared\Data; 9 use Mollie\Psr\Container\ContainerInterface; 9 10 abstract class AbstractPage 10 11 { … … 18 19 protected array $paymentMethods; 19 20 protected Data $dataHelper; 20 public function __construct(Settings $settings, string $pluginUrl, array $pages, string $currentSection, bool $connectionStatus, bool $testModeEnabled, array $mollieGateways, array $paymentMethods, Data $dataHelper) 21 protected ContainerInterface $container; 22 public function __construct(Settings $settings, string $pluginUrl, array $pages, string $currentSection, bool $connectionStatus, bool $testModeEnabled, array $mollieGateways, array $paymentMethods, Data $dataHelper, ContainerInterface $container) 21 23 { 22 24 $this->settings = $settings; … … 29 31 $this->paymentMethods = $paymentMethods; 30 32 $this->dataHelper = $dataHelper; 33 $this->container = $container; 31 34 } 32 35 abstract public static function isTab(): bool; … … 46 49 foreach ($this->sections() as $sectionClass) { 47 50 /** @var AbstractSection $section */ 48 $section = new $sectionClass($this->settings, $this->pluginUrl, $this->pages, $this->currentSection, $this->connectionStatus, $this->testModeEnabled, $this->mollieGateways, $this->paymentMethods, $this->dataHelper );51 $section = new $sectionClass($this->settings, $this->pluginUrl, $this->pages, $this->currentSection, $this->connectionStatus, $this->testModeEnabled, $this->mollieGateways, $this->paymentMethods, $this->dataHelper, $this->container); 49 52 foreach ($section->config() as $field) { 50 53 $settings[] = $field; -
mollie-payments-for-woocommerce/trunk/src/Settings/Page/Section/AbstractSection.php
r3191126 r3262577 6 6 use Mollie\WooCommerce\Settings\Settings; 7 7 use Mollie\WooCommerce\Shared\Data; 8 use Mollie\Psr\Container\ContainerInterface; 8 9 abstract class AbstractSection 9 10 { … … 17 18 protected array $paymentMethods; 18 19 protected Data $dataHelper; 19 public function __construct(Settings $settings, string $pluginUrl, array $pages, string $currentSection, bool $connectionStatus, bool $testModeEnabled, array $mollieGateways, array $paymentMethods, Data $dataHelper) 20 protected ContainerInterface $container; 21 public function __construct(Settings $settings, string $pluginUrl, array $pages, string $currentSection, bool $connectionStatus, bool $testModeEnabled, array $mollieGateways, array $paymentMethods, Data $dataHelper, ContainerInterface $container) 20 22 { 21 23 $this->settings = $settings; … … 28 30 $this->paymentMethods = $paymentMethods; 29 31 $this->dataHelper = $dataHelper; 32 $this->container = $container; 30 33 } 31 34 abstract public function config(): array; -
mollie-payments-for-woocommerce/trunk/src/Settings/Page/Section/Advanced.php
r3191126 r3262577 5 5 6 6 use Mollie\WooCommerce\Shared\SharedDataDictionary; 7 use Mollie\WooCommerce\Payment\Payment Service;7 use Mollie\WooCommerce\Payment\PaymentProcessor; 8 8 class Advanced extends \Mollie\WooCommerce\Settings\Page\Section\AbstractSection 9 9 { … … 21 21 strtolower(__('Enabled', 'mollie-payments-for-woocommerce')), 22 22 __('Single Click Payments', 'mollie-payments-for-woocommerce') 23 ), 'type' => 'checkbox', 'default' => 'yes'], ['id' => $this->settings->getSettingId('api_switch'), 'title' => __('Select API Method', 'mollie-payments-for-woocommerce'), 'type' => 'select', 'options' => [Payment Service::PAYMENT_METHOD_TYPE_ORDER => ucfirst(PaymentService::PAYMENT_METHOD_TYPE_ORDER) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', PaymentService::PAYMENT_METHOD_TYPE_PAYMENT => ucfirst(PaymentService::PAYMENT_METHOD_TYPE_PAYMENT)], 'default' => PaymentService::PAYMENT_METHOD_TYPE_ORDER, 'desc' => sprintf(23 ), 'type' => 'checkbox', 'default' => 'yes'], ['id' => $this->settings->getSettingId('api_switch'), 'title' => __('Select API Method', 'mollie-payments-for-woocommerce'), 'type' => 'select', 'options' => [PaymentProcessor::PAYMENT_METHOD_TYPE_ORDER => ucfirst(PaymentProcessor::PAYMENT_METHOD_TYPE_ORDER) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')', PaymentProcessor::PAYMENT_METHOD_TYPE_PAYMENT => ucfirst(PaymentProcessor::PAYMENT_METHOD_TYPE_PAYMENT)], 'default' => PaymentProcessor::PAYMENT_METHOD_TYPE_ORDER, 'desc' => sprintf( 24 24 /* translators: Placeholder 1: opening link tag, placeholder 2: closing link tag */ 25 25 __('Click %1$shere%2$s to read more about the differences between the Payments and Orders API', 'mollie-payments-for-woocommerce'), -
mollie-payments-for-woocommerce/trunk/src/Settings/Page/Section/Notices.php
r3226701 r3262577 4 4 namespace Mollie\WooCommerce\Settings\Page\Section; 5 5 6 use Mollie\WooCommerce\PaymentMethods\AbstractPaymentMethod; 6 7 use Mollie\WooCommerce\PaymentMethods\Constants; 7 8 use WC_Gateway_BACS; … … 39 40 protected function warnDirectDebitStatus(): string 40 41 { 42 if (!$this->paymentMethods["directdebit"] instanceof AbstractPaymentMethod) { 43 return ''; 44 } 41 45 $hasCustomSepaSettings = $this->paymentMethods["directdebit"]->getProperty('enabled') !== \false; 42 46 $isSepaEnabled = !$hasCustomSepaSettings || $this->paymentMethods["directdebit"]->getProperty('enabled') === 'yes'; -
mollie-payments-for-woocommerce/trunk/src/Settings/Page/Section/PaymentMethods.php
r3242448 r3262577 182 182 $button = '<a class="button-secondary" href="https://my.mollie.com/dashboard/settings/profiles?utm_source=woocommerce&utm_medium=plugin&utm_campaign=partner" target="_blank">' . esc_html(__('Activate Payment Method', 'mollie-payments-for-woocommerce')) . '</a>'; 183 183 } 184 $iconProvider = $paymentMethod->paymentMethodIconProvider($this->container); 185 $icon = $iconProvider->provideIcons()[0]; 184 186 ob_start(); 185 187 ?> 186 188 <div class="mollie-settings-pm__single"> 187 189 <?php 188 echo $ paymentMethod->getIconUrl();190 echo $icon->src(); 189 191 // phpcs:ignore XSS ok. 190 192 ?> 191 193 <?php 192 echo esc_html($paymentMethod->title( ));194 echo esc_html($paymentMethod->title($this->container)); 193 195 ?> 194 196 <?php -
mollie-payments-for-woocommerce/trunk/src/Settings/Settings.php
r3191126 r3262577 7 7 use DateTime; 8 8 use Mollie\Api\Exceptions\ApiException; 9 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler; 9 10 use Mollie\WooCommerce\Gateway\Surcharge; 10 11 use Mollie\WooCommerce\Notice\AdminNotice; 11 use Mollie\WooCommerce\Payment\Payment Service;12 use Mollie\WooCommerce\Payment\PaymentProcessor; 12 13 use Mollie\WooCommerce\Settings\General\MollieGeneralSettings; 13 14 use Mollie\WooCommerce\Shared\SharedDataDictionary; … … 48 49 return $generalSettings->gatewayFormFields($defaultTitle, $defaultDescription, $paymentConfirmation); 49 50 } 50 public function processSettings( WC_Payment_Gateway $gateway)51 public function processSettings(string $gatewayId) 51 52 { 52 53 $nonce = filter_input(\INPUT_POST, '_wpnonce', \FILTER_SANITIZE_SPECIAL_CHARS); … … 56 57 } 57 58 if (isset($_POST['save'])) { 58 $this->processAdminOptionCustomLogo($gateway );59 $this->processAdminOptionSurcharge($gateway );59 $this->processAdminOptionCustomLogo($gatewayId); 60 $this->processAdminOptionSurcharge($gatewayId); 60 61 //only credit cards have a selector 61 if ($gateway ->id === 'mollie_wc_gateway_creditcard') {62 if ($gatewayId === 'mollie_wc_gateway_creditcard') { 62 63 $this->processAdminOptionCreditcardSelector(); 63 64 } 64 65 } 65 66 } 66 public function processAdminOptionCustomLogo( WC_Payment_Gateway $gateway)67 public function processAdminOptionCustomLogo(string $gatewayId) 67 68 { 68 69 $nonce = filter_input(\INPUT_POST, '_wpnonce', \FILTER_SANITIZE_SPECIAL_CHARS); … … 71 72 return; 72 73 } 73 $enabledLogoOptionName = $gateway->id . '_enable_custom_logo';74 $gatewaySettings = get_option(sprintf('%s_settings', $gateway ->id), []);74 $enabledLogoOptionName = 'woocommerce_' . $gatewayId . '_enable_custom_logo'; 75 $gatewaySettings = get_option(sprintf('%s_settings', $gatewayId), []); 75 76 if (!isset($_POST[$enabledLogoOptionName])) { 76 77 $gatewaySettings["iconFileUrl"] = null; 77 78 $gatewaySettings["iconFilePath"] = null; 78 update_option(sprintf('%s_settings', $gateway ->id), $gatewaySettings);79 update_option(sprintf('%s_settings', $gatewayId), $gatewaySettings); 79 80 return; 80 81 } 81 $fileOptionName = $gateway->id . '_upload_logo';82 $fileOptionName = 'woocommerce_' . $gatewayId . '_upload_logo'; 82 83 if (!empty($_FILES[$fileOptionName]['size']) && !empty($_FILES[$fileOptionName]['name']) && is_string($_FILES[$fileOptionName]['name']) && !empty($_FILES[$fileOptionName]['tmp_name']) && is_string($_FILES[$fileOptionName]['tmp_name'])) { 83 84 $name = filter_var(wp_unslash($_FILES[$fileOptionName]['name']), \FILTER_SANITIZE_FULL_SPECIAL_CHARS); … … 87 88 return; 88 89 } 89 $this->processUploadedFile($name, $tempName, $gateway );90 } 91 } 92 public function processAdminOptionSurcharge( WC_Payment_Gateway $gateway)90 $this->processUploadedFile($name, $tempName, $gatewayId); 91 } 92 } 93 public function processAdminOptionSurcharge(string $gatewayId) 93 94 { 94 95 $nonce = filter_input(\INPUT_POST, '_wpnonce', \FILTER_SANITIZE_SPECIAL_CHARS); … … 97 98 return; 98 99 } 99 $paymentSurcharge = $gateway ->id . '_payment_surcharge';100 $paymentSurcharge = $gatewayId . '_payment_surcharge'; 100 101 if (isset($_POST[$paymentSurcharge]) && $_POST[$paymentSurcharge] !== Surcharge::NO_FEE) { 101 102 $surchargeFields = ['_fixed_fee', '_percentage', '_surcharge_limit']; 102 103 foreach ($surchargeFields as $field) { 103 $optionName = $gateway ->id . $field;104 $optionName = $gatewayId . $field; 104 105 $validatedValue = isset($_POST[$optionName]) && $_POST[$optionName] > 0 && $_POST[$optionName] < 999; 105 106 if (!$validatedValue) { … … 109 110 } 110 111 } 111 public function adminOptions(WC_Payment_Gateway $gateway)112 {113 if (!$gateway->enabled && count($gateway->errors)) {114 echo '<div class="inline error"><p><strong>' . esc_html(__('Gateway Disabled', 'mollie-payments-for-woocommerce')) . '</strong>: ' . wp_kses_post(implode('<br/>', $gateway->errors)) . '</p></div>';115 return;116 }117 $html = '';118 foreach ($gateway->get_form_fields() as $k => $v) {119 $type = $gateway->get_field_type($v);120 if ($type === 'multi_select_countries') {121 $html .= $this->multiSelectCountry($gateway);122 } elseif (method_exists($gateway, 'generate_' . $type . '_html')) {123 $html .= $gateway->{'generate_' . $type . '_html'}($k, $v);124 } else {125 $html .= $gateway->generate_text_html($k, $v);126 }127 }128 echo '<h2>' . esc_html($gateway->get_method_title());129 wc_back_link(__('Return to payments', 'mollie-payments-for-woocommerce'), admin_url('admin.php?page=wc-settings&tab=checkout'));130 echo '</h2>';131 echo wp_kses_post(wpautop($gateway->get_method_description()));132 echo '<table class="form-table">' . $html . '</table>';133 }134 public function multiSelectCountry($gateway)135 {136 $selections = (array) $gateway->get_option('allowed_countries', []);137 $gatewayId = $gateway->paymentMethod()->getProperty('id');138 $id = 'mollie_wc_gateway_' . $gatewayId . '_allowed_countries';139 $title = __('Sell to specific countries', 'mollie-payments-for-woocommerce');140 $countries = WC()->countries->countries;141 asort($countries);142 ob_start();143 ?>144 <tr valign="top">145 <th scope="row" class="titledesc">146 <label for="<?php147 echo esc_attr($id);148 ?>"><?php149 echo esc_html($title);150 ?> </label>151 </th>152 <td class="forminp">153 <select multiple="multiple" name="<?php154 echo esc_attr($id);155 ?>[]" style="width:350px"156 data-placeholder="<?php157 esc_attr_e('Choose countries…', 'mollie-payments-for-woocommerce');158 ?>"159 aria-label="<?php160 esc_attr_e('Country', 'mollie-payments-for-woocommerce');161 ?>" class="wc-enhanced-select">162 <?php163 if (!empty($countries)) {164 foreach ($countries as $key => $val) {165 echo '<option value="' . esc_attr($key) . '"' . esc_attr(wc_selected($key, $selections)) . '>' . esc_html($val) . '</option>';166 }167 }168 ?>169 </select><br/><a class="select_all button" href="#"><?php170 esc_html_e('Select all', 'mollie-payments-for-woocommerce');171 ?></a>172 <a class="select_none button" href="#"><?php173 esc_html_e('Select none', 'mollie-payments-for-woocommerce');174 ?></a>175 </td>176 </tr>177 <?php178 return ob_get_clean();179 }180 112 /** 181 113 * @return bool … … 193 125 { 194 126 $orderApiSetting = get_option($this->getSettingId('api_switch')); 195 return !$orderApiSetting || is_string($orderApiSetting) && trim($orderApiSetting) === Payment Service::PAYMENT_METHOD_TYPE_ORDER;127 return !$orderApiSetting || is_string($orderApiSetting) && trim($orderApiSetting) === PaymentProcessor::PAYMENT_METHOD_TYPE_ORDER; 196 128 } 197 129 /** … … 564 496 return \true; 565 497 } 566 protected function processUploadedFile(string $name, string $tempName, WC_Payment_Gateway $gateway)498 protected function processUploadedFile(string $name, string $tempName, string $gatewayId) 567 499 { 568 500 $fileName = preg_replace('#\s+#', '_', $name); … … 572 504 $upload_overrides = ['test_form' => \false]; 573 505 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 574 $file = isset($_FILES[ $gateway->id . '_upload_logo']) ? wp_unslash($_FILES[$gateway->id . '_upload_logo']) : [];506 $file = isset($_FILES['woocommerce_' . $gatewayId . '_upload_logo']) ? wp_unslash($_FILES['woocommerce_' . $gatewayId . '_upload_logo']) : []; 575 507 if (!empty($file)) { 576 508 $file = ['name' => $file['name'], 'type' => $file['type'], 'tmp_name' => $file['tmp_name'], 'error' => $file['error'], 'size' => $file['size']]; 577 509 $movefile = wp_handle_upload($file, $upload_overrides); 578 510 if ($movefile) { 511 $gatewaySettings = get_option(sprintf('%s_settings', $gatewayId), []); 579 512 $gatewaySettings["iconFileUrl"] = $movefile['url']; 580 513 $gatewaySettings["iconFilePath"] = $movefile['file']; 581 update_option(sprintf('%s_settings', $gateway ->id), $gatewaySettings);514 update_option(sprintf('%s_settings', $gatewayId), $gatewaySettings); 582 515 } 583 516 } -
mollie-payments-for-woocommerce/trunk/src/Settings/SettingsModule.php
r3226701 r3262577 119 119 $this->maybeTestModeNotice(); 120 120 }); 121 $gateways = $container->get(' gateway.instances');121 $gateways = $container->get('__deprecated.gateway_helpers'); 122 122 $isSDDGatewayEnabled = $container->get('gateway.isSDDGatewayEnabled'); 123 $this->initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods );123 $this->initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods, $container); 124 124 add_action('woocommerce_admin_settings_sanitize_option', [$this->settingsHelper, 'updateMerchantIdOnApiKeyChanges'], 10, 2); 125 125 add_action('update_option_mollie-payments-for-woocommerce_live_api_key', [$this->settingsHelper, 'updateMerchantIdAfterApiKeyChanges'], 10, 3); … … 189 189 * @param $pluginUrl 190 190 * @param $paymentMethods 191 * @param $container 191 192 * @return void 192 193 */ 193 protected function initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods ): void194 protected function initMollieSettingsPage($isSDDGatewayEnabled, $gateways, $pluginPath, $pluginUrl, $paymentMethods, $container): void 194 195 { 195 196 if (!$isSDDGatewayEnabled) { … … 197 198 unset($gateways['mollie_wc_gateway_directdebit']); 198 199 } 199 add_filter('woocommerce_get_settings_pages', function ($settings) use ($pluginPath, $pluginUrl, $gateways, $paymentMethods ) {200 $settings[] = new \Mollie\WooCommerce\Settings\MollieSettingsPage($this->settingsHelper, $pluginPath, $pluginUrl, $gateways, $paymentMethods, $this->isTestModeEnabled, $this->dataHelper );200 add_filter('woocommerce_get_settings_pages', function ($settings) use ($pluginPath, $pluginUrl, $gateways, $paymentMethods, $container) { 201 $settings[] = new \Mollie\WooCommerce\Settings\MollieSettingsPage($this->settingsHelper, $pluginPath, $pluginUrl, $gateways, $paymentMethods, $this->isTestModeEnabled, $this->dataHelper, $container); 201 202 return $settings; 202 203 }); -
mollie-payments-for-woocommerce/trunk/src/Shared/Data.php
r3191126 r3262577 104 104 $this->settingsHelper->processSettings($gateway); 105 105 } 106 public function processAdminOptions($gateway)107 {108 $this->settingsHelper->adminOptions($gateway);109 }110 106 public function getPaymentLocale() 111 107 { -
mollie-payments-for-woocommerce/trunk/src/Subscription/SubscriptionModule.php
r3164004 r3262577 8 8 use Mollie\Inpsyde\Modularity\Module\ExecutableModule; 9 9 use Mollie\Inpsyde\Modularity\Module\ModuleClassNameIdTrait; 10 use Mollie\WooCommerce\Gateway\MolliePaymentGateway ;10 use Mollie\WooCommerce\Gateway\MolliePaymentGatewayHandler; 11 11 use Mollie\WooCommerce\Settings\Settings; 12 12 use Mollie\WooCommerce\Shared\Data; … … 38 38 $this->settingsHelper = $container->get('settings.settings_helper'); 39 39 assert($this->settingsHelper instanceof Settings); 40 $this->maybeFixSubscriptions();41 40 $this->schedulePendingPaymentOrdersExpirationCheck(); 42 41 return \true; 43 }44 /**45 * See MOL-322, MOL-40546 */47 public function maybeFixSubscriptions()48 {49 $fixer = new \Mollie\WooCommerce\Subscription\MaybeFixSubscription();50 $fixer->maybeFix();51 42 } 52 43 /** -
mollie-payments-for-woocommerce/trunk/vendor/autoload.php
r3226701 r3262577 23 23 require_once __DIR__ . '/composer/autoload_real.php'; 24 24 25 return ComposerAutoloaderInit c0778a800f6c5eb39482522e8993a1d5::getLoader();25 return ComposerAutoloaderInitb1e8936703aa6cff296fa891dd9ccf25::getLoader(); -
mollie-payments-for-woocommerce/trunk/vendor/composer/autoload_classmap.php
r3242448 r3262577 154 154 'Mollie\\Api\\Types\\SubscriptionStatus' => $vendorDir . '/mollie/mollie-api-php/src/Types/SubscriptionStatus.php', 155 155 'Mollie\\Api\\Types\\TerminalStatus' => $vendorDir . '/mollie/mollie-api-php/src/Types/TerminalStatus.php', 156 'Mollie\\Dhii\\Services\\Extension' => $vendorDir . '/dhii/services/src/Extension.php', 157 'Mollie\\Dhii\\Services\\Extensions\\ArrayExtension' => $vendorDir . '/dhii/services/src/Extensions/ArrayExtension.php', 158 'Mollie\\Dhii\\Services\\Factories\\Alias' => $vendorDir . '/dhii/services/src/Factories/Alias.php', 159 'Mollie\\Dhii\\Services\\Factories\\Constructor' => $vendorDir . '/dhii/services/src/Factories/Constructor.php', 160 'Mollie\\Dhii\\Services\\Factories\\FuncService' => $vendorDir . '/dhii/services/src/Factories/FuncService.php', 161 'Mollie\\Dhii\\Services\\Factories\\GlobalVar' => $vendorDir . '/dhii/services/src/Factories/GlobalVar.php', 162 'Mollie\\Dhii\\Services\\Factories\\ServiceList' => $vendorDir . '/dhii/services/src/Factories/ServiceList.php', 163 'Mollie\\Dhii\\Services\\Factories\\StringService' => $vendorDir . '/dhii/services/src/Factories/StringService.php', 164 'Mollie\\Dhii\\Services\\Factories\\Value' => $vendorDir . '/dhii/services/src/Factories/Value.php', 165 'Mollie\\Dhii\\Services\\Factory' => $vendorDir . '/dhii/services/src/Factory.php', 166 'Mollie\\Dhii\\Services\\ResolveKeysCapableTrait' => $vendorDir . '/dhii/services/src/ResolveKeysCapableTrait.php', 167 'Mollie\\Dhii\\Services\\Service' => $vendorDir . '/dhii/services/src/Service.php', 156 168 'Mollie\\Inpsyde\\EnvironmentChecker\\ConstraintsCollectionFactory' => $baseDir . '/pluginEnvironmentChecker/ConstraintsCollectionFactory.php', 157 169 'Mollie\\Inpsyde\\EnvironmentChecker\\ConstraintsCollectionFactoryInterface' => $baseDir . '/pluginEnvironmentChecker/ConstraintsCollectionFactoryInterface.php', … … 182 194 'Mollie\\Inpsyde\\Modularity\\Properties\\Properties' => $vendorDir . '/inpsyde/modularity/src/Properties/Properties.php', 183 195 'Mollie\\Inpsyde\\Modularity\\Properties\\ThemeProperties' => $vendorDir . '/inpsyde/modularity/src/Properties/ThemeProperties.php', 196 'Mollie\\Inpsyde\\PaymentGateway\\DefaultIconsRenderer' => $baseDir . '/lib/payment-gateway/src/DefaultIconsRenderer.php', 197 'Mollie\\Inpsyde\\PaymentGateway\\Fields\\ContentField' => $baseDir . '/lib/payment-gateway/src/Fields/ContentField.php', 198 'Mollie\\Inpsyde\\PaymentGateway\\GatewayIconsRendererInterface' => $baseDir . '/lib/payment-gateway/src/GatewayIconsRendererInterface.php', 199 'Mollie\\Inpsyde\\PaymentGateway\\I18n' => $baseDir . '/lib/payment-gateway/src/I18n.php', 200 'Mollie\\Inpsyde\\PaymentGateway\\Icon' => $baseDir . '/lib/payment-gateway/src/Icon.php', 201 'Mollie\\Inpsyde\\PaymentGateway\\IconProviderInterface' => $baseDir . '/lib/payment-gateway/src/IconProviderInterface.php', 202 'Mollie\\Inpsyde\\PaymentGateway\\Method\\CustomSettingsFields' => $baseDir . '/lib/payment-gateway/src/Method/CustomSettingsFields.php', 203 'Mollie\\Inpsyde\\PaymentGateway\\Method\\CustomSettingsFieldsDefinition' => $baseDir . '/lib/payment-gateway/src/Method/CustomSettingsFieldsDefinition.php', 204 'Mollie\\Inpsyde\\PaymentGateway\\Method\\DefaultPaymentMethodDefinitionTrait' => $baseDir . '/lib/payment-gateway/src/Method/DefaultPaymentMethodDefinitionTrait.php', 205 'Mollie\\Inpsyde\\PaymentGateway\\Method\\PaymentMethodDefinition' => $baseDir . '/lib/payment-gateway/src/Method/PaymentMethodDefinition.php', 206 'Mollie\\Inpsyde\\PaymentGateway\\NoopPaymentProcessor' => $baseDir . '/lib/payment-gateway/src/NoopPaymentProcessor.php', 207 'Mollie\\Inpsyde\\PaymentGateway\\NoopPaymentRequestValidator' => $baseDir . '/lib/payment-gateway/src/NoopPaymentRequestValidator.php', 208 'Mollie\\Inpsyde\\PaymentGateway\\NoopRefundProcessor' => $baseDir . '/lib/payment-gateway/src/NoopRefundProcessor.php', 209 'Mollie\\Inpsyde\\PaymentGateway\\PaymentFieldsRendererInterface' => $baseDir . '/lib/payment-gateway/src/PaymentFieldsRendererInterface.php', 210 'Mollie\\Inpsyde\\PaymentGateway\\PaymentGateway' => $baseDir . '/lib/payment-gateway/src/PaymentGateway.php', 211 'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayBlocks' => $baseDir . '/lib/payment-gateway/src/PaymentGatewayBlocks.php', 212 'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayModule' => $baseDir . '/lib/payment-gateway/src/PaymentGatewayModule.php', 213 'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayValidator' => $baseDir . '/lib/payment-gateway/src/PaymentGatewayValidator.php', 214 'Mollie\\Inpsyde\\PaymentGateway\\PaymentMethodServiceProviderTrait' => $baseDir . '/lib/payment-gateway/src/PaymentMethodServiceProviderTrait.php', 215 'Mollie\\Inpsyde\\PaymentGateway\\PaymentProcessorInterface' => $baseDir . '/lib/payment-gateway/src/PaymentProcessorInterface.php', 216 'Mollie\\Inpsyde\\PaymentGateway\\PaymentRequestValidatorInterface' => $baseDir . '/lib/payment-gateway/src/PaymentRequestValidatorInterface.php', 217 'Mollie\\Inpsyde\\PaymentGateway\\RefundProcessorInterface' => $baseDir . '/lib/payment-gateway/src/RefundProcessorInterface.php', 218 'Mollie\\Inpsyde\\PaymentGateway\\ServiceKeyGenerator' => $baseDir . '/lib/payment-gateway/src/ServiceKeyGenerator.php', 219 'Mollie\\Inpsyde\\PaymentGateway\\SettingsFieldRendererInterface' => $baseDir . '/lib/payment-gateway/src/SettingsFieldRendererInterface.php', 220 'Mollie\\Inpsyde\\PaymentGateway\\SettingsFieldSanitizerInterface' => $baseDir . '/lib/payment-gateway/src/SettingsFieldSanitizerInterface.php', 221 'Mollie\\Inpsyde\\PaymentGateway\\StaticIconProvider' => $baseDir . '/lib/payment-gateway/src/StaticIconProvider.php', 184 222 'Mollie\\Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php', 185 223 'Mollie\\Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php', … … 217 255 'Mollie\\WooCommerce\\Components\\ComponentsStyles' => $baseDir . '/src/Components/ComponentsStyles.php', 218 256 'Mollie\\WooCommerce\\Components\\StylesPropertiesDictionary' => $baseDir . '/src/Components/StylesPropertiesDictionary.php', 257 'Mollie\\WooCommerce\\Gateway\\DeprecatedGatewayBuilder' => $baseDir . '/src/Gateway/DeprecatedGatewayBuilder.php', 219 258 'Mollie\\WooCommerce\\Gateway\\GatewayModule' => $baseDir . '/src/Gateway/GatewayModule.php', 220 'Mollie\\WooCommerce\\Gateway\\MolliePaymentGateway' => $baseDir . '/src/Gateway/MolliePaymentGateway.php', 221 'Mollie\\WooCommerce\\Gateway\\MolliePaymentGatewayI' => $baseDir . '/src/Gateway/MolliePaymentGatewayI.php', 259 'Mollie\\WooCommerce\\Gateway\\MolliePaymentGatewayHandler' => $baseDir . '/src/Gateway/MolliePaymentGatewayHandler.php', 222 260 'Mollie\\WooCommerce\\Gateway\\OrderMandatoryGatewayDisabler' => $baseDir . '/src/Gateway/OrderMandatoryGatewayDisabler.php', 261 'Mollie\\WooCommerce\\Gateway\\Refund\\OrderItemsRefunder' => $baseDir . '/src/Gateway/Refund/OrderItemsRefunder.php', 262 'Mollie\\WooCommerce\\Gateway\\Refund\\OrderLineStatus' => $baseDir . '/src/Gateway/Refund/OrderLineStatus.php', 263 'Mollie\\WooCommerce\\Gateway\\Refund\\PartialRefundException' => $baseDir . '/src/Gateway/Refund/PartialRefundException.php', 264 'Mollie\\WooCommerce\\Gateway\\Refund\\RefundLineItemsBuilder' => $baseDir . '/src/Gateway/Refund/RefundLineItemsBuilder.php', 265 'Mollie\\WooCommerce\\Gateway\\Refund\\RefundProcessor' => $baseDir . '/src/Gateway/Refund/RefundProcessor.php', 223 266 'Mollie\\WooCommerce\\Gateway\\Surcharge' => $baseDir . '/src/Gateway/Surcharge.php', 224 267 'Mollie\\WooCommerce\\Gateway\\Voucher\\MaybeDisableGateway' => $baseDir . '/src/Gateway/Voucher/MaybeDisableGateway.php', … … 258 301 'Mollie\\WooCommerce\\PaymentMethods\\Giropay' => $baseDir . '/src/PaymentMethods/Giropay.php', 259 302 'Mollie\\WooCommerce\\PaymentMethods\\IconFactory' => $baseDir . '/src/PaymentMethods/IconFactory.php', 303 'Mollie\\WooCommerce\\PaymentMethods\\Icon\\GatewayIconsRenderer' => $baseDir . '/src/PaymentMethods/Icon/GatewayIconsRenderer.php', 260 304 'Mollie\\WooCommerce\\PaymentMethods\\Ideal' => $baseDir . '/src/PaymentMethods/Ideal.php', 261 305 'Mollie\\WooCommerce\\PaymentMethods\\In3' => $baseDir . '/src/PaymentMethods/In3.php', … … 269 313 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\InstructionStrategyI' => $baseDir . '/src/PaymentMethods/InstructionStrategies/InstructionStrategyI.php', 270 314 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\MybankInstructionStrategy' => $baseDir . '/src/PaymentMethods/InstructionStrategies/MybankInstructionStrategy.php', 315 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\OrderInstructionsManager' => $baseDir . '/src/PaymentMethods/InstructionStrategies/OrderInstructionsManager.php', 271 316 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\PaypalInstructionStrategy' => $baseDir . '/src/PaymentMethods/InstructionStrategies/PaypalInstructionStrategy.php', 272 317 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\Przelewy24InstructionStrategy' => $baseDir . '/src/PaymentMethods/InstructionStrategies/Przelewy24InstructionStrategy.php', … … 282 327 'Mollie\\WooCommerce\\PaymentMethods\\Paybybank' => $baseDir . '/src/PaymentMethods/Paybybank.php', 283 328 'Mollie\\WooCommerce\\PaymentMethods\\Payconiq' => $baseDir . '/src/PaymentMethods/Payconiq.php', 329 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\AbstractPaymentFieldsRenderer' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/AbstractPaymentFieldsRenderer.php', 284 330 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\BancomatpayFieldsStrategy' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/BancomatpayFieldsStrategy.php', 285 331 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\BillieFieldsStrategy' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/BillieFieldsStrategy.php', … … 290 336 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\IssuersDropdownBehavior' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/IssuersDropdownBehavior.php', 291 337 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\KbcFieldsStrategy' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/KbcFieldsStrategy.php', 338 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\NoopPaymentFieldsRenderer' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/NoopPaymentFieldsRenderer.php', 292 339 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\PaymentFieldsStrategiesTrait' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategiesTrait.php', 293 340 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\PaymentFieldsStrategyI' => $baseDir . '/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategyI.php', … … 313 360 'Mollie\\WooCommerce\\Payment\\MolliePayment' => $baseDir . '/src/Payment/MolliePayment.php', 314 361 'Mollie\\WooCommerce\\Payment\\MollieSubscription' => $baseDir . '/src/Payment/MollieSubscription.php', 315 'Mollie\\WooCommerce\\Payment\\OrderInstructionsService' => $baseDir . '/src/Payment/OrderInstructionsService.php',316 'Mollie\\WooCommerce\\Payment\\OrderItemsRefunder' => $baseDir . '/src/Payment/OrderItemsRefunder.php',317 'Mollie\\WooCommerce\\Payment\\OrderLineStatus' => $baseDir . '/src/Payment/OrderLineStatus.php',318 362 'Mollie\\WooCommerce\\Payment\\OrderLines' => $baseDir . '/src/Payment/OrderLines.php', 319 'Mollie\\WooCommerce\\Payment\\PartialRefundException' => $baseDir . '/src/Payment/PartialRefundException.php',320 363 'Mollie\\WooCommerce\\Payment\\PaymentCheckoutRedirectService' => $baseDir . '/src/Payment/PaymentCheckoutRedirectService.php', 321 364 'Mollie\\WooCommerce\\Payment\\PaymentFactory' => $baseDir . '/src/Payment/PaymentFactory.php', 322 'Mollie\\WooCommerce\\Payment\\Payment FieldsService' => $baseDir . '/src/Payment/PaymentFieldsService.php',365 'Mollie\\WooCommerce\\Payment\\PaymentLines' => $baseDir . '/src/Payment/PaymentLines.php', 323 366 'Mollie\\WooCommerce\\Payment\\PaymentModule' => $baseDir . '/src/Payment/PaymentModule.php', 324 'Mollie\\WooCommerce\\Payment\\PaymentService' => $baseDir . '/src/Payment/PaymentService.php', 325 'Mollie\\WooCommerce\\Payment\\RefundLineItemsBuilder' => $baseDir . '/src/Payment/RefundLineItemsBuilder.php', 367 'Mollie\\WooCommerce\\Payment\\PaymentProcessor' => $baseDir . '/src/Payment/PaymentProcessor.php', 368 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddCustomRequestFieldsMiddleware' => $baseDir . '/src/Payment/Request/Middleware/AddCustomRequestFieldsMiddleware.php', 369 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddSequenceTypeForSubscriptionsMiddleware' => $baseDir . '/src/Payment/Request/Middleware/AddSequenceTypeForSubscriptionsMiddleware.php', 370 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddressMiddleware' => $baseDir . '/src/Payment/Request/Middleware/AddressMiddleware.php', 371 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\ApplePayTokenMiddleware' => $baseDir . '/src/Payment/Request/Middleware/ApplePayTokenMiddleware.php', 372 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CaptureModeMiddleware' => $baseDir . '/src/Payment/Request/Middleware/CaptureModeMiddleware.php', 373 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CardTokenMiddleware' => $baseDir . '/src/Payment/Request/Middleware/CardTokenMiddleware.php', 374 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CustomerBirthdateMiddleware' => $baseDir . '/src/Payment/Request/Middleware/CustomerBirthdateMiddleware.php', 375 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\MiddlewareHandler' => $baseDir . '/src/Payment/Request/Middleware/MiddlewareHandler.php', 376 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\OrderLinesMiddleware' => $baseDir . '/src/Payment/Request/Middleware/OrderLinesMiddleware.php', 377 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\PaymentDescriptionMiddleware' => $baseDir . '/src/Payment/Request/Middleware/PaymentDescriptionMiddleware.php', 378 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\RequestMiddlewareInterface' => $baseDir . '/src/Payment/Request/Middleware/RequestMiddlewareInterface.php', 379 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\SelectedIssuerMiddleware' => $baseDir . '/src/Payment/Request/Middleware/SelectedIssuerMiddleware.php', 380 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\StoreCustomerMiddleware' => $baseDir . '/src/Payment/Request/Middleware/StoreCustomerMiddleware.php', 381 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\UrlMiddleware' => $baseDir . '/src/Payment/Request/Middleware/UrlMiddleware.php', 382 'Mollie\\WooCommerce\\Payment\\Request\\RequestFactory' => $baseDir . '/src/Payment/Request/RequestFactory.php', 383 'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\OrderRequestStrategy' => $baseDir . '/src/Payment/Request/Strategies/OrderRequestStrategy.php', 384 'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\PaymentRequestStrategy' => $baseDir . '/src/Payment/Request/Strategies/PaymentRequestStrategy.php', 385 'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\RequestStrategyInterface' => $baseDir . '/src/Payment/Request/Strategies/RequestStrategyInterface.php', 326 386 'Mollie\\WooCommerce\\SDK\\Api' => $baseDir . '/src/SDK/Api.php', 327 387 'Mollie\\WooCommerce\\SDK\\CouldNotConnectToMollie' => $baseDir . '/src/SDK/CouldNotConnectToMollie.php', … … 333 393 'Mollie\\WooCommerce\\SDK\\WordPressHttpAdapterPicker' => $baseDir . '/src/SDK/WordPressHttpAdapterPicker.php', 334 394 'Mollie\\WooCommerce\\Settings\\General\\MollieGeneralSettings' => $baseDir . '/src/Settings/General/MollieGeneralSettings.php', 395 'Mollie\\WooCommerce\\Settings\\General\\MultiCountrySettingsField' => $baseDir . '/src/Settings/General/MultiCountrySettingsField.php', 335 396 'Mollie\\WooCommerce\\Settings\\MollieSettingsPage' => $baseDir . '/src/Settings/MollieSettingsPage.php', 336 397 'Mollie\\WooCommerce\\Settings\\Page\\AbstractPage' => $baseDir . '/src/Settings/Page/AbstractPage.php', … … 359 420 'Mollie\\WooCommerce\\Shared\\SharedModule' => $baseDir . '/src/Shared/SharedModule.php', 360 421 'Mollie\\WooCommerce\\Shared\\Status' => $baseDir . '/src/Shared/Status.php', 361 'Mollie\\WooCommerce\\Subscription\\MaybeFixSubscription' => $baseDir . '/src/Subscription/MaybeFixSubscription.php', 362 'Mollie\\WooCommerce\\Subscription\\MollieSepaRecurringGateway' => $baseDir . '/src/Subscription/MollieSepaRecurringGateway.php', 363 'Mollie\\WooCommerce\\Subscription\\MollieSubscriptionGateway' => $baseDir . '/src/Subscription/MollieSubscriptionGateway.php', 422 'Mollie\\WooCommerce\\Subscription\\MollieSepaRecurringGatewayHandler' => $baseDir . '/src/Subscription/MollieSepaRecurringGatewayHandler.php', 423 'Mollie\\WooCommerce\\Subscription\\MollieSubscriptionGatewayHandler' => $baseDir . '/src/Subscription/MollieSubscriptionGatewayHandler.php', 364 424 'Mollie\\WooCommerce\\Subscription\\SubscriptionModule' => $baseDir . '/src/Subscription/SubscriptionModule.php', 365 425 'Mollie\\WooCommerce\\Uninstall\\CleanDb' => $baseDir . '/src/Uninstall/CleanDb.php', -
mollie-payments-for-woocommerce/trunk/vendor/composer/autoload_psr4.php
r3164004 r3262577 10 10 'Mollie\\Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 11 11 'Mollie\\Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 12 'Mollie\\Inpsyde\\PaymentGateway\\' => array($baseDir . '/lib/payment-gateway/src'), 12 13 'Mollie\\Inpsyde\\Modularity\\' => array($vendorDir . '/inpsyde/modularity/src'), 13 14 'Mollie\\Inpsyde\\EnvironmentChecker\\' => array($baseDir . '/pluginEnvironmentChecker'), 15 'Mollie\\Dhii\\Services\\' => array($vendorDir . '/dhii/services/src'), 14 16 'Mollie\\Api\\' => array($vendorDir . '/mollie/mollie-api-php/src'), 15 17 'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'), -
mollie-payments-for-woocommerce/trunk/vendor/composer/autoload_real.php
r3226701 r3262577 3 3 // autoload_real.php @generated by Composer 4 4 5 class ComposerAutoloaderInit c0778a800f6c5eb39482522e8993a1d55 class ComposerAutoloaderInitb1e8936703aa6cff296fa891dd9ccf25 6 6 { 7 7 private static $loader; … … 25 25 require __DIR__ . '/platform_check.php'; 26 26 27 spl_autoload_register(array('ComposerAutoloaderInit c0778a800f6c5eb39482522e8993a1d5', 'loadClassLoader'), true, true);27 spl_autoload_register(array('ComposerAutoloaderInitb1e8936703aa6cff296fa891dd9ccf25', 'loadClassLoader'), true, true); 28 28 self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); 29 spl_autoload_unregister(array('ComposerAutoloaderInit c0778a800f6c5eb39482522e8993a1d5', 'loadClassLoader'));29 spl_autoload_unregister(array('ComposerAutoloaderInitb1e8936703aa6cff296fa891dd9ccf25', 'loadClassLoader')); 30 30 31 31 require __DIR__ . '/autoload_static.php'; 32 call_user_func(\Composer\Autoload\ComposerStaticInit c0778a800f6c5eb39482522e8993a1d5::getInitializer($loader));32 call_user_func(\Composer\Autoload\ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25::getInitializer($loader)); 33 33 34 34 $loader->register(true); -
mollie-payments-for-woocommerce/trunk/vendor/composer/autoload_static.php
r3242448 r3262577 5 5 namespace Composer\Autoload; 6 6 7 class ComposerStaticInit c0778a800f6c5eb39482522e8993a1d57 class ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25 8 8 { 9 9 public static $prefixLengthsPsr4 = array ( … … 13 13 'Mollie\\Psr\\Log\\' => 15, 14 14 'Mollie\\Psr\\Container\\' => 21, 15 'Mollie\\Inpsyde\\PaymentGateway\\' => 30, 15 16 'Mollie\\Inpsyde\\Modularity\\' => 26, 16 17 'Mollie\\Inpsyde\\EnvironmentChecker\\' => 34, 18 'Mollie\\Dhii\\Services\\' => 21, 17 19 'Mollie\\Api\\' => 11, 18 20 ), … … 36 38 0 => __DIR__ . '/..' . '/psr/container/src', 37 39 ), 40 'Mollie\\Inpsyde\\PaymentGateway\\' => 41 array ( 42 0 => __DIR__ . '/../..' . '/lib/payment-gateway/src', 43 ), 38 44 'Mollie\\Inpsyde\\Modularity\\' => 39 45 array ( … … 43 49 array ( 44 50 0 => __DIR__ . '/../..' . '/pluginEnvironmentChecker', 51 ), 52 'Mollie\\Dhii\\Services\\' => 53 array ( 54 0 => __DIR__ . '/..' . '/dhii/services/src', 45 55 ), 46 56 'Mollie\\Api\\' => … … 202 212 'Mollie\\Api\\Types\\SubscriptionStatus' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/Types/SubscriptionStatus.php', 203 213 'Mollie\\Api\\Types\\TerminalStatus' => __DIR__ . '/..' . '/mollie/mollie-api-php/src/Types/TerminalStatus.php', 214 'Mollie\\Dhii\\Services\\Extension' => __DIR__ . '/..' . '/dhii/services/src/Extension.php', 215 'Mollie\\Dhii\\Services\\Extensions\\ArrayExtension' => __DIR__ . '/..' . '/dhii/services/src/Extensions/ArrayExtension.php', 216 'Mollie\\Dhii\\Services\\Factories\\Alias' => __DIR__ . '/..' . '/dhii/services/src/Factories/Alias.php', 217 'Mollie\\Dhii\\Services\\Factories\\Constructor' => __DIR__ . '/..' . '/dhii/services/src/Factories/Constructor.php', 218 'Mollie\\Dhii\\Services\\Factories\\FuncService' => __DIR__ . '/..' . '/dhii/services/src/Factories/FuncService.php', 219 'Mollie\\Dhii\\Services\\Factories\\GlobalVar' => __DIR__ . '/..' . '/dhii/services/src/Factories/GlobalVar.php', 220 'Mollie\\Dhii\\Services\\Factories\\ServiceList' => __DIR__ . '/..' . '/dhii/services/src/Factories/ServiceList.php', 221 'Mollie\\Dhii\\Services\\Factories\\StringService' => __DIR__ . '/..' . '/dhii/services/src/Factories/StringService.php', 222 'Mollie\\Dhii\\Services\\Factories\\Value' => __DIR__ . '/..' . '/dhii/services/src/Factories/Value.php', 223 'Mollie\\Dhii\\Services\\Factory' => __DIR__ . '/..' . '/dhii/services/src/Factory.php', 224 'Mollie\\Dhii\\Services\\ResolveKeysCapableTrait' => __DIR__ . '/..' . '/dhii/services/src/ResolveKeysCapableTrait.php', 225 'Mollie\\Dhii\\Services\\Service' => __DIR__ . '/..' . '/dhii/services/src/Service.php', 204 226 'Mollie\\Inpsyde\\EnvironmentChecker\\ConstraintsCollectionFactory' => __DIR__ . '/../..' . '/pluginEnvironmentChecker/ConstraintsCollectionFactory.php', 205 227 'Mollie\\Inpsyde\\EnvironmentChecker\\ConstraintsCollectionFactoryInterface' => __DIR__ . '/../..' . '/pluginEnvironmentChecker/ConstraintsCollectionFactoryInterface.php', … … 230 252 'Mollie\\Inpsyde\\Modularity\\Properties\\Properties' => __DIR__ . '/..' . '/inpsyde/modularity/src/Properties/Properties.php', 231 253 'Mollie\\Inpsyde\\Modularity\\Properties\\ThemeProperties' => __DIR__ . '/..' . '/inpsyde/modularity/src/Properties/ThemeProperties.php', 254 'Mollie\\Inpsyde\\PaymentGateway\\DefaultIconsRenderer' => __DIR__ . '/../..' . '/lib/payment-gateway/src/DefaultIconsRenderer.php', 255 'Mollie\\Inpsyde\\PaymentGateway\\Fields\\ContentField' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Fields/ContentField.php', 256 'Mollie\\Inpsyde\\PaymentGateway\\GatewayIconsRendererInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/GatewayIconsRendererInterface.php', 257 'Mollie\\Inpsyde\\PaymentGateway\\I18n' => __DIR__ . '/../..' . '/lib/payment-gateway/src/I18n.php', 258 'Mollie\\Inpsyde\\PaymentGateway\\Icon' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Icon.php', 259 'Mollie\\Inpsyde\\PaymentGateway\\IconProviderInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/IconProviderInterface.php', 260 'Mollie\\Inpsyde\\PaymentGateway\\Method\\CustomSettingsFields' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Method/CustomSettingsFields.php', 261 'Mollie\\Inpsyde\\PaymentGateway\\Method\\CustomSettingsFieldsDefinition' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Method/CustomSettingsFieldsDefinition.php', 262 'Mollie\\Inpsyde\\PaymentGateway\\Method\\DefaultPaymentMethodDefinitionTrait' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Method/DefaultPaymentMethodDefinitionTrait.php', 263 'Mollie\\Inpsyde\\PaymentGateway\\Method\\PaymentMethodDefinition' => __DIR__ . '/../..' . '/lib/payment-gateway/src/Method/PaymentMethodDefinition.php', 264 'Mollie\\Inpsyde\\PaymentGateway\\NoopPaymentProcessor' => __DIR__ . '/../..' . '/lib/payment-gateway/src/NoopPaymentProcessor.php', 265 'Mollie\\Inpsyde\\PaymentGateway\\NoopPaymentRequestValidator' => __DIR__ . '/../..' . '/lib/payment-gateway/src/NoopPaymentRequestValidator.php', 266 'Mollie\\Inpsyde\\PaymentGateway\\NoopRefundProcessor' => __DIR__ . '/../..' . '/lib/payment-gateway/src/NoopRefundProcessor.php', 267 'Mollie\\Inpsyde\\PaymentGateway\\PaymentFieldsRendererInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentFieldsRendererInterface.php', 268 'Mollie\\Inpsyde\\PaymentGateway\\PaymentGateway' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentGateway.php', 269 'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayBlocks' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentGatewayBlocks.php', 270 'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayModule' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentGatewayModule.php', 271 'Mollie\\Inpsyde\\PaymentGateway\\PaymentGatewayValidator' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentGatewayValidator.php', 272 'Mollie\\Inpsyde\\PaymentGateway\\PaymentMethodServiceProviderTrait' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentMethodServiceProviderTrait.php', 273 'Mollie\\Inpsyde\\PaymentGateway\\PaymentProcessorInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentProcessorInterface.php', 274 'Mollie\\Inpsyde\\PaymentGateway\\PaymentRequestValidatorInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/PaymentRequestValidatorInterface.php', 275 'Mollie\\Inpsyde\\PaymentGateway\\RefundProcessorInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/RefundProcessorInterface.php', 276 'Mollie\\Inpsyde\\PaymentGateway\\ServiceKeyGenerator' => __DIR__ . '/../..' . '/lib/payment-gateway/src/ServiceKeyGenerator.php', 277 'Mollie\\Inpsyde\\PaymentGateway\\SettingsFieldRendererInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/SettingsFieldRendererInterface.php', 278 'Mollie\\Inpsyde\\PaymentGateway\\SettingsFieldSanitizerInterface' => __DIR__ . '/../..' . '/lib/payment-gateway/src/SettingsFieldSanitizerInterface.php', 279 'Mollie\\Inpsyde\\PaymentGateway\\StaticIconProvider' => __DIR__ . '/../..' . '/lib/payment-gateway/src/StaticIconProvider.php', 232 280 'Mollie\\Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php', 233 281 'Mollie\\Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php', … … 265 313 'Mollie\\WooCommerce\\Components\\ComponentsStyles' => __DIR__ . '/../..' . '/src/Components/ComponentsStyles.php', 266 314 'Mollie\\WooCommerce\\Components\\StylesPropertiesDictionary' => __DIR__ . '/../..' . '/src/Components/StylesPropertiesDictionary.php', 315 'Mollie\\WooCommerce\\Gateway\\DeprecatedGatewayBuilder' => __DIR__ . '/../..' . '/src/Gateway/DeprecatedGatewayBuilder.php', 267 316 'Mollie\\WooCommerce\\Gateway\\GatewayModule' => __DIR__ . '/../..' . '/src/Gateway/GatewayModule.php', 268 'Mollie\\WooCommerce\\Gateway\\MolliePaymentGateway' => __DIR__ . '/../..' . '/src/Gateway/MolliePaymentGateway.php', 269 'Mollie\\WooCommerce\\Gateway\\MolliePaymentGatewayI' => __DIR__ . '/../..' . '/src/Gateway/MolliePaymentGatewayI.php', 317 'Mollie\\WooCommerce\\Gateway\\MolliePaymentGatewayHandler' => __DIR__ . '/../..' . '/src/Gateway/MolliePaymentGatewayHandler.php', 270 318 'Mollie\\WooCommerce\\Gateway\\OrderMandatoryGatewayDisabler' => __DIR__ . '/../..' . '/src/Gateway/OrderMandatoryGatewayDisabler.php', 319 'Mollie\\WooCommerce\\Gateway\\Refund\\OrderItemsRefunder' => __DIR__ . '/../..' . '/src/Gateway/Refund/OrderItemsRefunder.php', 320 'Mollie\\WooCommerce\\Gateway\\Refund\\OrderLineStatus' => __DIR__ . '/../..' . '/src/Gateway/Refund/OrderLineStatus.php', 321 'Mollie\\WooCommerce\\Gateway\\Refund\\PartialRefundException' => __DIR__ . '/../..' . '/src/Gateway/Refund/PartialRefundException.php', 322 'Mollie\\WooCommerce\\Gateway\\Refund\\RefundLineItemsBuilder' => __DIR__ . '/../..' . '/src/Gateway/Refund/RefundLineItemsBuilder.php', 323 'Mollie\\WooCommerce\\Gateway\\Refund\\RefundProcessor' => __DIR__ . '/../..' . '/src/Gateway/Refund/RefundProcessor.php', 271 324 'Mollie\\WooCommerce\\Gateway\\Surcharge' => __DIR__ . '/../..' . '/src/Gateway/Surcharge.php', 272 325 'Mollie\\WooCommerce\\Gateway\\Voucher\\MaybeDisableGateway' => __DIR__ . '/../..' . '/src/Gateway/Voucher/MaybeDisableGateway.php', … … 306 359 'Mollie\\WooCommerce\\PaymentMethods\\Giropay' => __DIR__ . '/../..' . '/src/PaymentMethods/Giropay.php', 307 360 'Mollie\\WooCommerce\\PaymentMethods\\IconFactory' => __DIR__ . '/../..' . '/src/PaymentMethods/IconFactory.php', 361 'Mollie\\WooCommerce\\PaymentMethods\\Icon\\GatewayIconsRenderer' => __DIR__ . '/../..' . '/src/PaymentMethods/Icon/GatewayIconsRenderer.php', 308 362 'Mollie\\WooCommerce\\PaymentMethods\\Ideal' => __DIR__ . '/../..' . '/src/PaymentMethods/Ideal.php', 309 363 'Mollie\\WooCommerce\\PaymentMethods\\In3' => __DIR__ . '/../..' . '/src/PaymentMethods/In3.php', … … 317 371 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\InstructionStrategyI' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/InstructionStrategyI.php', 318 372 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\MybankInstructionStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/MybankInstructionStrategy.php', 373 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\OrderInstructionsManager' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/OrderInstructionsManager.php', 319 374 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\PaypalInstructionStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/PaypalInstructionStrategy.php', 320 375 'Mollie\\WooCommerce\\PaymentMethods\\InstructionStrategies\\Przelewy24InstructionStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/InstructionStrategies/Przelewy24InstructionStrategy.php', … … 330 385 'Mollie\\WooCommerce\\PaymentMethods\\Paybybank' => __DIR__ . '/../..' . '/src/PaymentMethods/Paybybank.php', 331 386 'Mollie\\WooCommerce\\PaymentMethods\\Payconiq' => __DIR__ . '/../..' . '/src/PaymentMethods/Payconiq.php', 387 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\AbstractPaymentFieldsRenderer' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/AbstractPaymentFieldsRenderer.php', 332 388 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\BancomatpayFieldsStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/BancomatpayFieldsStrategy.php', 333 389 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\BillieFieldsStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/BillieFieldsStrategy.php', … … 338 394 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\IssuersDropdownBehavior' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/IssuersDropdownBehavior.php', 339 395 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\KbcFieldsStrategy' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/KbcFieldsStrategy.php', 396 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\NoopPaymentFieldsRenderer' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/NoopPaymentFieldsRenderer.php', 340 397 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\PaymentFieldsStrategiesTrait' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategiesTrait.php', 341 398 'Mollie\\WooCommerce\\PaymentMethods\\PaymentFieldsStrategies\\PaymentFieldsStrategyI' => __DIR__ . '/../..' . '/src/PaymentMethods/PaymentFieldsStrategies/PaymentFieldsStrategyI.php', … … 361 418 'Mollie\\WooCommerce\\Payment\\MolliePayment' => __DIR__ . '/../..' . '/src/Payment/MolliePayment.php', 362 419 'Mollie\\WooCommerce\\Payment\\MollieSubscription' => __DIR__ . '/../..' . '/src/Payment/MollieSubscription.php', 363 'Mollie\\WooCommerce\\Payment\\OrderInstructionsService' => __DIR__ . '/../..' . '/src/Payment/OrderInstructionsService.php',364 'Mollie\\WooCommerce\\Payment\\OrderItemsRefunder' => __DIR__ . '/../..' . '/src/Payment/OrderItemsRefunder.php',365 'Mollie\\WooCommerce\\Payment\\OrderLineStatus' => __DIR__ . '/../..' . '/src/Payment/OrderLineStatus.php',366 420 'Mollie\\WooCommerce\\Payment\\OrderLines' => __DIR__ . '/../..' . '/src/Payment/OrderLines.php', 367 'Mollie\\WooCommerce\\Payment\\PartialRefundException' => __DIR__ . '/../..' . '/src/Payment/PartialRefundException.php',368 421 'Mollie\\WooCommerce\\Payment\\PaymentCheckoutRedirectService' => __DIR__ . '/../..' . '/src/Payment/PaymentCheckoutRedirectService.php', 369 422 'Mollie\\WooCommerce\\Payment\\PaymentFactory' => __DIR__ . '/../..' . '/src/Payment/PaymentFactory.php', 370 'Mollie\\WooCommerce\\Payment\\Payment FieldsService' => __DIR__ . '/../..' . '/src/Payment/PaymentFieldsService.php',423 'Mollie\\WooCommerce\\Payment\\PaymentLines' => __DIR__ . '/../..' . '/src/Payment/PaymentLines.php', 371 424 'Mollie\\WooCommerce\\Payment\\PaymentModule' => __DIR__ . '/../..' . '/src/Payment/PaymentModule.php', 372 'Mollie\\WooCommerce\\Payment\\PaymentService' => __DIR__ . '/../..' . '/src/Payment/PaymentService.php', 373 'Mollie\\WooCommerce\\Payment\\RefundLineItemsBuilder' => __DIR__ . '/../..' . '/src/Payment/RefundLineItemsBuilder.php', 425 'Mollie\\WooCommerce\\Payment\\PaymentProcessor' => __DIR__ . '/../..' . '/src/Payment/PaymentProcessor.php', 426 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddCustomRequestFieldsMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/AddCustomRequestFieldsMiddleware.php', 427 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddSequenceTypeForSubscriptionsMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/AddSequenceTypeForSubscriptionsMiddleware.php', 428 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\AddressMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/AddressMiddleware.php', 429 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\ApplePayTokenMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/ApplePayTokenMiddleware.php', 430 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CaptureModeMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/CaptureModeMiddleware.php', 431 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CardTokenMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/CardTokenMiddleware.php', 432 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\CustomerBirthdateMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/CustomerBirthdateMiddleware.php', 433 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\MiddlewareHandler' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/MiddlewareHandler.php', 434 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\OrderLinesMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/OrderLinesMiddleware.php', 435 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\PaymentDescriptionMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/PaymentDescriptionMiddleware.php', 436 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\RequestMiddlewareInterface' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/RequestMiddlewareInterface.php', 437 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\SelectedIssuerMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/SelectedIssuerMiddleware.php', 438 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\StoreCustomerMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/StoreCustomerMiddleware.php', 439 'Mollie\\WooCommerce\\Payment\\Request\\Middleware\\UrlMiddleware' => __DIR__ . '/../..' . '/src/Payment/Request/Middleware/UrlMiddleware.php', 440 'Mollie\\WooCommerce\\Payment\\Request\\RequestFactory' => __DIR__ . '/../..' . '/src/Payment/Request/RequestFactory.php', 441 'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\OrderRequestStrategy' => __DIR__ . '/../..' . '/src/Payment/Request/Strategies/OrderRequestStrategy.php', 442 'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\PaymentRequestStrategy' => __DIR__ . '/../..' . '/src/Payment/Request/Strategies/PaymentRequestStrategy.php', 443 'Mollie\\WooCommerce\\Payment\\Request\\Strategies\\RequestStrategyInterface' => __DIR__ . '/../..' . '/src/Payment/Request/Strategies/RequestStrategyInterface.php', 374 444 'Mollie\\WooCommerce\\SDK\\Api' => __DIR__ . '/../..' . '/src/SDK/Api.php', 375 445 'Mollie\\WooCommerce\\SDK\\CouldNotConnectToMollie' => __DIR__ . '/../..' . '/src/SDK/CouldNotConnectToMollie.php', … … 381 451 'Mollie\\WooCommerce\\SDK\\WordPressHttpAdapterPicker' => __DIR__ . '/../..' . '/src/SDK/WordPressHttpAdapterPicker.php', 382 452 'Mollie\\WooCommerce\\Settings\\General\\MollieGeneralSettings' => __DIR__ . '/../..' . '/src/Settings/General/MollieGeneralSettings.php', 453 'Mollie\\WooCommerce\\Settings\\General\\MultiCountrySettingsField' => __DIR__ . '/../..' . '/src/Settings/General/MultiCountrySettingsField.php', 383 454 'Mollie\\WooCommerce\\Settings\\MollieSettingsPage' => __DIR__ . '/../..' . '/src/Settings/MollieSettingsPage.php', 384 455 'Mollie\\WooCommerce\\Settings\\Page\\AbstractPage' => __DIR__ . '/../..' . '/src/Settings/Page/AbstractPage.php', … … 407 478 'Mollie\\WooCommerce\\Shared\\SharedModule' => __DIR__ . '/../..' . '/src/Shared/SharedModule.php', 408 479 'Mollie\\WooCommerce\\Shared\\Status' => __DIR__ . '/../..' . '/src/Shared/Status.php', 409 'Mollie\\WooCommerce\\Subscription\\MaybeFixSubscription' => __DIR__ . '/../..' . '/src/Subscription/MaybeFixSubscription.php', 410 'Mollie\\WooCommerce\\Subscription\\MollieSepaRecurringGateway' => __DIR__ . '/../..' . '/src/Subscription/MollieSepaRecurringGateway.php', 411 'Mollie\\WooCommerce\\Subscription\\MollieSubscriptionGateway' => __DIR__ . '/../..' . '/src/Subscription/MollieSubscriptionGateway.php', 480 'Mollie\\WooCommerce\\Subscription\\MollieSepaRecurringGatewayHandler' => __DIR__ . '/../..' . '/src/Subscription/MollieSepaRecurringGatewayHandler.php', 481 'Mollie\\WooCommerce\\Subscription\\MollieSubscriptionGatewayHandler' => __DIR__ . '/../..' . '/src/Subscription/MollieSubscriptionGatewayHandler.php', 412 482 'Mollie\\WooCommerce\\Subscription\\SubscriptionModule' => __DIR__ . '/../..' . '/src/Subscription/SubscriptionModule.php', 413 483 'Mollie\\WooCommerce\\Uninstall\\CleanDb' => __DIR__ . '/../..' . '/src/Uninstall/CleanDb.php', … … 418 488 { 419 489 return \Closure::bind(function () use ($loader) { 420 $loader->prefixLengthsPsr4 = ComposerStaticInit c0778a800f6c5eb39482522e8993a1d5::$prefixLengthsPsr4;421 $loader->prefixDirsPsr4 = ComposerStaticInit c0778a800f6c5eb39482522e8993a1d5::$prefixDirsPsr4;422 $loader->classMap = ComposerStaticInit c0778a800f6c5eb39482522e8993a1d5::$classMap;490 $loader->prefixLengthsPsr4 = ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25::$prefixLengthsPsr4; 491 $loader->prefixDirsPsr4 = ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25::$prefixDirsPsr4; 492 $loader->classMap = ComposerStaticInitb1e8936703aa6cff296fa891dd9ccf25::$classMap; 423 493 424 494 }, null, ClassLoader::class); -
mollie-payments-for-woocommerce/trunk/vendor/composer/ca-bundle/res/cacert.pem
r3226701 r3262577 2 2 ## Bundle of CA Root Certificates 3 3 ## 4 ## Certificate data from Mozilla as of: Tue Nov 26 13:58:25 2024 GMT4 ## Certificate data from Mozilla as of: Tue Dec 31 04:12:05 2024 GMT 5 5 ## 6 6 ## Find updated versions here: https://curl.se/docs/caextract.html … … 17 17 ## 18 18 ## Conversion done with mk-ca-bundle.pl version 1.29. 19 ## SHA256: 36105b01631f9fc03b1eca779b44a30a1a5890b9bf8dc07ccb001a07301e01cf19 ## SHA256: c99d6d3f8d3d4e47719ba2b648992f5b58b150128d3aca3c05c566d8dc98e116 20 20 ## 21 21 … … 583 583 NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu 584 584 dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= 585 -----END CERTIFICATE-----586 587 SecureSign RootCA11588 ===================589 -----BEGIN CERTIFICATE-----590 MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi591 SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS592 b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw593 KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1594 cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL595 TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO596 wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq597 g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP598 O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA599 bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX600 t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh601 OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r602 bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ603 Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01604 y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061605 lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=606 585 -----END CERTIFICATE----- 607 586 … … 2320 2299 -----END CERTIFICATE----- 2321 2300 2322 Entrust Root Certification Authority - G42323 =========================================2324 -----BEGIN CERTIFICATE-----2325 MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV2326 BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu2327 bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF12328 dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF12329 dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT2330 AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV02331 L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv2332 cml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv2333 cml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D2334 umSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV2335 3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds2336 8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ2337 e9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn72338 ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X2339 xNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV2340 7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX82341 dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW2342 Hv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T2343 AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n2344 MA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q2345 jbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht2346 7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK2347 YvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt2348 jqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+2349 m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW2350 RGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA2351 JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G2352 +TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT2353 kcpG2om3PVODLAgfi49T3f+sHw==2354 -----END CERTIFICATE-----2355 2356 2301 Microsoft ECC Root Certificate Authority 2017 2357 2302 ============================================= … … 3171 3116 -----END CERTIFICATE----- 3172 3117 3173 Security Communication RootCA33174 ==============================3175 -----BEGIN CERTIFICATE-----3176 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3201 -----END CERTIFICATE-----3202 3203 3118 Security Communication ECC RootCA1 3204 3119 ================================== -
mollie-payments-for-woocommerce/trunk/vendor/composer/installed.json
r3226701 r3262577 3 3 { 4 4 "name": "composer\/ca-bundle", 5 "version": "1.5. 4",6 "version_normalized": "1.5. 4.0",5 "version": "1.5.5", 6 "version_normalized": "1.5.5.0", 7 7 "source": { 8 8 "type": "git", 9 9 "url": "https:\/\/github.com\/composer\/ca-bundle.git", 10 "reference": " bc0593537a463e55cadf45fd938d23b75095b7e1"11 }, 12 "dist": { 13 "type": "zip", 14 "url": "https:\/\/api.github.com\/repos\/composer\/ca-bundle\/zipball\/ bc0593537a463e55cadf45fd938d23b75095b7e1",15 "reference": " bc0593537a463e55cadf45fd938d23b75095b7e1",10 "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6" 11 }, 12 "dist": { 13 "type": "zip", 14 "url": "https:\/\/api.github.com\/repos\/composer\/ca-bundle\/zipball\/08c50d5ec4c6ced7d0271d2862dec8c1033283e6", 15 "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6", 16 16 "shasum": "" 17 17 }, … … 27 27 "symfony\/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" 28 28 }, 29 "time": "202 4-11-27T15:35:25+00:00",29 "time": "2025-01-08T16:17:16+00:00", 30 30 "type": "library", 31 31 "extra": { … … 62 62 "irc": "irc:\/\/irc.freenode.org\/composer", 63 63 "issues": "https:\/\/github.com\/composer\/ca-bundle\/issues", 64 "source": "https:\/\/github.com\/composer\/ca-bundle\/tree\/1.5. 4"64 "source": "https:\/\/github.com\/composer\/ca-bundle\/tree\/1.5.5" 65 65 }, 66 66 "funding": [ … … 79 79 ], 80 80 "install-path": ".\/ca-bundle" 81 }, 82 { 83 "name": "dhii\/services", 84 "version": "v0.1.0", 85 "version_normalized": "0.1.0.0", 86 "source": { 87 "type": "git", 88 "url": "https:\/\/github.com\/Dhii\/services.git", 89 "reference": "09cad8199a59d2003ad19126213075aefecaf17b" 90 }, 91 "dist": { 92 "type": "zip", 93 "url": "https:\/\/api.github.com\/repos\/Dhii\/services\/zipball\/09cad8199a59d2003ad19126213075aefecaf17b", 94 "reference": "09cad8199a59d2003ad19126213075aefecaf17b", 95 "shasum": "" 96 }, 97 "require": { 98 "php": "^7.1 | ^8.0", 99 "psr\/container": "^1.0" 100 }, 101 "require-dev": { 102 "codeclimate\/php-test-reporter": "<=0.3.2", 103 "phpunit\/phpunit": "^7.0 | ^8.0 | ^9.0", 104 "slevomat\/coding-standard": "^6.0", 105 "vimeo\/psalm": "^4.0" 106 }, 107 "time": "2022-01-06T14:57:20+00:00", 108 "type": "library", 109 "installation-source": "dist", 110 "autoload": { 111 "psr-4": { 112 "Mollie\\Dhii\\Services\\": "src" 113 } 114 }, 115 "notification-url": "https:\/\/packagist.org\/downloads\/", 116 "license": [ 117 "MIT" 118 ], 119 "authors": [ 120 { 121 "name": "Dhii Team", 122 "email": "[email protected]" 123 } 124 ], 125 "description": "A collection of useful DI service implementations.", 126 "support": { 127 "issues": "https:\/\/github.com\/Dhii\/services\/issues", 128 "source": "https:\/\/github.com\/Dhii\/services\/tree\/v0.1.0" 129 }, 130 "install-path": "..\/dhii\/services" 81 131 }, 82 132 { … … 143 193 { 144 194 "name": "mollie\/mollie-api-php", 145 "version": "v2.76. 0",146 "version_normalized": "2.76. 0.0",195 "version": "v2.76.1", 196 "version_normalized": "2.76.1.0", 147 197 "source": { 148 198 "type": "git", 149 199 "url": "https:\/\/github.com\/mollie\/mollie-api-php.git", 150 "reference": " b6e9848e4893d1d306fba54da3ac6f4a31a40368"151 }, 152 "dist": { 153 "type": "zip", 154 "url": "https:\/\/api.github.com\/repos\/mollie\/mollie-api-php\/zipball\/ b6e9848e4893d1d306fba54da3ac6f4a31a40368",155 "reference": " b6e9848e4893d1d306fba54da3ac6f4a31a40368",200 "reference": "2a90a9224e6dcc25569e572edfe57ba75455e435" 201 }, 202 "dist": { 203 "type": "zip", 204 "url": "https:\/\/api.github.com\/repos\/mollie\/mollie-api-php\/zipball\/2a90a9224e6dcc25569e572edfe57ba75455e435", 205 "reference": "2a90a9224e6dcc25569e572edfe57ba75455e435", 156 206 "shasum": "" 157 207 }, … … 173 223 "mollie\/oauth2-mollie-php": "Use OAuth to authenticate with the Mollie API. This is needed for some endpoints. Visit https:\/\/docs.mollie.com\/ for more information." 174 224 }, 175 "time": "202 4-12-18T12:26:03+00:00",225 "time": "2025-01-24T14:59:44+00:00", 176 226 "type": "library", 177 227 "installation-source": "dist", … … 232 282 "support": { 233 283 "issues": "https:\/\/github.com\/mollie\/mollie-api-php\/issues", 234 "source": "https:\/\/github.com\/mollie\/mollie-api-php\/tree\/v2.76. 0"284 "source": "https:\/\/github.com\/mollie\/mollie-api-php\/tree\/v2.76.1" 235 285 }, 236 286 "install-path": "..\/mollie\/mollie-api-php" -
mollie-payments-for-woocommerce/trunk/vendor/composer/installed.php
r3242448 r3262577 3 3 namespace Mollie; 4 4 5 return array('root' => array('name' => 'mollie/mollie-woocommerce', 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', 'reference' => ' 4c05485f591d8cdba6a58fd5a9982b258649e4c2', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('composer/ca-bundle' => array('pretty_version' => '1.5.4', 'version' => '1.5.4.0', 'reference' => 'bc0593537a463e55cadf45fd938d23b75095b7e1', 'type' => 'library', 'install_path' => __DIR__ . '/./ca-bundle', 'aliases' => array(), 'dev_requirement' => \false), 'inpsyde/modularity' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'reference' => 'c79bb3682f55e1a2ece67f36e70d04fa2ab8c65d', 'type' => 'library', 'install_path' => __DIR__ . '/../inpsyde/modularity', 'aliases' => array(), 'dev_requirement' => \false), 'mollie/mollie-api-php' => array('pretty_version' => 'v2.76.0', 'version' => '2.76.0.0', 'reference' => 'b6e9848e4893d1d306fba54da3ac6f4a31a40368', 'type' => 'library', 'install_path' => __DIR__ . '/../mollie/mollie-api-php', 'aliases' => array(), 'dev_requirement' => \false), 'mollie/mollie-woocommerce' => array('pretty_version' => 'dev-develop', 'version' => 'dev-develop', 'reference' => '4c05485f591d8cdba6a58fd5a9982b258649e4c2', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'psr/container' => array('pretty_version' => '1.1.0', 'version' => '1.1.0.0', 'reference' => '9fc7aab7a78057a124384358ebae8a1711b6f6fc', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'dev_requirement' => \false), 'psr/log' => array('pretty_version' => '1.1.4', 'version' => '1.1.4.0', 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => \false), 'sniccowp/php-scoper-wordpress-excludes' => array('pretty_version' => '6.7.1', 'version' => '6.7.1.0', 'reference' => 'd8e6b5fdc9e42300a8ab18b44b775836a7b52363', 'type' => 'library', 'install_path' => __DIR__ . '/../sniccowp/php-scoper-wordpress-excludes', 'aliases' => array(), 'dev_requirement' => \false)));5 return array('root' => array('name' => 'mollie/mollie-woocommerce', 'pretty_version' => 'dev-develop', 'version' => 'dev-develop', 'reference' => 'f04128ceada3f2294561dce9cc3caa9722c4fbb1', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('composer/ca-bundle' => array('pretty_version' => '1.5.5', 'version' => '1.5.5.0', 'reference' => '08c50d5ec4c6ced7d0271d2862dec8c1033283e6', 'type' => 'library', 'install_path' => __DIR__ . '/./ca-bundle', 'aliases' => array(), 'dev_requirement' => \false), 'dhii/services' => array('pretty_version' => 'v0.1.0', 'version' => '0.1.0.0', 'reference' => '09cad8199a59d2003ad19126213075aefecaf17b', 'type' => 'library', 'install_path' => __DIR__ . '/../dhii/services', 'aliases' => array(), 'dev_requirement' => \false), 'inpsyde/modularity' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'reference' => 'c79bb3682f55e1a2ece67f36e70d04fa2ab8c65d', 'type' => 'library', 'install_path' => __DIR__ . '/../inpsyde/modularity', 'aliases' => array(), 'dev_requirement' => \false), 'mollie/mollie-api-php' => array('pretty_version' => 'v2.76.1', 'version' => '2.76.1.0', 'reference' => '2a90a9224e6dcc25569e572edfe57ba75455e435', 'type' => 'library', 'install_path' => __DIR__ . '/../mollie/mollie-api-php', 'aliases' => array(), 'dev_requirement' => \false), 'mollie/mollie-woocommerce' => array('pretty_version' => 'dev-develop', 'version' => 'dev-develop', 'reference' => 'f04128ceada3f2294561dce9cc3caa9722c4fbb1', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'psr/container' => array('pretty_version' => '1.1.0', 'version' => '1.1.0.0', 'reference' => '9fc7aab7a78057a124384358ebae8a1711b6f6fc', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'dev_requirement' => \false), 'psr/log' => array('pretty_version' => '1.1.4', 'version' => '1.1.4.0', 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => \false), 'sniccowp/php-scoper-wordpress-excludes' => array('pretty_version' => '6.7.1', 'version' => '6.7.1.0', 'reference' => 'd8e6b5fdc9e42300a8ab18b44b775836a7b52363', 'type' => 'library', 'install_path' => __DIR__ . '/../sniccowp/php-scoper-wordpress-excludes', 'aliases' => array(), 'dev_requirement' => \false))); -
mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/Endpoints/CustomerEndpoint.php
r3164004 r3262577 76 76 { 77 77 if (empty($customerId) || strpos($customerId, self::RESOURCE_ID_PREFIX) !== 0) { 78 throw new ApiException("Invalid order ID: '{$customerId}'. An order ID should start with '" . self::RESOURCE_ID_PREFIX . "'.");78 throw new ApiException("Invalid customer ID: '{$customerId}'. A customer ID should start with '" . self::RESOURCE_ID_PREFIX . "'."); 79 79 } 80 80 return parent::rest_update($customerId, $data); -
mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/Endpoints/ProfileEndpoint.php
r3164004 r3262577 82 82 { 83 83 if (empty($profileId) || strpos($profileId, self::RESOURCE_ID_PREFIX) !== 0) { 84 throw new ApiException("Invalid profile id: '{$profileId}'. An profile idshould start with '" . self::RESOURCE_ID_PREFIX . "'.");84 throw new ApiException("Invalid profile ID: '{$profileId}'. A profile ID should start with '" . self::RESOURCE_ID_PREFIX . "'."); 85 85 } 86 86 return parent::rest_update($profileId, $data); -
mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/Endpoints/ShipmentEndpoint.php
r3164004 r3262577 111 111 { 112 112 if (empty($shipmentId) || strpos($shipmentId, self::RESOURCE_ID_PREFIX) !== 0) { 113 throw new ApiException("Invalid s ubscription ID: '{$shipmentId}'. An subscriptionID should start with '" . self::RESOURCE_ID_PREFIX . "'.");113 throw new ApiException("Invalid shipment ID: '{$shipmentId}'. A shipment ID should start with '" . self::RESOURCE_ID_PREFIX . "'."); 114 114 } 115 115 $this->parentId = $orderId; -
mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/Endpoints/SubscriptionEndpoint.php
r3226701 r3262577 82 82 { 83 83 if (empty($subscriptionId) || strpos($subscriptionId, self::RESOURCE_ID_PREFIX) !== 0) { 84 throw new ApiException("Invalid subscription ID: '{$subscriptionId}'. A nsubscription ID should start with '" . self::RESOURCE_ID_PREFIX . "'.");84 throw new ApiException("Invalid subscription ID: '{$subscriptionId}'. A subscription ID should start with '" . self::RESOURCE_ID_PREFIX . "'."); 85 85 } 86 86 $this->parentId = $customerId; -
mollie-payments-for-woocommerce/trunk/vendor/mollie/mollie-api-php/src/MollieApiClient.php
r3226701 r3262577 55 55 * Version of our client. 56 56 */ 57 public const CLIENT_VERSION = "2.76. 0";57 public const CLIENT_VERSION = "2.76.1"; 58 58 /** 59 59 * Endpoint of the remote API.
Note: See TracChangeset
for help on using the changeset viewer.