Version Description
- Fix - Hide smart buttons for free products and zero-sum carts #499
- Fix - Unprocessable Entity when paying with AMEX card #516
- Fix - Multisite path doubled in ajax URLs #528
- Fix - "Place order" button looking unstyled in the Twenty Twenty-Two theme #478
- Fix - PayPal options available on minicart when adding subscription to the cart from shop page without vaulting enabled #518
- Fix - Buttons not visible on products page #551
- Fix - Buttons not visible in mini-cart #553
- Fix - PayPal button missing on pay for order page #555
- Enhancement - PayPal buttons loading time #533
- Enhancement - Improve payment token checking for subscriptions #525
- Enhancement - Add Spain and Italy to messaging #497
Download this release
Release Info
Developer | woothemes |
Plugin | WooCommerce PayPal Payments |
Version | 1.7.1 |
Comparing to | |
See all releases |
Code changes from version 1.7.0 to 1.7.1
- changelog.txt +13 -0
- modules/ppcp-api-client/src/Factory/ItemFactory.php +6 -6
- modules/ppcp-api-client/src/Repository/ApplicationContextRepository.php +1 -1
- modules/ppcp-button/assets/js/button.js +1 -1
- modules/ppcp-button/resources/js/button.js +53 -1
- modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js +10 -14
- modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js +3 -4
- modules/ppcp-button/resources/js/modules/ContextBootstrap/PayNowBootstrap.js +2 -2
- modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js +35 -5
- modules/ppcp-button/resources/js/modules/Helper/CheckoutMethodState.js +20 -0
- modules/ppcp-button/resources/js/modules/Helper/Spinner.js +2 -2
- modules/ppcp-button/resources/js/modules/Helper/Subscriptions.js +4 -0
- modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js +6 -2
- modules/ppcp-button/resources/js/modules/Renderer/Renderer.js +3 -1
- modules/ppcp-button/src/Assets/SmartButton.php +49 -27
- modules/ppcp-button/src/Helper/MessagesApply.php +2 -0
- modules/ppcp-button/src/Helper/MessagesDisclaimers.php +11 -5
- modules/ppcp-onboarding/src/Assets/OnboardingAssets.php +1 -1
- modules/ppcp-vaulting/services.php +10 -0
- modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php +1 -1
- modules/ppcp-vaulting/src/PaymentTokenChecker.php +227 -0
- modules/ppcp-vaulting/src/VaultingModule.php +10 -0
- modules/ppcp-wc-gateway/services.php +13 -2
- modules/ppcp-wc-gateway/src/Gateway/ProcessPaymentTrait.php +7 -89
- modules/ppcp-wc-gateway/src/Processor/AuthorizedPaymentsProcessor.php +59 -5
- modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php +16 -1
- modules/ppcp-webhooks/services.php +5 -0
- modules/ppcp-webhooks/src/Handler/RequestHandler.php +8 -5
- modules/ppcp-webhooks/src/Handler/VaultCreditCardCreated.php +87 -0
- modules/ppcp-webhooks/src/Handler/VaultPaymentTokenCreated.php +104 -0
- modules/ppcp-webhooks/src/Status/Assets/WebhooksStatusPageAssets.php +3 -3
- readme.txt +14 -1
- vendor/autoload.php +1 -1
- vendor/composer/autoload_real.php +7 -7
- vendor/composer/autoload_static.php +4 -4
- woocommerce-paypal-payments.php +2 -2
changelog.txt
CHANGED
@@ -1,5 +1,18 @@
|
|
1 |
*** Changelog ***
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
= 1.7.0 - 2022-02-28 =
|
4 |
* Fix - DCC orders randomly failing #503
|
5 |
* Fix - Multi-currency broke #481
|
1 |
*** Changelog ***
|
2 |
|
3 |
+
= 1.7.1 - 2022-04-06 =
|
4 |
+
* Fix - Hide smart buttons for free products and zero-sum carts #499
|
5 |
+
* Fix - Unprocessable Entity when paying with AMEX card #516
|
6 |
+
* Fix - Multisite path doubled in ajax URLs #528
|
7 |
+
* Fix - "Place order" button looking unstyled in the Twenty Twenty-Two theme #478
|
8 |
+
* Fix - PayPal options available on minicart when adding subscription to the cart from shop page without vaulting enabled #518
|
9 |
+
* Fix - Buttons not visible on products page #551
|
10 |
+
* Fix - Buttons not visible in mini-cart #553
|
11 |
+
* Fix - PayPal button missing on pay for order page #555
|
12 |
+
* Enhancement - PayPal buttons loading time #533
|
13 |
+
* Enhancement - Improve payment token checking for subscriptions #525
|
14 |
+
* Enhancement - Add Spain and Italy to messaging #497
|
15 |
+
|
16 |
= 1.7.0 - 2022-02-28 =
|
17 |
* Fix - DCC orders randomly failing #503
|
18 |
* Fix - Multi-currency broke #481
|
modules/ppcp-api-client/src/Factory/ItemFactory.php
CHANGED
@@ -9,6 +9,7 @@ declare(strict_types=1);
|
|
9 |
|
10 |
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
11 |
|
|
|
12 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
|
13 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
14 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
@@ -123,21 +124,20 @@ class ItemFactory {
|
|
123 |
* @return Item
|
124 |
*/
|
125 |
private function from_wc_order_line_item( \WC_Order_Item_Product $item, \WC_Order $order ): Item {
|
126 |
-
$currency = $order->get_currency();
|
127 |
-
$product = $item->get_product();
|
128 |
-
|
129 |
/**
|
130 |
* The WooCommerce product.
|
131 |
*
|
132 |
-
* @var
|
133 |
*/
|
134 |
-
$
|
135 |
-
|
|
|
136 |
$price = (float) $order->get_item_subtotal( $item, true );
|
137 |
$price_without_tax = (float) $order->get_item_subtotal( $item, false );
|
138 |
$price_without_tax_rounded = round( $price_without_tax, 2 );
|
139 |
$tax = round( $price - $price_without_tax_rounded, 2 );
|
140 |
$tax = new Money( $tax, $currency );
|
|
|
141 |
return new Item(
|
142 |
mb_substr( $product->get_name(), 0, 127 ),
|
143 |
new Money( $price_without_tax_rounded, $currency ),
|
9 |
|
10 |
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
|
11 |
|
12 |
+
use WC_Product;
|
13 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
|
14 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
124 |
* @return Item
|
125 |
*/
|
126 |
private function from_wc_order_line_item( \WC_Order_Item_Product $item, \WC_Order $order ): Item {
|
|
|
|
|
|
|
127 |
/**
|
128 |
* The WooCommerce product.
|
129 |
*
|
130 |
+
* @var WC_Product $product
|
131 |
*/
|
132 |
+
$product = $item->get_product();
|
133 |
+
$currency = $order->get_currency();
|
134 |
+
$quantity = (int) $item->get_quantity();
|
135 |
$price = (float) $order->get_item_subtotal( $item, true );
|
136 |
$price_without_tax = (float) $order->get_item_subtotal( $item, false );
|
137 |
$price_without_tax_rounded = round( $price_without_tax, 2 );
|
138 |
$tax = round( $price - $price_without_tax_rounded, 2 );
|
139 |
$tax = new Money( $tax, $currency );
|
140 |
+
|
141 |
return new Item(
|
142 |
mb_substr( $product->get_name(), 0, 127 ),
|
143 |
new Money( $price_without_tax_rounded, $currency ),
|
modules/ppcp-api-client/src/Repository/ApplicationContextRepository.php
CHANGED
@@ -50,7 +50,7 @@ class ApplicationContextRepository {
|
|
50 |
$landingpage = $this->settings->has( 'landing_page' ) ?
|
51 |
$this->settings->get( 'landing_page' ) : ApplicationContext::LANDING_PAGE_NO_PREFERENCE;
|
52 |
$context = new ApplicationContext(
|
53 |
-
(
|
54 |
(string) wc_get_checkout_url(),
|
55 |
(string) $brand_name,
|
56 |
$locale,
|
50 |
$landingpage = $this->settings->has( 'landing_page' ) ?
|
51 |
$this->settings->get( 'landing_page' ) : ApplicationContext::LANDING_PAGE_NO_PREFERENCE;
|
52 |
$context = new ApplicationContext(
|
53 |
+
network_home_url( \WC_AJAX::get_endpoint( ReturnUrlEndpoint::ENDPOINT ) ),
|
54 |
(string) wc_get_checkout_url(),
|
55 |
(string) $brand_name,
|
56 |
$locale,
|
modules/ppcp-button/assets/js/button.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
(()=>{"use strict";var __webpack_modules__={964:()=>{eval("\n;// CONCATENATED MODULE: ./resources/js/modules/ErrorHandler.js\nclass ErrorHandler {\n constructor(genericErrorText) {\n this.genericErrorText = genericErrorText;\n this.wrapper = document.querySelector('.woocommerce-notices-wrapper');\n this.messagesList = document.querySelector('ul.woocommerce-error');\n }\n\n genericError() {\n if (this.wrapper.classList.contains('ppcp-persist')) {\n return;\n }\n\n this.clear();\n this.message(this.genericErrorText);\n }\n\n appendPreparedErrorMessageElement(errorMessageElement) {\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n this.messagesList.replaceWith(errorMessageElement);\n }\n\n message(text, persist = false) {\n if (!typeof String || text.length === 0) {\n throw new Error('A new message text must be a non-empty string.');\n }\n\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n if (persist) {\n this.wrapper.classList.add('ppcp-persist');\n } else {\n this.wrapper.classList.remove('ppcp-persist');\n }\n\n let messageNode = this.prepareMessagesListItem(text);\n this.messagesList.appendChild(messageNode);\n jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'));\n }\n\n prepareMessagesList() {\n if (this.messagesList === null) {\n this.messagesList = document.createElement('ul');\n this.messagesList.setAttribute('class', 'woocommerce-error');\n this.messagesList.setAttribute('role', 'alert');\n this.wrapper.appendChild(this.messagesList);\n }\n }\n\n prepareMessagesListItem(message) {\n const li = document.createElement('li');\n li.innerHTML = message;\n return li;\n }\n\n sanitize(text) {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = text;\n return textarea.value.replace('Error: ', '');\n }\n\n clear() {\n if (this.messagesList === null) {\n return;\n }\n\n this.messagesList.innerHTML = '';\n }\n\n}\n\n/* harmony default export */ const modules_ErrorHandler = (ErrorHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForContinue.js\nconst onApprove = (context, errorHandler) => {\n return (data, actions) => {\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID,\n funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CartActionHandler.js\n\n\n\nclass CartActionHandler {\n constructor(config, errorHandler) {\n this.config = config;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units: [],\n bn_code: bnCode,\n payer,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CartActionHandler = (CartActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/MiniCartBootstap.js\n\n\n\nclass MiniCartBootstap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.actionHandler = null;\n }\n\n init() {\n this.actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.render();\n jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.mini_cart_wrapper) !== null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.renderer.render(this.gateway.button.mini_cart_wrapper, this.gateway.hosted_fields.mini_cart_wrapper, this.actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_MiniCartBootstap = (MiniCartBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/UpdateCart.js\n\n\nclass UpdateCart {\n constructor(endpoint, nonce) {\n this.endpoint = endpoint;\n this.nonce = nonce;\n }\n /**\n *\n * @param onResolve\n * @param {Product[]} products\n * @returns {Promise<unknown>}\n */\n\n\n update(onResolve, products) {\n return new Promise((resolve, reject) => {\n fetch(this.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.nonce,\n products\n })\n }).then(result => {\n return result.json();\n }).then(result => {\n if (!result.success) {\n reject(result.data);\n return;\n }\n\n const resolved = onResolve(result.data);\n resolve(resolved);\n });\n });\n }\n\n}\n\n/* harmony default export */ const Helper_UpdateCart = (UpdateCart);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/ButtonsToggleListener.js\n/**\n * When you can't add something to the cart, the PayPal buttons should not show.\n * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.\n */\nclass ButtonsToggleListener {\n constructor(element, showCallback, hideCallback) {\n this.element = element;\n this.showCallback = showCallback;\n this.hideCallback = hideCallback;\n this.observer = null;\n }\n\n init() {\n const config = {\n attributes: true\n };\n\n const callback = () => {\n if (this.element.classList.contains('disabled')) {\n this.hideCallback();\n return;\n }\n\n this.showCallback();\n };\n\n this.observer = new MutationObserver(callback);\n this.observer.observe(this.element, config);\n callback();\n }\n\n disconnect() {\n this.observer.disconnect();\n }\n\n}\n\n/* harmony default export */ const Helper_ButtonsToggleListener = (ButtonsToggleListener);\n;// CONCATENATED MODULE: ./resources/js/modules/Entity/Product.js\nclass Product {\n constructor(id, quantity, variations) {\n this.id = id;\n this.quantity = quantity;\n this.variations = variations;\n }\n\n data() {\n return {\n id: this.id,\n quantity: this.quantity,\n variations: this.variations\n };\n }\n\n}\n\n/* harmony default export */ const Entity_Product = (Product);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/SingleProductActionHandler.js\n\n\n\n\n\nclass SingleProductActionHandler {\n constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler) {\n this.config = config;\n this.updateCart = updateCart;\n this.showButtonCallback = showButtonCallback;\n this.hideButtonCallback = hideButtonCallback;\n this.formElement = formElement;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n if (this.hasVariations()) {\n const observer = new Helper_ButtonsToggleListener(this.formElement.querySelector('.single_add_to_cart_button'), this.showButtonCallback, this.hideButtonCallback);\n observer.init();\n }\n\n return {\n createOrder: this.createOrder(),\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n createOrder() {\n var getProducts = null;\n\n if (!this.isGroupedProduct()) {\n getProducts = () => {\n const id = document.querySelector('[name=\"add-to-cart\"]').value;\n const qty = document.querySelector('[name=\"quantity\"]').value;\n const variations = this.variations();\n return [new Entity_Product(id, qty, variations)];\n };\n } else {\n getProducts = () => {\n const products = [];\n this.formElement.querySelectorAll('input[type=\"number\"]').forEach(element => {\n if (!element.value) {\n return;\n }\n\n const elementName = element.getAttribute('name').match(/quantity\\[([\\d]*)\\]/);\n\n if (elementName.length !== 2) {\n return;\n }\n\n const id = parseInt(elementName[1]);\n const quantity = parseInt(element.value);\n products.push(new Entity_Product(id, quantity, null));\n });\n return products;\n };\n }\n\n const createOrder = (data, actions) => {\n this.errorHandler.clear();\n\n const onResolve = purchase_units => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units,\n payer,\n bn_code: bnCode,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n const promise = this.updateCart.update(onResolve, getProducts());\n return promise;\n };\n\n return createOrder;\n }\n\n variations() {\n if (!this.hasVariations()) {\n return null;\n }\n\n const attributes = [...this.formElement.querySelectorAll(\"[name^='attribute_']\")].map(element => {\n return {\n value: element.value,\n name: element.name\n };\n });\n return attributes;\n }\n\n hasVariations() {\n return this.formElement.classList.contains('variations_form');\n }\n\n isGroupedProduct() {\n return this.formElement.classList.contains('grouped_form');\n }\n\n}\n\n/* harmony default export */ const ActionHandler_SingleProductActionHandler = (SingleProductActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/SingleProductBootstap.js\n\n\n\n\nclass SingleProductBootstap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n }\n\n init() {\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n return;\n }\n\n this.render();\n }\n\n shouldRender() {\n if (document.querySelector('form.cart') === null) {\n return false;\n }\n\n return true;\n }\n\n render() {\n const actionHandler = new ActionHandler_SingleProductActionHandler(this.gateway, new Helper_UpdateCart(this.gateway.ajax.change_cart.endpoint, this.gateway.ajax.change_cart.nonce), () => {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseInt(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n this.messages.renderWithAmount(amount);\n }, () => {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }, document.querySelector('form.cart'), new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_SingleProductBootstap = (SingleProductBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CartBootstap.js\n\n\n\nclass CartBootstrap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n }\n\n init() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.render();\n jQuery(document.body).on('updated_cart_totals updated_checkout', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n const actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const CartBootstap = (CartBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForPayNow.js\nconst onApproveForPayNow_onApprove = (context, errorHandler, spinner) => {\n return (data, actions) => {\n spinner.block();\n errorHandler.clear();\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID,\n funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\nclass CheckoutActionHandler {\n constructor(config, errorHandler, spinner) {\n this.config = config;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n }\n\n configuration() {\n const spinner = this.spinner;\n\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n const errorHandler = this.errorHandler;\n const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';\n const formValues = jQuery(formSelector).serialize();\n const createaccount = jQuery('#createaccount').is(\":checked\") ? true : false;\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n payer,\n bn_code: bnCode,\n context: this.config.context,\n order_id: this.config.order_id,\n form: formValues,\n createaccount: createaccount\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n spinner.unblock(); //handle both messages sent from Woocommerce (data.messages) and this plugin (data.data.message)\n\n if (typeof data.messages !== 'undefined') {\n const domParser = new DOMParser();\n errorHandler.appendPreparedErrorMessageElement(domParser.parseFromString(data.messages, 'text/html').querySelector('ul'));\n } else {\n errorHandler.clear();\n\n if (data.data.details.length > 0) {\n errorHandler.message(data.data.details.map(d => `${d.issue} ${d.description}`).join('<br/>'), true);\n } else {\n errorHandler.message(data.data.message, true);\n }\n }\n\n return;\n }\n\n const input = document.createElement('input');\n input.setAttribute('type', 'hidden');\n input.setAttribute('name', 'ppcp-resume-order');\n input.setAttribute('value', data.data.purchase_units[0].custom_id);\n document.querySelector(formSelector).append(input);\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForPayNow(this, this.errorHandler, this.spinner),\n onCancel: () => {\n spinner.unblock();\n },\n onError: () => {\n this.errorHandler.genericError();\n spinner.unblock();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CheckoutActionHandler = (CheckoutActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Hiding.js\nconst getElement = selectorOrElement => {\n if (typeof selectorOrElement === 'string') {\n return document.querySelector(selectorOrElement);\n }\n\n return selectorOrElement;\n};\n\nconst isVisible = element => {\n return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);\n};\nconst setVisible = (selectorOrElement, show, important = false) => {\n const element = getElement(selectorOrElement);\n\n if (!element) {\n return;\n }\n\n const currentValue = element.style.getPropertyValue('display');\n\n if (!show) {\n if (currentValue === 'none') {\n return;\n }\n\n element.style.setProperty('display', 'none', important ? 'important' : '');\n } else {\n if (currentValue === 'none') {\n element.style.removeProperty('display');\n } // still not visible (if something else added display: none in CSS)\n\n\n if (!isVisible(element)) {\n element.style.setProperty('display', 'block');\n }\n }\n};\nconst hide = (selectorOrElement, important = false) => {\n setVisible(selectorOrElement, false, important);\n};\nconst show = selectorOrElement => {\n setVisible(selectorOrElement, true);\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CheckoutBootstap.js\n\n\n\n\nclass CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n this.standardOrderButtonSelector = '#place_order';\n this.buttonChangeObserver = new MutationObserver(el => {\n this.updateUi();\n });\n }\n\n init() {\n this.render(); // Unselect saved card.\n // WC saves form values, so with our current UI it would be a bit weird\n // if the user paid with saved, then after some time tries to pay again,\n // but wants to enter a new card, and to do that they have to choose “Select payment” in the list.\n\n jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.updateUi();\n });\n jQuery(document).on('hosted_fields_loaded', () => {\n jQuery('#saved-credit-card').on('change', () => {\n this.updateUi();\n });\n });\n this.updateUi();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n this.buttonChangeObserver.observe(document.querySelector(this.standardOrderButtonSelector), {\n attributes: true\n });\n }\n\n updateUi() {\n const currentPaymentMethod = this.currentPaymentMethod();\n const isPaypal = currentPaymentMethod === 'ppcp-gateway';\n const isCard = currentPaymentMethod === 'ppcp-credit-card-gateway';\n const isSavedCard = isCard && this.isSavedCardSelected();\n const isNotOurGateway = !isPaypal && !isCard;\n setVisible(this.standardOrderButtonSelector, isNotOurGateway || isSavedCard, true);\n setVisible(this.gateway.button.wrapper, isPaypal);\n setVisible(this.gateway.messages.wrapper, isPaypal);\n setVisible(this.gateway.hosted_fields.wrapper, isCard && !isSavedCard);\n\n if (isPaypal) {\n this.messages.render();\n }\n\n if (isCard) {\n if (isSavedCard) {\n this.disableCreditCardFields();\n } else {\n this.enableCreditCardFields();\n }\n }\n }\n\n disableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", true);\n this.renderer.disableCreditCardFields();\n }\n\n enableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", false);\n this.renderer.enableCreditCardFields();\n }\n\n currentPaymentMethod() {\n return jQuery('input[name=\"payment_method\"]:checked').val();\n }\n\n isSavedCardSelected() {\n const savedCardList = jQuery('#saved-credit-card');\n return savedCardList.length && savedCardList.val() !== '';\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_CheckoutBootstap = (CheckoutBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/PayNowBootstrap.js\n\n\nclass PayNowBootstrap extends ContextBootstrap_CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n super(gateway, renderer, messages, spinner);\n }\n\n updateUi() {\n const urlParams = new URLSearchParams(window.location.search);\n\n if (urlParams.has('change_payment_method')) {\n return;\n }\n\n super.updateUi();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_PayNowBootstrap = (PayNowBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/Renderer.js\nclass Renderer {\n constructor(creditCardRenderer, defaultConfig, onSmartButtonClick) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n this.onSmartButtonClick = onSmartButtonClick;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig,\n onClick: this.onSmartButtonClick\n }).render(wrapper);\n }\n\n isAlreadyRendered(wrapper) {\n return document.querySelector(wrapper).hasChildNodes();\n }\n\n hideButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'none';\n return true;\n }\n\n showButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'block';\n return true;\n }\n\n disableCreditCardFields() {\n this.creditCardRenderer.disableFields();\n }\n\n enableCreditCardFields() {\n this.creditCardRenderer.enableFields();\n }\n\n}\n\n/* harmony default export */ const Renderer_Renderer = (Renderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/DccInputFactory.js\nconst dccInputFactory = original => {\n const styles = window.getComputedStyle(original);\n const newElement = document.createElement('span');\n newElement.setAttribute('id', original.id);\n Object.values(styles).forEach(prop => {\n if (!styles[prop] || !isNaN(prop)) {\n return;\n }\n\n newElement.style.setProperty(prop, '' + styles[prop]);\n });\n return newElement;\n};\n\n/* harmony default export */ const DccInputFactory = (dccInputFactory);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/CreditCardRenderer.js\n\n\nclass CreditCardRenderer {\n constructor(defaultConfig, errorHandler, spinner) {\n this.defaultConfig = defaultConfig;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n this.cardValid = false;\n this.formValid = false;\n this.currentHostedFieldsInstance = null;\n }\n\n render(wrapper, contextConfig) {\n if (this.defaultConfig.context !== 'checkout' && this.defaultConfig.context !== 'pay-now' || wrapper === null || document.querySelector(wrapper) === null) {\n return;\n }\n\n if (typeof paypal.HostedFields === 'undefined' || !paypal.HostedFields.isEligible()) {\n const wrapperElement = document.querySelector(wrapper);\n wrapperElement.parentNode.removeChild(wrapperElement);\n return;\n }\n\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.teardown().catch(err => console.error(`Hosted fields teardown error: ${err}`));\n this.currentHostedFieldsInstance = null;\n }\n\n const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');\n const oldDisplayStyle = gateWayBox.style.display;\n gateWayBox.style.display = 'block';\n const hideDccGateway = document.querySelector('#ppcp-hide-dcc');\n\n if (hideDccGateway) {\n hideDccGateway.parentNode.removeChild(hideDccGateway);\n }\n\n const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');\n const stylesRaw = window.getComputedStyle(cardNumberField);\n let styles = {};\n Object.values(stylesRaw).forEach(prop => {\n if (!stylesRaw[prop]) {\n return;\n }\n\n styles[prop] = '' + stylesRaw[prop];\n });\n const cardNumber = DccInputFactory(cardNumberField);\n cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);\n const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');\n const cardExpiry = DccInputFactory(cardExpiryField);\n cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);\n const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');\n const cardCode = DccInputFactory(cardCodeField);\n cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);\n gateWayBox.style.display = oldDisplayStyle;\n const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';\n\n if (this.defaultConfig.enforce_vault && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')) {\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);\n }\n\n paypal.HostedFields.render({\n createOrder: contextConfig.createOrder,\n styles: {\n 'input': styles\n },\n fields: {\n number: {\n selector: '#ppcp-credit-card-gateway-card-number',\n placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number\n },\n cvv: {\n selector: '#ppcp-credit-card-gateway-card-cvc',\n placeholder: this.defaultConfig.hosted_fields.labels.cvv\n },\n expirationDate: {\n selector: '#ppcp-credit-card-gateway-card-expiry',\n placeholder: this.defaultConfig.hosted_fields.labels.mm_yy\n }\n }\n }).then(hostedFields => {\n document.dispatchEvent(new CustomEvent(\"hosted_fields_loaded\"));\n this.currentHostedFieldsInstance = hostedFields;\n hostedFields.on('inputSubmitRequest', () => {\n this._submit(contextConfig);\n });\n hostedFields.on('cardTypeChange', event => {\n if (!event.cards.length) {\n this.cardValid = false;\n return;\n }\n\n const validCards = this.defaultConfig.hosted_fields.valid_cards;\n this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;\n });\n hostedFields.on('validityChange', event => {\n const formValid = Object.keys(event.fields).every(function (key) {\n return event.fields[key].isValid;\n });\n this.formValid = formValid;\n });\n\n if (document.querySelector(wrapper).getAttribute('data-ppcp-subscribed') !== true) {\n document.querySelector(wrapper + ' button').addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n document.querySelector(wrapper).setAttribute('data-ppcp-subscribed', true);\n }\n });\n document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener('click', () => {\n document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();\n });\n }\n\n disableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.setAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n enableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n _submit(contextConfig) {\n this.spinner.block();\n this.errorHandler.clear();\n\n if (this.formValid && this.cardValid) {\n const save_card = this.defaultConfig.save_card ? true : false;\n let vault = document.getElementById('ppcp-credit-card-vault') ? document.getElementById('ppcp-credit-card-vault').checked : save_card;\n\n if (this.defaultConfig.enforce_vault) {\n vault = true;\n }\n\n const contingency = this.defaultConfig.hosted_fields.contingency;\n const hostedFieldsData = {\n vault: vault\n };\n\n if (contingency !== 'NO_3D_SECURE') {\n hostedFieldsData.contingencies = [contingency];\n }\n\n if (this.defaultConfig.payer) {\n hostedFieldsData.cardholderName = this.defaultConfig.payer.name.given_name + ' ' + this.defaultConfig.payer.name.surname;\n }\n\n if (!hostedFieldsData.cardholderName) {\n const firstName = document.getElementById('billing_first_name') ? document.getElementById('billing_first_name').value : '';\n const lastName = document.getElementById('billing_last_name') ? document.getElementById('billing_last_name').value : '';\n\n if (!firstName || !lastName) {\n this.spinner.unblock();\n this.errorHandler.message(this.defaultConfig.hosted_fields.labels.cardholder_name_required);\n return;\n }\n\n hostedFieldsData.cardholderName = firstName + ' ' + lastName;\n }\n\n this.currentHostedFieldsInstance.submit(hostedFieldsData).then(payload => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n }).catch(err => {\n console.error(err);\n this.spinner.unblock();\n });\n } else {\n this.spinner.unblock();\n const message = !this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;\n this.errorHandler.message(message);\n }\n }\n\n}\n\n/* harmony default export */ const Renderer_CreditCardRenderer = (CreditCardRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/DataClientIdAttributeHandler.js\nconst storageKey = 'ppcp-data-client-id';\n\nconst validateToken = (token, user) => {\n if (!token) {\n return false;\n }\n\n if (token.user !== user) {\n return false;\n }\n\n const currentTime = new Date().getTime();\n const isExpired = currentTime >= token.expiration * 1000;\n return !isExpired;\n};\n\nconst storedTokenForUser = user => {\n const token = JSON.parse(sessionStorage.getItem(storageKey));\n\n if (validateToken(token, user)) {\n return token.token;\n }\n\n return null;\n};\n\nconst storeToken = token => {\n sessionStorage.setItem(storageKey, JSON.stringify(token));\n};\n\nconst dataClientIdAttributeHandler = (script, config) => {\n fetch(config.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: config.nonce\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n const isValid = validateToken(data, config.user);\n\n if (!isValid) {\n return;\n }\n\n storeToken(data);\n script.setAttribute('data-client-token', data.token);\n document.body.append(script);\n });\n};\n\n/* harmony default export */ const DataClientIdAttributeHandler = (dataClientIdAttributeHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/MessageRenderer.js\nclass MessageRenderer {\n constructor(config) {\n this.config = config;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n renderWithAmount(amount) {\n if (!this.shouldRender()) {\n return;\n }\n\n const newWrapper = document.createElement('div');\n newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));\n const sibling = document.querySelector(this.config.wrapper).nextSibling;\n document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));\n sibling.parentElement.insertBefore(newWrapper, sibling);\n paypal.Messages({\n amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n shouldRender() {\n if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined') {\n return false;\n }\n\n if (!document.querySelector(this.config.wrapper)) {\n return false;\n }\n\n return true;\n }\n\n}\n\n/* harmony default export */ const Renderer_MessageRenderer = (MessageRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Spinner.js\nclass Spinner {\n constructor() {\n this.target = 'form.woocommerce-checkout';\n }\n\n setTarget(target) {\n this.target = target;\n }\n\n block() {\n jQuery(this.target).block({\n message: null,\n overlayCSS: {\n background: '#fff',\n opacity: 0.6\n }\n });\n }\n\n unblock() {\n jQuery(this.target).unblock();\n }\n\n}\n\n/* harmony default export */ const Helper_Spinner = (Spinner);\n;// CONCATENATED MODULE: ./resources/js/button.js\n\n\n\n\n\n\n\n\n\n\n\n\nconst bootstrap = () => {\n const errorHandler = new modules_ErrorHandler(PayPalCommerceGateway.labels.error.generic);\n const spinner = new Helper_Spinner();\n const creditCardRenderer = new Renderer_CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);\n\n const onSmartButtonClick = data => {\n window.ppcpFundingSource = data.fundingSource;\n };\n\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick);\n const messageRenderer = new Renderer_MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n\n if (context === 'mini-cart' || context === 'product') {\n if (PayPalCommerceGateway.mini_cart_buttons_enabled === '1') {\n const miniCartBootstrap = new ContextBootstrap_MiniCartBootstap(PayPalCommerceGateway, renderer);\n miniCartBootstrap.init();\n }\n }\n\n if (context === 'product' && PayPalCommerceGateway.single_product_buttons_enabled === '1') {\n const singleProductBootstrap = new ContextBootstrap_SingleProductBootstap(PayPalCommerceGateway, renderer, messageRenderer);\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstap(PayPalCommerceGateway, renderer);\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new ContextBootstrap_CheckoutBootstap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now') {\n const payNowBootstrap = new ContextBootstrap_PayNowBootstrap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (!typeof PayPalCommerceGateway) {\n console.error('PayPal button could not be configured.');\n return;\n }\n\n if (PayPalCommerceGateway.context !== 'checkout' && PayPalCommerceGateway.data_client_id.user === 0 && PayPalCommerceGateway.data_client_id.has_subscriptions) {\n return;\n }\n\n const script = document.createElement('script');\n script.addEventListener('load', event => {\n bootstrap();\n });\n script.setAttribute('src', PayPalCommerceGateway.button.url);\n Object.entries(PayPalCommerceGateway.script_attributes).forEach(keyValue => {\n script.setAttribute(keyValue[0], keyValue[1]);\n });\n\n if (PayPalCommerceGateway.data_client_id.set_attribute) {\n DataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);\n return;\n }\n\n document.body.append(script);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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OFMsRUFBQUEsTUFBTSxDQUFDcEMsZ0JBQVAsQ0FBd0IsTUFBeEIsRUFBaUNWLEtBQUQsSUFBVztBQUN2QzZELElBQUFBLFNBQVM7QUFDWixHQUZEO0FBR0FmLEVBQUFBLE1BQU0sQ0FBQzdTLFlBQVAsQ0FBb0IsS0FBcEIsRUFBMkJ1QyxxQkFBcUIsQ0FBQ3NDLE1BQXRCLENBQTZCMlAsR0FBeEQ7QUFDQWpILEVBQUFBLE1BQU0sQ0FBQ2tILE9BQVAsQ0FBZWxTLHFCQUFxQixDQUFDbVMsaUJBQXJDLEVBQXdEMU4sT0FBeEQsQ0FDSzJOLFFBQUQsSUFBYztBQUNWOUIsSUFBQUEsTUFBTSxDQUFDN1MsWUFBUCxDQUFvQjJVLFFBQVEsQ0FBQyxDQUFELENBQTVCLEVBQWlDQSxRQUFRLENBQUMsQ0FBRCxDQUF6QztBQUNILEdBSEw7O0FBTUEsTUFBSXBTLHFCQUFxQixDQUFDK1IsY0FBdEIsQ0FBcUNNLGFBQXpDLEVBQXdEO0FBQ3BEaEMsSUFBQUEsNEJBQTRCLENBQUNDLE1BQUQsRUFBU3RRLHFCQUFxQixDQUFDK1IsY0FBL0IsQ0FBNUI7QUFDQTtBQUNIOztBQUVEL1YsRUFBQUEsUUFBUSxDQUFDMkMsSUFBVCxDQUFjc0ksTUFBZCxDQUFxQnFKLE1BQXJCO0FBQ0gsQ0FqQ0wiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRXJyb3JIYW5kbGVyLmpzP2U2NWEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanM/YzQ1NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1BheWVyRGF0YS5qcz8yYWYxIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyLmpzPzgyY2YiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcC5qcz9kNTUyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvVXBkYXRlQ2FydC5qcz9lNDIyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyLmpzP2UxOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0VudGl0eS9Qcm9kdWN0LmpzPzlmZmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIuanM/ZDliNyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAuanM/N2MxOSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAuanM/NWU5NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanM/OTMwNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXIuanM/ODUxNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0hpZGluZy5qcz8xZDM2Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAuanM/Yzg1NSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9QYXlOb3dCb290c3RyYXAuanM/ZDlmNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvUmVuZGVyZXIuanM/ZmE5MyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0RjY0lucHV0RmFjdG9yeS5qcz8yYTJmIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9DcmVkaXRDYXJkUmVuZGVyZXIuanM/Mzg3YSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlci5qcz9lZTBiIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXIuanM/Y2QwMiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1NwaW5uZXIuanM/MTcwOCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL2J1dHRvbi5qcz8wNjBmIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEVycm9ySGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3RvcihnZW5lcmljRXJyb3JUZXh0KVxuICAgIHtcbiAgICAgICAgdGhpcy5nZW5lcmljRXJyb3JUZXh0ID0gZ2VuZXJpY0Vycm9yVGV4dDtcbiAgICAgICAgdGhpcy53cmFwcGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLndvb2NvbW1lcmNlLW5vdGljZXMtd3JhcHBlcicpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3VsLndvb2NvbW1lcmNlLWVycm9yJyk7XG4gICAgfVxuXG4gICAgZ2VuZXJpY0Vycm9yKCkge1xuICAgICAgICBpZiAodGhpcy53cmFwcGVyLmNsYXNzTGlzdC5jb250YWlucygncHBjcC1wZXJzaXN0JykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMubWVzc2FnZSh0aGlzLmdlbmVyaWNFcnJvclRleHQpXG4gICAgfVxuXG4gICAgYXBwZW5kUHJlcGFyZWRFcnJvck1lc3NhZ2VFbGVtZW50KGVycm9yTWVzc2FnZUVsZW1lbnQpXG4gICAge1xuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlTWVzc2FnZXNMaXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5yZXBsYWNlV2l0aChlcnJvck1lc3NhZ2VFbGVtZW50KTtcbiAgICB9XG5cbiAgICBtZXNzYWdlKHRleHQsIHBlcnNpc3QgPSBmYWxzZSlcbiAgICB7XG4gICAgICAgIGlmKCEgdHlwZW9mIFN0cmluZyB8fCB0ZXh0Lmxlbmd0aCA9PT0gMCl7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgbmV3IG1lc3NhZ2UgdGV4dCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKXtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBlcnNpc3QpIHtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QuYWRkKCdwcGNwLXBlcnNpc3QnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QucmVtb3ZlKCdwcGNwLXBlcnNpc3QnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBtZXNzYWdlTm9kZSA9IHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0odGV4dCk7XG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LmFwcGVuZENoaWxkKG1lc3NhZ2VOb2RlKTtcblxuICAgICAgICBqUXVlcnkuc2Nyb2xsX3RvX25vdGljZXMoalF1ZXJ5KCcud29vY29tbWVyY2Utbm90aWNlcy13cmFwcGVyJykpXG4gICAgfVxuXG4gICAgcHJlcGFyZU1lc3NhZ2VzTGlzdCgpXG4gICAge1xuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCl7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3VsJyk7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3dvb2NvbW1lcmNlLWVycm9yJyk7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnYWxlcnQnKTtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlci5hcHBlbmRDaGlsZCh0aGlzLm1lc3NhZ2VzTGlzdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcmVwYXJlTWVzc2FnZXNMaXN0SXRlbShtZXNzYWdlKVxuICAgIHtcbiAgICAgICAgY29uc3QgbGkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpO1xuICAgICAgICBsaS5pbm5lckhUTUwgPSBtZXNzYWdlO1xuXG4gICAgICAgIHJldHVybiBsaTtcbiAgICB9XG5cbiAgICBzYW5pdGl6ZSh0ZXh0KVxuICAgIHtcbiAgICAgICAgY29uc3QgdGV4dGFyZWEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xuICAgICAgICB0ZXh0YXJlYS5pbm5lckhUTUwgPSB0ZXh0O1xuICAgICAgICByZXR1cm4gdGV4dGFyZWEudmFsdWUucmVwbGFjZSgnRXJyb3I6ICcsICcnKTtcbiAgICB9XG5cbiAgICBjbGVhcigpXG4gICAge1xuICAgICAgICBpZiAodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LmlubmVySFRNTCA9ICcnO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXJyb3JIYW5kbGVyO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICByZXR1cm4gZmV0Y2goY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICBub25jZTogY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgIG9yZGVyX2lkOmRhdGEub3JkZXJJRCxcbiAgICAgICAgICAgICAgICBmdW5kaW5nX3NvdXJjZTogd2luZG93LnBwY3BGdW5kaW5nU291cmNlLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgIH0pLnRoZW4oKGRhdGEpPT57XG4gICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5yZXN0YXJ0KCkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGNvbnRleHQuY29uZmlnLnJlZGlyZWN0O1xuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiZXhwb3J0IGNvbnN0IHBheWVyRGF0YSA9ICgpID0+IHtcbiAgICBjb25zdCBwYXllciA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5wYXllcjtcbiAgICBpZiAoISBwYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwaG9uZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpIHx8IHR5cGVvZiBwYXllci5waG9uZSAhPT0gJ3VuZGVmaW5lZCcpID9cbiAgICB7XG4gICAgICAgIHBob25lX3R5cGU6XCJIT01FXCIsXG4gICAgICAgICAgICBwaG9uZV9udW1iZXI6e1xuICAgICAgICAgICAgbmF0aW9uYWxfbnVtYmVyIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKS52YWx1ZSA6IHBheWVyLnBob25lLnBob25lX251bWJlci5uYXRpb25hbF9udW1iZXJcbiAgICAgICAgfVxuICAgIH0gOiBudWxsO1xuICAgIGNvbnN0IHBheWVyRGF0YSA9IHtcbiAgICAgICAgZW1haWxfYWRkcmVzczooZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpLnZhbHVlIDogcGF5ZXIuZW1haWxfYWRkcmVzcyxcbiAgICAgICAgbmFtZSA6IHtcbiAgICAgICAgICAgIHN1cm5hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuc3VybmFtZSxcbiAgICAgICAgICAgIGdpdmVuX25hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5naXZlbl9uYW1lXG4gICAgICAgIH0sXG4gICAgICAgIGFkZHJlc3MgOiB7XG4gICAgICAgICAgICBjb3VudHJ5X2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuY291bnRyeV9jb2RlLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8xLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8yLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8xLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMixcbiAgICAgICAgICAgIHBvc3RhbF9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MucG9zdGFsX2NvZGVcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAocGhvbmUpIHtcbiAgICAgICAgcGF5ZXJEYXRhLnBob25lID0gcGhvbmU7XG4gICAgfVxuICAgIHJldHVybiBwYXllckRhdGE7XG59XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENhcnRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOiBvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIpLFxuICAgICAgICAgICAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgTWluaUNhcnRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbignd2NfZnJhZ21lbnRzX2xvYWRlZCB3Y19mcmFnbWVudHNfcmVmcmVzaGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcikgIT09XG4gICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKVxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWluaUNhcnRCb290c3RhcDsiLCJpbXBvcnQgUHJvZHVjdCBmcm9tIFwiLi4vRW50aXR5L1Byb2R1Y3RcIjtcbmNsYXNzIFVwZGF0ZUNhcnQge1xuXG4gICAgY29uc3RydWN0b3IoZW5kcG9pbnQsIG5vbmNlKVxuICAgIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludCA9IGVuZHBvaW50O1xuICAgICAgICB0aGlzLm5vbmNlID0gbm9uY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb25SZXNvbHZlXG4gICAgICogQHBhcmFtIHtQcm9kdWN0W119IHByb2R1Y3RzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAgICovXG4gICAgdXBkYXRlKG9uUmVzb2x2ZSwgcHJvZHVjdHMpXG4gICAge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgZmV0Y2goXG4gICAgICAgICAgICAgICAgdGhpcy5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICkudGhlbihcbiAgICAgICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qc29uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISByZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkID0gb25SZXNvbHZlKHJlc3VsdC5kYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXNvbHZlZCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVcGRhdGVDYXJ0OyIsIi8qKlxuICogV2hlbiB5b3UgY2FuJ3QgYWRkIHNvbWV0aGluZyB0byB0aGUgY2FydCwgdGhlIFBheVBhbCBidXR0b25zIHNob3VsZCBub3Qgc2hvdy5cbiAqIFRoZXJlZm9yZSB3ZSBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhlIGFkZCB0byBjYXJ0IGJ1dHRvbiBhbmQgc2hvdy9oaWRlIHRoZSBidXR0b25zIGFjY29yZGluZ2x5LlxuICovXG5cbmNsYXNzIEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciB7XG4gICAgY29uc3RydWN0b3IoZWxlbWVudCwgc2hvd0NhbGxiYWNrLCBoaWRlQ2FsbGJhY2spXG4gICAge1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgICAgICB0aGlzLnNob3dDYWxsYmFjayA9IHNob3dDYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2sgPSBoaWRlQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKVxuICAgIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0geyBhdHRyaWJ1dGVzIDogdHJ1ZSB9O1xuICAgICAgICBjb25zdCBjYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQ2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNob3dDYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihjYWxsYmFjayk7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIGNvbmZpZyk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuXG4gICAgZGlzY29ubmVjdCgpXG4gICAge1xuICAgICAgICB0aGlzLm9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcjsiLCJjbGFzcyBQcm9kdWN0IHtcblxuICAgIGNvbnN0cnVjdG9yKGlkLCBxdWFudGl0eSwgdmFyaWF0aW9ucykge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMucXVhbnRpdHkgPSBxdWFudGl0eTtcbiAgICAgICAgdGhpcy52YXJpYXRpb25zID0gdmFyaWF0aW9ucztcbiAgICB9XG5cbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaWQ6dGhpcy5pZCxcbiAgICAgICAgICAgIHF1YW50aXR5OnRoaXMucXVhbnRpdHksXG4gICAgICAgICAgICB2YXJpYXRpb25zOnRoaXMudmFyaWF0aW9uc1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQcm9kdWN0OyIsImltcG9ydCBCdXR0b25zVG9nZ2xlTGlzdGVuZXIgZnJvbSAnLi4vSGVscGVyL0J1dHRvbnNUb2dnbGVMaXN0ZW5lcic7XG5pbXBvcnQgUHJvZHVjdCBmcm9tICcuLi9FbnRpdHkvUHJvZHVjdCc7XG5pbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHVwZGF0ZUNhcnQsXG4gICAgICAgIHNob3dCdXR0b25DYWxsYmFjayxcbiAgICAgICAgaGlkZUJ1dHRvbkNhbGxiYWNrLFxuICAgICAgICBmb3JtRWxlbWVudCxcbiAgICAgICAgZXJyb3JIYW5kbGVyXG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLnVwZGF0ZUNhcnQgPSB1cGRhdGVDYXJ0O1xuICAgICAgICB0aGlzLnNob3dCdXR0b25DYWxsYmFjayA9IHNob3dCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2sgPSBoaWRlQnV0dG9uQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuZm9ybUVsZW1lbnQgPSBmb3JtRWxlbWVudDtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpXG4gICAge1xuXG4gICAgICAgIGlmICggdGhpcy5oYXNWYXJpYXRpb25zKCkgKSB7XG4gICAgICAgICAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBCdXR0b25zVG9nZ2xlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlX2FkZF90b19jYXJ0X2J1dHRvbicpLFxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUJ1dHRvbkNhbGxiYWNrXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuaW5pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiB0aGlzLmNyZWF0ZU9yZGVyKCksXG4gICAgICAgICAgICBvbkFwcHJvdmU6IG9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciksXG4gICAgICAgICAgICBvbkVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU9yZGVyKClcbiAgICB7XG4gICAgICAgIHZhciBnZXRQcm9kdWN0cyA9IG51bGw7XG4gICAgICAgIGlmICghIHRoaXMuaXNHcm91cGVkUHJvZHVjdCgpICkge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cImFkZC10by1jYXJ0XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgcXR5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW25hbWU9XCJxdWFudGl0eVwiXScpLnZhbHVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhdGlvbnMgPSB0aGlzLnZhcmlhdGlvbnMoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25ldyBQcm9kdWN0KGlkLCBxdHksIHZhcmlhdGlvbnMpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFByb2R1Y3RzID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RzID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwibnVtYmVyXCJdJykuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBlbGVtZW50LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbmFtZScpLm1hdGNoKC9xdWFudGl0eVxcWyhbXFxkXSopXFxdLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50TmFtZS5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IHBhcnNlSW50KGVsZW1lbnROYW1lWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBwYXJzZUludChlbGVtZW50LnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMucHVzaChuZXcgUHJvZHVjdChpZCwgcXVhbnRpdHksIG51bGwpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBwcm9kdWN0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICBjb25zdCBvblJlc29sdmUgPSAocHVyY2hhc2VfdW5pdHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHVyY2hhc2VfdW5pdHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YS5pZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLnVwZGF0ZUNhcnQudXBkYXRlKG9uUmVzb2x2ZSwgZ2V0UHJvZHVjdHMoKSk7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU9yZGVyO1xuICAgIH1cblxuICAgIHZhcmlhdGlvbnMoKVxuICAgIHtcblxuICAgICAgICBpZiAoISB0aGlzLmhhc1ZhcmlhdGlvbnMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IFsuLi50aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZV49J2F0dHJpYnV0ZV8nXVwiKV0ubWFwKFxuICAgICAgICAgICAgKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOmVsZW1lbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ZWxlbWVudC5uYW1lXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgICB9XG5cbiAgICBoYXNWYXJpYXRpb25zKClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygndmFyaWF0aW9uc19mb3JtJyk7XG4gICAgfVxuXG4gICAgaXNHcm91cGVkUHJvZHVjdCgpXG4gICAge1xuICAgICAgICByZXR1cm4gdGhpcy5mb3JtRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyb3VwZWRfZm9ybScpO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RBY3Rpb25IYW5kbGVyO1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhcnQgZnJvbSBcIi4uL0hlbHBlci9VcGRhdGVDYXJ0XCI7XG5pbXBvcnQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIgZnJvbSBcIi4uL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXJcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXksXG4gICAgICAgICAgICBuZXcgVXBkYXRlQ2FydChcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5lbmRwb2ludCxcbiAgICAgICAgICAgICAgICB0aGlzLmdhdGV3YXkuYWpheC5jaGFuZ2VfY2FydC5ub25jZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuc2hvd0J1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgbGV0IHByaWNlVGV4dCA9IFwiMFwiO1xuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlSW50KHByaWNlVGV4dC5yZXBsYWNlKC8oW15cXGQsXFwuXFxzXSopL2csICcnKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXJXaXRoQW1vdW50KGFtb3VudClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuaGlkZUJ1dHRvbnModGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JyksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTaW5nbGVQcm9kdWN0Qm9vdHN0YXA7IiwiaW1wb3J0IENhcnRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2FydEFjdGlvbkhhbmRsZXInO1xuaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuXG5jbGFzcyBDYXJ0Qm9vdHN0cmFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jYXJ0X3RvdGFscyB1cGRhdGVkX2NoZWNrb3V0JywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PVxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkhhbmRsZXIgPSBuZXcgQ2FydEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW5kZXIoXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsXG4gICAgICAgICAgICB0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLFxuICAgICAgICAgICAgYWN0aW9uSGFuZGxlci5jb25maWd1cmF0aW9uKCksXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0Qm9vdHN0cmFwO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICBzcGlubmVyLmJsb2NrKCk7XG4gICAgICAgIGVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgIHJldHVybiBmZXRjaChjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgIG5vbmNlOiBjb250ZXh0LmNvbmZpZy5hamF4LmFwcHJvdmVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgb3JkZXJfaWQ6ZGF0YS5vcmRlcklELFxuICAgICAgICAgICAgICAgIGZ1bmRpbmdfc291cmNlOiB3aW5kb3cucHBjcEZ1bmRpbmdTb3VyY2UsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KS50aGVuKChyZXMpPT57XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICAgICAgfSkudGhlbigoZGF0YSk9PntcbiAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmNvZGUgPT09IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFjdGlvbnMgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBhY3Rpb25zLnJlc3RhcnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb25zLnJlc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwbGFjZV9vcmRlcicpLmNsaWNrKClcbiAgICAgICAgfSk7XG5cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG9uQXBwcm92ZTtcbiIsImltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENoZWNrb3V0QWN0aW9uSGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgfVxuXG4gICAgY29uZmlndXJhdGlvbigpIHtcbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IHRoaXMuc3Bpbm5lcjtcbiAgICAgICAgY29uc3QgY3JlYXRlT3JkZXIgPSAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGF5ZXIgPSBwYXllckRhdGEoKTtcbiAgICAgICAgICAgIGNvbnN0IGJuQ29kZSA9IHR5cGVvZiB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IHRoaXMuZXJyb3JIYW5kbGVyO1xuXG4gICAgICAgICAgICBjb25zdCBmb3JtU2VsZWN0b3IgPSB0aGlzLmNvbmZpZy5jb250ZXh0ID09PSAnY2hlY2tvdXQnID8gJ2Zvcm0uY2hlY2tvdXQnIDogJ2Zvcm0jb3JkZXJfcmV2aWV3JztcbiAgICAgICAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSBqUXVlcnkoZm9ybVNlbGVjdG9yKS5zZXJpYWxpemUoKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlYWNjb3VudCA9IGpRdWVyeSgnI2NyZWF0ZWFjY291bnQnKS5pcyhcIjpjaGVja2VkXCIpID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgICAgICByZXR1cm4gZmV0Y2godGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIuZW5kcG9pbnQsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgcGF5ZXIsXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyX2lkOnRoaXMuY29uZmlnLm9yZGVyX2lkLFxuICAgICAgICAgICAgICAgICAgICBmb3JtOmZvcm1WYWx1ZXMsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWFjY291bnQ6IGNyZWF0ZWFjY291bnRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vaGFuZGxlIGJvdGggbWVzc2FnZXMgc2VudCBmcm9tIFdvb2NvbW1lcmNlIChkYXRhLm1lc3NhZ2VzKSBhbmQgdGhpcyBwbHVnaW4gKGRhdGEuZGF0YS5tZXNzYWdlKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mKGRhdGEubWVzc2FnZXMpICE9PSAndW5kZWZpbmVkJyApXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5hcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyhkYXRhLm1lc3NhZ2VzLCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnF1ZXJ5U2VsZWN0b3IoJ3VsJylcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmRhdGEuZGV0YWlscy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLm1lc3NhZ2UoZGF0YS5kYXRhLmRldGFpbHMubWFwKGQgPT4gYCR7ZC5pc3N1ZX0gJHtkLmRlc2NyaXB0aW9ufWApLmpvaW4oJzxici8+JyksIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIubWVzc2FnZShkYXRhLmRhdGEubWVzc2FnZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnaGlkZGVuJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCduYW1lJywgJ3BwY3AtcmVzdW1lLW9yZGVyJyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd2YWx1ZScsIGRhdGEuZGF0YS5wdXJjaGFzZV91bml0c1swXS5jdXN0b21faWQpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVNlbGVjdG9yKS5hcHBlbmQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGEuaWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXIsXG4gICAgICAgICAgICBvbkFwcHJvdmU6b25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyLCB0aGlzLnNwaW5uZXIpLFxuICAgICAgICAgICAgb25DYW5jZWw6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0QWN0aW9uSGFuZGxlcjtcbiIsImNvbnN0IGdldEVsZW1lbnQgPSAoc2VsZWN0b3JPckVsZW1lbnQpID0+IHtcbiAgICBpZiAodHlwZW9mIHNlbGVjdG9yT3JFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3Rvck9yRWxlbWVudCk7XG4gICAgfVxuICAgIHJldHVybiBzZWxlY3Rvck9yRWxlbWVudDtcbn1cblxuZXhwb3J0IGNvbnN0IGlzVmlzaWJsZSA9IChlbGVtZW50KSA9PiB7XG4gICAgcmV0dXJuICEhKGVsZW1lbnQub2Zmc2V0V2lkdGggfHwgZWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgZWxlbWVudC5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCk7XG59XG5cbmV4cG9ydCBjb25zdCBzZXRWaXNpYmxlID0gKHNlbGVjdG9yT3JFbGVtZW50LCBzaG93LCBpbXBvcnRhbnQgPSBmYWxzZSkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBnZXRFbGVtZW50KHNlbGVjdG9yT3JFbGVtZW50KTtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGVsZW1lbnQuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgnZGlzcGxheScpO1xuXG4gICAgaWYgKCFzaG93KSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPT09ICdub25lJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnZGlzcGxheScsICdub25lJywgaW1wb3J0YW50ID8gJ2ltcG9ydGFudCcgOiAnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA9PT0gJ25vbmUnKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnJlbW92ZVByb3BlcnR5KCdkaXNwbGF5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzdGlsbCBub3QgdmlzaWJsZSAoaWYgc29tZXRoaW5nIGVsc2UgYWRkZWQgZGlzcGxheTogbm9uZSBpbiBDU1MpXG4gICAgICAgIGlmICghaXNWaXNpYmxlKGVsZW1lbnQpKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCdkaXNwbGF5JywgJ2Jsb2NrJyk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5leHBvcnQgY29uc3QgaGlkZSA9IChzZWxlY3Rvck9yRWxlbWVudCwgaW1wb3J0YW50ID0gZmFsc2UpID0+IHtcbiAgICBzZXRWaXNpYmxlKHNlbGVjdG9yT3JFbGVtZW50LCBmYWxzZSwgaW1wb3J0YW50KTtcbn07XG5cbmV4cG9ydCBjb25zdCBzaG93ID0gKHNlbGVjdG9yT3JFbGVtZW50KSA9PiB7XG4gICAgc2V0VmlzaWJsZShzZWxlY3Rvck9yRWxlbWVudCwgdHJ1ZSk7XG59O1xuIiwiaW1wb3J0IEVycm9ySGFuZGxlciBmcm9tICcuLi9FcnJvckhhbmRsZXInO1xuaW1wb3J0IENoZWNrb3V0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NoZWNrb3V0QWN0aW9uSGFuZGxlcic7XG5pbXBvcnQgeyBzZXRWaXNpYmxlIH0gZnJvbSAnLi4vSGVscGVyL0hpZGluZyc7XG5cbmNsYXNzIENoZWNrb3V0Qm9vdHN0YXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcywgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlcztcbiAgICAgICAgdGhpcy5zcGlubmVyID0gc3Bpbm5lcjtcblxuICAgICAgICB0aGlzLnN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciA9ICcjcGxhY2Vfb3JkZXInO1xuXG4gICAgICAgIHRoaXMuYnV0dG9uQ2hhbmdlT2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoZWwpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgICAgICAvLyBVbnNlbGVjdCBzYXZlZCBjYXJkLlxuICAgICAgICAvLyBXQyBzYXZlcyBmb3JtIHZhbHVlcywgc28gd2l0aCBvdXIgY3VycmVudCBVSSBpdCB3b3VsZCBiZSBhIGJpdCB3ZWlyZFxuICAgICAgICAvLyBpZiB0aGUgdXNlciBwYWlkIHdpdGggc2F2ZWQsIHRoZW4gYWZ0ZXIgc29tZSB0aW1lIHRyaWVzIHRvIHBheSBhZ2FpbixcbiAgICAgICAgLy8gYnV0IHdhbnRzIHRvIGVudGVyIGEgbmV3IGNhcmQsIGFuZCB0byBkbyB0aGF0IHRoZXkgaGF2ZSB0byBjaG9vc2Ug4oCcU2VsZWN0IHBheW1lbnTigJ0gaW4gdGhlIGxpc3QuXG4gICAgICAgIGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkJykudmFsKGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkIG9wdGlvbjpmaXJzdCcpLnZhbCgpKTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3VwZGF0ZWRfY2hlY2tvdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCBwYXltZW50X21ldGhvZF9zZWxlY3RlZCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVWkoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50KS5vbignaG9zdGVkX2ZpZWxkc19sb2FkZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBqUXVlcnkoJyNzYXZlZC1jcmVkaXQtY2FyZCcpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi5jYW5jZWxfd3JhcHBlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcikgIT09IG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKSAhPT0gbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGlmICghdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIgKyAnPmRpdicpKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIgKyAnPmRpdicpLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYWN0aW9uSGFuZGxlciA9IG5ldyBDaGVja291dEFjdGlvbkhhbmRsZXIoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICBuZXcgRXJyb3JIYW5kbGVyKHRoaXMuZ2F0ZXdheS5sYWJlbHMuZXJyb3IuZ2VuZXJpYyksXG4gICAgICAgICAgICB0aGlzLnNwaW5uZXJcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsXG4gICAgICAgICAgICBhY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmJ1dHRvbkNoYW5nZU9ic2VydmVyLm9ic2VydmUoXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuc3RhbmRhcmRPcmRlckJ1dHRvblNlbGVjdG9yKSxcbiAgICAgICAgICAgIHthdHRyaWJ1dGVzOiB0cnVlfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHVwZGF0ZVVpKCkge1xuICAgICAgICBjb25zdCBjdXJyZW50UGF5bWVudE1ldGhvZCA9IHRoaXMuY3VycmVudFBheW1lbnRNZXRob2QoKTtcbiAgICAgICAgY29uc3QgaXNQYXlwYWwgPSBjdXJyZW50UGF5bWVudE1ldGhvZCA9PT0gJ3BwY3AtZ2F0ZXdheSc7XG4gICAgICAgIGNvbnN0IGlzQ2FyZCA9IGN1cnJlbnRQYXltZW50TWV0aG9kID09PSAncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JztcbiAgICAgICAgY29uc3QgaXNTYXZlZENhcmQgPSBpc0NhcmQgJiYgdGhpcy5pc1NhdmVkQ2FyZFNlbGVjdGVkKCk7XG4gICAgICAgIGNvbnN0IGlzTm90T3VyR2F0ZXdheSA9ICFpc1BheXBhbCAmJiAhaXNDYXJkO1xuXG4gICAgICAgIHNldFZpc2libGUodGhpcy5zdGFuZGFyZE9yZGVyQnV0dG9uU2VsZWN0b3IsIGlzTm90T3VyR2F0ZXdheSB8fCBpc1NhdmVkQ2FyZCwgdHJ1ZSk7XG4gICAgICAgIHNldFZpc2libGUodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLCBpc1BheXBhbCk7XG4gICAgICAgIHNldFZpc2libGUodGhpcy5nYXRld2F5Lm1lc3NhZ2VzLndyYXBwZXIsIGlzUGF5cGFsKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyLCBpc0NhcmQgJiYgIWlzU2F2ZWRDYXJkKTtcblxuICAgICAgICBpZiAoaXNQYXlwYWwpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucmVuZGVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNDYXJkKSB7XG4gICAgICAgICAgICBpZiAoaXNTYXZlZENhcmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCB0cnVlKVxuICAgICAgICB0aGlzLnJlbmRlcmVyLmRpc2FibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG5cbiAgICBlbmFibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlclwiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmNcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInZhdWx0XCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hdHRyKFwiZGlzYWJsZWRcIiwgZmFsc2UpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpXG4gICAgfVxuXG4gICAgY3VycmVudFBheW1lbnRNZXRob2QoKSB7XG4gICAgICAgIHJldHVybiBqUXVlcnkoJ2lucHV0W25hbWU9XCJwYXltZW50X21ldGhvZFwiXTpjaGVja2VkJykudmFsKCk7XG4gICAgfVxuXG4gICAgaXNTYXZlZENhcmRTZWxlY3RlZCgpIHtcbiAgICAgICAgY29uc3Qgc2F2ZWRDYXJkTGlzdCA9IGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkJyk7XG4gICAgICAgIHJldHVybiBzYXZlZENhcmRMaXN0Lmxlbmd0aCAmJiBzYXZlZENhcmRMaXN0LnZhbCgpICE9PSAnJztcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0Qm9vdHN0YXBcbiIsImltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vQ2hlY2tvdXRCb290c3RhcCdcblxuY2xhc3MgUGF5Tm93Qm9vdHN0cmFwIGV4dGVuZHMgQ2hlY2tvdXRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIsIG1lc3NhZ2VzLCBzcGlubmVyKSB7XG4gICAgICAgIHN1cGVyKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcywgc3Bpbm5lcilcbiAgICB9XG5cbiAgICB1cGRhdGVVaSgpIHtcbiAgICAgICAgY29uc3QgdXJsUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKVxuICAgICAgICBpZiAodXJsUGFyYW1zLmhhcygnY2hhbmdlX3BheW1lbnRfbWV0aG9kJykpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgc3VwZXIudXBkYXRlVWkoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBheU5vd0Jvb3RzdHJhcDtcbiIsImNsYXNzIFJlbmRlcmVyIHtcbiAgICBjb25zdHJ1Y3RvcihjcmVkaXRDYXJkUmVuZGVyZXIsIGRlZmF1bHRDb25maWcsIG9uU21hcnRCdXR0b25DbGljaykge1xuICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcgPSBkZWZhdWx0Q29uZmlnO1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlciA9IGNyZWRpdENhcmRSZW5kZXJlcjtcbiAgICAgICAgdGhpcy5vblNtYXJ0QnV0dG9uQ2xpY2sgPSBvblNtYXJ0QnV0dG9uQ2xpY2s7XG4gICAgfVxuXG4gICAgcmVuZGVyKHdyYXBwZXIsIGhvc3RlZEZpZWxkc1dyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcblxuICAgICAgICB0aGlzLnJlbmRlckJ1dHRvbnMod3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLnJlbmRlcihob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKTtcbiAgICB9XG5cbiAgICByZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpIHtcbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSB8fCB0aGlzLmlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHx8ICd1bmRlZmluZWQnID09PSB0eXBlb2YgcGF5cGFsLkJ1dHRvbnMgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdHlsZSA9IHdyYXBwZXIgPT09IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24ud3JhcHBlciA/IHRoaXMuZGVmYXVsdENvbmZpZy5idXR0b24uc3R5bGUgOiB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLm1pbmlfY2FydF9zdHlsZTtcbiAgICAgICAgcGF5cGFsLkJ1dHRvbnMoe1xuICAgICAgICAgICAgc3R5bGUsXG4gICAgICAgICAgICAuLi5jb250ZXh0Q29uZmlnLFxuICAgICAgICAgICAgb25DbGljazogdGhpcy5vblNtYXJ0QnV0dG9uQ2xpY2ssXG4gICAgICAgIH0pLnJlbmRlcih3cmFwcGVyKTtcbiAgICB9XG5cbiAgICBpc0FscmVhZHlSZW5kZXJlZCh3cmFwcGVyKSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpLmhhc0NoaWxkTm9kZXMoKTtcbiAgICB9XG5cbiAgICBoaWRlQnV0dG9ucyhlbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGRvbUVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsZW1lbnQpO1xuICAgICAgICBpZiAoISBkb21FbGVtZW50ICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGRvbUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgc2hvd0J1dHRvbnMoZWxlbWVudCkge1xuICAgICAgICBjb25zdCBkb21FbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgICAgICAgaWYgKCEgZG9tRWxlbWVudCApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBkb21FbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBkaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcygpIHtcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIuZGlzYWJsZUZpZWxkcygpO1xuICAgIH1cblxuICAgIGVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Q2FyZFJlbmRlcmVyLmVuYWJsZUZpZWxkcygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmVuZGVyZXI7XG4iLCJjb25zdCBkY2NJbnB1dEZhY3RvcnkgPSAob3JpZ2luYWwpID0+IHtcbiAgICBjb25zdCBzdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShvcmlnaW5hbCk7XG4gICAgY29uc3QgbmV3RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBuZXdFbGVtZW50LnNldEF0dHJpYnV0ZSgnaWQnLCBvcmlnaW5hbC5pZCk7XG4gICAgT2JqZWN0LnZhbHVlcyhzdHlsZXMpLmZvckVhY2goIChwcm9wKSA9PiB7XG4gICAgICAgIGlmICghIHN0eWxlc1twcm9wXSB8fCAhIGlzTmFOKHByb3ApICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIG5ld0VsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkocHJvcCwnJyArIHN0eWxlc1twcm9wXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ld0VsZW1lbnQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRjY0lucHV0RmFjdG9yeTsiLCJpbXBvcnQgZGNjSW5wdXRGYWN0b3J5IGZyb20gXCIuLi9IZWxwZXIvRGNjSW5wdXRGYWN0b3J5XCI7XG5cbmNsYXNzIENyZWRpdENhcmRSZW5kZXJlciB7XG5cbiAgICBjb25zdHJ1Y3RvcihkZWZhdWx0Q29uZmlnLCBlcnJvckhhbmRsZXIsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uZmlnID0gZGVmYXVsdENvbmZpZztcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIgPSBlcnJvckhhbmRsZXI7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG4gICAgICAgIHRoaXMuY2FyZFZhbGlkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZm9ybVZhbGlkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlID0gbnVsbDtcbiAgICB9XG5cbiAgICByZW5kZXIod3JhcHBlciwgY29udGV4dENvbmZpZykge1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcuY29udGV4dCAhPT0gJ2NoZWNrb3V0J1xuICAgICAgICAgICAgICAgICYmIHRoaXMuZGVmYXVsdENvbmZpZy5jb250ZXh0ICE9PSAncGF5LW5vdydcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIHx8IHdyYXBwZXIgPT09IG51bGxcbiAgICAgICAgICAgIHx8IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikgPT09IG51bGxcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdHlwZW9mIHBheXBhbC5Ib3N0ZWRGaWVsZHMgPT09ICd1bmRlZmluZWQnXG4gICAgICAgICAgICB8fCAhIHBheXBhbC5Ib3N0ZWRGaWVsZHMuaXNFbGlnaWJsZSgpXG4gICAgICAgICkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlckVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIpO1xuICAgICAgICAgICAgd3JhcHBlckVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh3cmFwcGVyRWxlbWVudCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnRlYXJkb3duKClcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoYEhvc3RlZCBmaWVsZHMgdGVhcmRvd24gZXJyb3I6ICR7ZXJyfWApKTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGdhdGVXYXlCb3ggPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGF5bWVudF9ib3gucGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5Jyk7XG4gICAgICAgIGNvbnN0IG9sZERpc3BsYXlTdHlsZSA9IGdhdGVXYXlCb3guc3R5bGUuZGlzcGxheTtcbiAgICAgICAgZ2F0ZVdheUJveC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblxuICAgICAgICBjb25zdCBoaWRlRGNjR2F0ZXdheSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWhpZGUtZGNjJyk7XG4gICAgICAgIGlmIChoaWRlRGNjR2F0ZXdheSkge1xuICAgICAgICAgICAgaGlkZURjY0dhdGV3YXkucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChoaWRlRGNjR2F0ZXdheSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjYXJkTnVtYmVyRmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJyk7XG5cbiAgICAgICAgY29uc3Qgc3R5bGVzUmF3ID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoY2FyZE51bWJlckZpZWxkKTtcbiAgICAgICAgbGV0IHN0eWxlcyA9IHt9O1xuICAgICAgICBPYmplY3QudmFsdWVzKHN0eWxlc1JhdykuZm9yRWFjaCggKHByb3ApID0+IHtcbiAgICAgICAgICAgIGlmICghIHN0eWxlc1Jhd1twcm9wXSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0eWxlc1twcm9wXSA9ICcnICsgc3R5bGVzUmF3W3Byb3BdO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBjYXJkTnVtYmVyID0gZGNjSW5wdXRGYWN0b3J5KGNhcmROdW1iZXJGaWVsZCk7XG4gICAgICAgIGNhcmROdW1iZXJGaWVsZC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjYXJkTnVtYmVyLCBjYXJkTnVtYmVyRmllbGQpO1xuXG4gICAgICAgIGNvbnN0IGNhcmRFeHBpcnlGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKTtcbiAgICAgICAgY29uc3QgY2FyZEV4cGlyeSA9IGRjY0lucHV0RmFjdG9yeShjYXJkRXhwaXJ5RmllbGQpO1xuICAgICAgICBjYXJkRXhwaXJ5RmllbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2FyZEV4cGlyeSwgY2FyZEV4cGlyeUZpZWxkKTtcblxuICAgICAgICBjb25zdCBjYXJkQ29kZUZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpO1xuICAgICAgICBjb25zdCBjYXJkQ29kZSA9IGRjY0lucHV0RmFjdG9yeShjYXJkQ29kZUZpZWxkKTtcbiAgICAgICAgY2FyZENvZGVGaWVsZC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjYXJkQ29kZSwgY2FyZENvZGVGaWVsZCk7XG5cbiAgICAgICAgZ2F0ZVdheUJveC5zdHlsZS5kaXNwbGF5ID0gb2xkRGlzcGxheVN0eWxlO1xuXG4gICAgICAgIGNvbnN0IGZvcm1XcmFwcGVyID0gJy5wYXltZW50X2JveCBwYXltZW50X21ldGhvZF9wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcuZW5mb3JjZV92YXVsdFxuICAgICAgICAgICAgJiYgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuY2hlY2tlZCA9IHRydWU7XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBwYXlwYWwuSG9zdGVkRmllbGRzLnJlbmRlcih7XG4gICAgICAgICAgICBjcmVhdGVPcmRlcjogY29udGV4dENvbmZpZy5jcmVhdGVPcmRlcixcbiAgICAgICAgICAgIHN0eWxlczoge1xuICAgICAgICAgICAgICAgICdpbnB1dCc6IHN0eWxlc1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZpZWxkczoge1xuICAgICAgICAgICAgICAgIG51bWJlcjoge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXInLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNyZWRpdF9jYXJkX251bWJlcixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGN2djoge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcjogJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1jdmMnLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmN2dixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGV4cGlyYXRpb25EYXRlOiB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yOiAnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeScsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMubW1feXksXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KS50aGVuKGhvc3RlZEZpZWxkcyA9PiB7XG4gICAgICAgICAgICBkb2N1bWVudC5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChcImhvc3RlZF9maWVsZHNfbG9hZGVkXCIpKTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlID0gaG9zdGVkRmllbGRzO1xuXG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ2lucHV0U3VibWl0UmVxdWVzdCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWJtaXQoY29udGV4dENvbmZpZyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbignY2FyZFR5cGVDaGFuZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoICEgZXZlbnQuY2FyZHMubGVuZ3RoICkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbGlkQ2FyZHMgPSB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy52YWxpZF9jYXJkcztcbiAgICAgICAgICAgICAgICB0aGlzLmNhcmRWYWxpZCA9IHZhbGlkQ2FyZHMuaW5kZXhPZihldmVudC5jYXJkc1swXS50eXBlKSAhPT0gLTE7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCd2YWxpZGl0eUNoYW5nZScsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1WYWxpZCA9IE9iamVjdC5rZXlzKGV2ZW50LmZpZWxkcykuZXZlcnkoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQuZmllbGRzW2tleV0uaXNWYWxpZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgIHRoaXMuZm9ybVZhbGlkID0gZm9ybVZhbGlkO1xuXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikuZ2V0QXR0cmlidXRlKCdkYXRhLXBwY3Atc3Vic2NyaWJlZCcpICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyICsgJyBidXR0b24nKS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAgICAgICAnY2xpY2snLFxuICAgICAgICAgICAgICAgICAgICBldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0KGNvbnRleHRDb25maWcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikuc2V0QXR0cmlidXRlKCdkYXRhLXBwY3Atc3Vic2NyaWJlZCcsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcGF5bWVudF9tZXRob2RfcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5JykuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbGFiZWxbZm9yPXBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcl0nKS5jbGljaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICApXG4gICAgfVxuXG4gICAgZGlzYWJsZUZpZWxkcygpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zZXRBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnbnVtYmVyJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zZXRBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnY3Z2JyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zZXRBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnZXhwaXJhdGlvbkRhdGUnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGVuYWJsZUZpZWxkcygpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5yZW1vdmVBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnbnVtYmVyJyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5yZW1vdmVBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnY3Z2JyxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGU6ICdkaXNhYmxlZCdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5yZW1vdmVBdHRyaWJ1dGUoe1xuICAgICAgICAgICAgICAgIGZpZWxkOiAnZXhwaXJhdGlvbkRhdGUnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9zdWJtaXQoY29udGV4dENvbmZpZykge1xuICAgICAgICB0aGlzLnNwaW5uZXIuYmxvY2soKTtcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuY2xlYXIoKTtcblxuICAgICAgICBpZiAodGhpcy5mb3JtVmFsaWQgJiYgdGhpcy5jYXJkVmFsaWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHNhdmVfY2FyZCA9IHRoaXMuZGVmYXVsdENvbmZpZy5zYXZlX2NhcmQgPyB0cnVlIDogZmFsc2U7XG4gICAgICAgICAgICBsZXQgdmF1bHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpID9cbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmNoZWNrZWQgOiBzYXZlX2NhcmQ7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0Q29uZmlnLmVuZm9yY2VfdmF1bHQpIHtcbiAgICAgICAgICAgICAgICB2YXVsdCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb250aW5nZW5jeSA9IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmNvbnRpbmdlbmN5O1xuICAgICAgICAgICAgY29uc3QgaG9zdGVkRmllbGRzRGF0YSA9IHtcbiAgICAgICAgICAgICAgICB2YXVsdDogdmF1bHRcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoY29udGluZ2VuY3kgIT09ICdOT18zRF9TRUNVUkUnKSB7XG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jb250aW5nZW5jaWVzID0gW2NvbnRpbmdlbmN5XTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbmZpZy5wYXllcikge1xuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY2FyZGhvbGRlck5hbWUgPSB0aGlzLmRlZmF1bHRDb25maWcucGF5ZXIubmFtZS5naXZlbl9uYW1lICsgJyAnICsgdGhpcy5kZWZhdWx0Q29uZmlnLnBheWVyLm5hbWUuc3VybmFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaG9zdGVkRmllbGRzRGF0YS5jYXJkaG9sZGVyTmFtZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0TmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2ZpcnN0X25hbWUnKSA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2ZpcnN0X25hbWUnKS52YWx1ZSA6ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxhc3ROYW1lID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JpbGxpbmdfbGFzdF9uYW1lJykgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6ICcnO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFmaXJzdE5hbWUgfHwgIWxhc3ROYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UodGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNhcmRob2xkZXJfbmFtZV9yZXF1aXJlZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBob3N0ZWRGaWVsZHNEYXRhLmNhcmRob2xkZXJOYW1lID0gZmlyc3ROYW1lICsgJyAnICsgbGFzdE5hbWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnN1Ym1pdChob3N0ZWRGaWVsZHNEYXRhKS50aGVuKChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgcGF5bG9hZC5vcmRlcklEID0gcGF5bG9hZC5vcmRlcklkO1xuICAgICAgICAgICAgICAgIHRoaXMuc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRDb25maWcub25BcHByb3ZlKHBheWxvYWQpO1xuICAgICAgICAgICAgfSkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSAhIHRoaXMuY2FyZFZhbGlkID8gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNhcmRfbm90X3N1cHBvcnRlZCA6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5maWVsZHNfbm90X3ZhbGlkO1xuICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IENyZWRpdENhcmRSZW5kZXJlcjtcbiIsImNvbnN0IHN0b3JhZ2VLZXkgPSAncHBjcC1kYXRhLWNsaWVudC1pZCc7XG5cbmNvbnN0IHZhbGlkYXRlVG9rZW4gPSAodG9rZW4sIHVzZXIpID0+IHtcbiAgICBpZiAoISB0b2tlbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0b2tlbi51c2VyICE9PSB1c2VyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBpc0V4cGlyZWQgPSBjdXJyZW50VGltZSA+PSB0b2tlbi5leHBpcmF0aW9uICogMTAwMDtcbiAgICByZXR1cm4gISBpc0V4cGlyZWQ7XG59XG5cbmNvbnN0IHN0b3JlZFRva2VuRm9yVXNlciA9ICh1c2VyKSA9PiB7XG4gICAgY29uc3QgdG9rZW4gPSBKU09OLnBhcnNlKHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oc3RvcmFnZUtleSkpO1xuICAgIGlmICh2YWxpZGF0ZVRva2VuKHRva2VuLCB1c2VyKSkge1xuICAgICAgICByZXR1cm4gdG9rZW4udG9rZW47XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBzdG9yZVRva2VuID0gKHRva2VuKSA9PiB7XG4gICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeSh0b2tlbikpO1xufVxuXG5jb25zdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyID0gKHNjcmlwdCwgY29uZmlnKSA9PiB7XG4gICAgZmV0Y2goY29uZmlnLmVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBub25jZTogY29uZmlnLm5vbmNlXG4gICAgICAgIH0pXG4gICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICB9KS50aGVuKChkYXRhKT0+e1xuICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdGVUb2tlbihkYXRhLCBjb25maWcudXNlcik7XG4gICAgICAgIGlmICghaXNWYWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0b3JlVG9rZW4oZGF0YSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtY2xpZW50LXRva2VuJywgZGF0YS50b2tlbik7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKHNjcmlwdCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXI7XG4iLCJjbGFzcyBNZXNzYWdlUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGF5cGFsLk1lc3NhZ2VzKHtcbiAgICAgICAgICAgIGFtb3VudDogdGhpcy5jb25maWcuYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHJlbmRlcldpdGhBbW91bnQoYW1vdW50KSB7XG5cbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3V3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBuZXdXcmFwcGVyLnNldEF0dHJpYnV0ZSgnaWQnLCB0aGlzLmNvbmZpZy53cmFwcGVyLnJlcGxhY2UoJyMnLCAnJykpO1xuXG4gICAgICAgIGNvbnN0IHNpYmxpbmcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLm5leHRTaWJsaW5nO1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSk7XG4gICAgICAgIHNpYmxpbmcucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUobmV3V3JhcHBlciwgc2libGluZyk7XG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgICBwbGFjZW1lbnQ6IHRoaXMuY29uZmlnLnBsYWNlbWVudCxcbiAgICAgICAgICAgIHN0eWxlOiB0aGlzLmNvbmZpZy5zdHlsZVxuICAgICAgICB9KS5yZW5kZXIodGhpcy5jb25maWcud3JhcHBlcik7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuXG4gICAgICAgIGlmICh0eXBlb2YgcGF5cGFsLk1lc3NhZ2VzID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgdGhpcy5jb25maWcud3JhcHBlciA9PT0gJ3VuZGVmaW5lZCcgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IE1lc3NhZ2VSZW5kZXJlcjsiLCJjbGFzcyBTcGlubmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnRhcmdldCA9ICdmb3JtLndvb2NvbW1lcmNlLWNoZWNrb3V0JztcbiAgICB9XG5cbiAgICBzZXRUYXJnZXQodGFyZ2V0KSB7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIH1cblxuICAgIGJsb2NrKCkge1xuXG4gICAgICAgIGpRdWVyeSggdGhpcy50YXJnZXQgKS5ibG9jayh7XG4gICAgICAgICAgICBtZXNzYWdlOiBudWxsLFxuICAgICAgICAgICAgb3ZlcmxheUNTUzoge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjZcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdW5ibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkudW5ibG9jaygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgU3Bpbm5lcjtcbiIsImltcG9ydCBNaW5pQ2FydEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL01pbmlDYXJ0Qm9vdHN0YXAnO1xuaW1wb3J0IFNpbmdsZVByb2R1Y3RCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAnO1xuaW1wb3J0IENhcnRCb290c3RyYXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2FydEJvb3RzdGFwJztcbmltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAnO1xuaW1wb3J0IFBheU5vd0Jvb3RzdHJhcCBmcm9tIFwiLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwXCI7XG5pbXBvcnQgUmVuZGVyZXIgZnJvbSAnLi9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyJztcbmltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi9tb2R1bGVzL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ3JlZGl0Q2FyZFJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyXCI7XG5pbXBvcnQgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciBmcm9tIFwiLi9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXJcIjtcbmltcG9ydCBNZXNzYWdlUmVuZGVyZXIgZnJvbSBcIi4vbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXJcIjtcbmltcG9ydCBTcGlubmVyIGZyb20gXCIuL21vZHVsZXMvSGVscGVyL1NwaW5uZXJcIjtcblxuY29uc3QgYm9vdHN0cmFwID0gKCkgPT4ge1xuICAgIGNvbnN0IGVycm9ySGFuZGxlciA9IG5ldyBFcnJvckhhbmRsZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKTtcbiAgICBjb25zdCBzcGlubmVyID0gbmV3IFNwaW5uZXIoKTtcbiAgICBjb25zdCBjcmVkaXRDYXJkUmVuZGVyZXIgPSBuZXcgQ3JlZGl0Q2FyZFJlbmRlcmVyKFBheVBhbENvbW1lcmNlR2F0ZXdheSwgZXJyb3JIYW5kbGVyLCBzcGlubmVyKTtcbiAgICBjb25zdCBvblNtYXJ0QnV0dG9uQ2xpY2sgPSBkYXRhID0+IHtcbiAgICAgICAgd2luZG93LnBwY3BGdW5kaW5nU291cmNlID0gZGF0YS5mdW5kaW5nU291cmNlO1xuICAgIH07XG4gICAgY29uc3QgcmVuZGVyZXIgPSBuZXcgUmVuZGVyZXIoY3JlZGl0Q2FyZFJlbmRlcmVyLCBQYXlQYWxDb21tZXJjZUdhdGV3YXksIG9uU21hcnRCdXR0b25DbGljayk7XG4gICAgY29uc3QgbWVzc2FnZVJlbmRlcmVyID0gbmV3IE1lc3NhZ2VSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXkubWVzc2FnZXMpO1xuICAgIGNvbnN0IGNvbnRleHQgPSBQYXlQYWxDb21tZXJjZUdhdGV3YXkuY29udGV4dDtcbiAgICBpZiAoY29udGV4dCA9PT0gJ21pbmktY2FydCcgfHwgY29udGV4dCA9PT0gJ3Byb2R1Y3QnKSB7XG4gICAgICAgIGlmIChQYXlQYWxDb21tZXJjZUdhdGV3YXkubWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgICAgICBjb25zdCBtaW5pQ2FydEJvb3RzdHJhcCA9IG5ldyBNaW5pQ2FydEJvb3RzdGFwKFxuICAgICAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgICAgICByZW5kZXJlclxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgbWluaUNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdwcm9kdWN0JyAmJiBQYXlQYWxDb21tZXJjZUdhdGV3YXkuc2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkID09PSAnMScpIHtcbiAgICAgICAgY29uc3Qgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcCA9IG5ldyBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBzaW5nbGVQcm9kdWN0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NhcnQnKSB7XG4gICAgICAgIGNvbnN0IGNhcnRCb290c3RyYXAgPSBuZXcgQ2FydEJvb3RzdHJhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICApO1xuXG4gICAgICAgIGNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAnY2hlY2tvdXQnKSB7XG4gICAgICAgIGNvbnN0IGNoZWNrb3V0Qm9vdHN0YXAgPSBuZXcgQ2hlY2tvdXRCb290c3RhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICAgICAgbWVzc2FnZVJlbmRlcmVyLFxuICAgICAgICAgICAgc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIGNoZWNrb3V0Qm9vdHN0YXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncGF5LW5vdycgKSB7XG4gICAgICAgIGNvbnN0IHBheU5vd0Jvb3RzdHJhcCA9IG5ldyBQYXlOb3dCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcbiAgICAgICAgcGF5Tm93Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCAhPT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBtZXNzYWdlUmVuZGVyZXIucmVuZGVyKCk7XG4gICAgfVxufTtcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgJ0RPTUNvbnRlbnRMb2FkZWQnLFxuICAgICgpID0+IHtcbiAgICAgICAgaWYgKCF0eXBlb2YgKFBheVBhbENvbW1lcmNlR2F0ZXdheSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1BheVBhbCBidXR0b24gY291bGQgbm90IGJlIGNvbmZpZ3VyZWQuJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXkuY29udGV4dCAhPT0gJ2NoZWNrb3V0J1xuICAgICAgICAgICAgJiYgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkLnVzZXIgPT09IDBcbiAgICAgICAgICAgICYmIFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZC5oYXNfc3Vic2NyaXB0aW9uc1xuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICBzY3JpcHQuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgYm9vdHN0cmFwKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdzcmMnLCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuYnV0dG9uLnVybCk7XG4gICAgICAgIE9iamVjdC5lbnRyaWVzKFBheVBhbENvbW1lcmNlR2F0ZXdheS5zY3JpcHRfYXR0cmlidXRlcykuZm9yRWFjaChcbiAgICAgICAgICAgIChrZXlWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoa2V5VmFsdWVbMF0sIGtleVZhbHVlWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkLnNldF9hdHRyaWJ1dGUpIHtcbiAgICAgICAgICAgIGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIoc2NyaXB0LCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoc2NyaXB0KTtcbiAgICB9LFxuKTtcbiJdLCJuYW1lcyI6WyJFcnJvckhhbmRsZXIiLCJjb25zdHJ1Y3RvciIsImdlbmVyaWNFcnJvclRleHQiLCJ3cmFwcGVyIiwiZG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwibWVzc2FnZXNMaXN0IiwiZ2VuZXJpY0Vycm9yIiwiY2xhc3NMaXN0IiwiY29udGFpbnMiLCJjbGVhciIsIm1lc3NhZ2UiLCJhcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQiLCJlcnJvck1lc3NhZ2VFbGVtZW50IiwicHJlcGFyZU1lc3NhZ2VzTGlzdCIsInJlcGxhY2VXaXRoIiwidGV4dCIsInBlcnNpc3QiLCJTdHJpbmciLCJsZW5ndGgiLCJFcnJvciIsImFkZCIsInJlbW92ZSIsIm1lc3NhZ2VOb2RlIiwicHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0iLCJhcHBlbmRDaGlsZCIsImpRdWVyeSIsInNjcm9sbF90b19ub3RpY2VzIiwiY3JlYXRlRWxlbWVudCIsInNldEF0dHJpYnV0ZSIsImxpIiwiaW5uZXJIVE1MIiwic2FuaXRpemUiLCJ0ZXh0YXJlYSIsInZhbHVlIiwicmVwbGFjZSIsIm9uQXBwcm92ZSIsImNvbnRleHQiLCJlcnJvckhhbmRsZXIiLCJkYXRhIiwiYWN0aW9ucyIsImZldGNoIiwiY29uZmlnIiwiYWpheCIsImFwcHJvdmVfb3JkZXIiLCJlbmRwb2ludCIsIm1ldGhvZCIsImJvZHkiLCJKU09OIiwic3RyaW5naWZ5Iiwibm9uY2UiLCJvcmRlcl9pZCIsIm9yZGVySUQiLCJmdW5kaW5nX3NvdXJjZSIsIndpbmRvdyIsInBwY3BGdW5kaW5nU291cmNlIiwidGhlbiIsInJlcyIsImpzb24iLCJzdWNjZXNzIiwicmVzdGFydCIsImNhdGNoIiwiZXJyIiwibG9jYXRpb24iLCJocmVmIiwicmVkaXJlY3QiLCJwYXllckRhdGEiLCJwYXllciIsIlBheVBhbENvbW1lcmNlR2F0ZXdheSIsInBob25lIiwicGhvbmVfdHlwZSIsInBob25lX251bWJlciIsIm5hdGlvbmFsX251bWJlciIsImVtYWlsX2FkZHJlc3MiLCJuYW1lIiwic3VybmFtZSIsImdpdmVuX25hbWUiLCJhZGRyZXNzIiwiY291bnRyeV9jb2RlIiwiYWRkcmVzc19saW5lXzEiLCJhZGRyZXNzX2xpbmVfMiIsImFkbWluX2FyZWFfMSIsImFkbWluX2FyZWFfMiIsInBvc3RhbF9jb2RlIiwiQ2FydEFjdGlvbkhhbmRsZXIiLCJjb25maWd1cmF0aW9uIiwiY3JlYXRlT3JkZXIiLCJibkNvZGUiLCJibl9jb2RlcyIsImNyZWF0ZV9vcmRlciIsInB1cmNoYXNlX3VuaXRzIiwiYm5fY29kZSIsImNvbnNvbGUiLCJlcnJvciIsImlkIiwib25FcnJvciIsIk1pbmlDYXJ0Qm9vdHN0YXAiLCJnYXRld2F5IiwicmVuZGVyZXIiLCJhY3Rpb25IYW5kbGVyIiwiaW5pdCIsImxhYmVscyIsImdlbmVyaWMiLCJyZW5kZXIiLCJvbiIsInNob3VsZFJlbmRlciIsImJ1dHRvbiIsIm1pbmlfY2FydF93cmFwcGVyIiwiaG9zdGVkX2ZpZWxkcyIsIlByb2R1Y3QiLCJVcGRhdGVDYXJ0IiwidXBkYXRlIiwib25SZXNvbHZlIiwicHJvZHVjdHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlc3VsdCIsInJlc29sdmVkIiwiQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIiwiZWxlbWVudCIsInNob3dDYWxsYmFjayIsImhpZGVDYWxsYmFjayIsIm9ic2VydmVyIiwiYXR0cmlidXRlcyIsImNhbGxiYWNrIiwiTXV0YXRpb25PYnNlcnZlciIsIm9ic2VydmUiLCJkaXNjb25uZWN0IiwicXVhbnRpdHkiLCJ2YXJpYXRpb25zIiwiU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIiLCJ1cGRhdGVDYXJ0Iiwic2hvd0J1dHRvbkNhbGxiYWNrIiwiaGlkZUJ1dHRvbkNhbGxiYWNrIiwiZm9ybUVsZW1lbnQiLCJoYXNWYXJpYXRpb25zIiwiZ2V0UHJvZHVjdHMiLCJpc0dyb3VwZWRQcm9kdWN0IiwicXR5IiwicXVlcnlTZWxlY3RvckFsbCIsImZvckVhY2giLCJlbGVtZW50TmFtZSIsImdldEF0dHJpYnV0ZSIsIm1hdGNoIiwicGFyc2VJbnQiLCJwdXNoIiwicHJvbWlzZSIsIm1hcCIsIlNpbmdsZVByb2R1Y3RCb290c3RhcCIsIm1lc3NhZ2VzIiwiaGlkZUJ1dHRvbnMiLCJjaGFuZ2VfY2FydCIsInNob3dCdXR0b25zIiwicHJpY2VUZXh0IiwiaW5uZXJUZXh0IiwiYW1vdW50IiwicmVuZGVyV2l0aEFtb3VudCIsIkNhcnRCb290c3RyYXAiLCJzcGlubmVyIiwiYmxvY2siLCJ1bmJsb2NrIiwiY29kZSIsImNsaWNrIiwiQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIiwiZm9ybVNlbGVjdG9yIiwiZm9ybVZhbHVlcyIsInNlcmlhbGl6ZSIsImNyZWF0ZWFjY291bnQiLCJpcyIsImZvcm0iLCJkb21QYXJzZXIiLCJET01QYXJzZXIiLCJwYXJzZUZyb21TdHJpbmciLCJkZXRhaWxzIiwiZCIsImlzc3VlIiwiZGVzY3JpcHRpb24iLCJqb2luIiwiaW5wdXQiLCJjdXN0b21faWQiLCJhcHBlbmQiLCJvbkNhbmNlbCIsImdldEVsZW1lbnQiLCJzZWxlY3Rvck9yRWxlbWVudCIsImlzVmlzaWJsZSIsIm9mZnNldFdpZHRoIiwib2Zmc2V0SGVpZ2h0IiwiZ2V0Q2xpZW50UmVjdHMiLCJzZXRWaXNpYmxlIiwic2hvdyIsImltcG9ydGFudCIsImN1cnJlbnRWYWx1ZSIsInN0eWxlIiwiZ2V0UHJvcGVydHlWYWx1ZSIsInNldFByb3BlcnR5IiwicmVtb3ZlUHJvcGVydHkiLCJoaWRlIiwiQ2hlY2tvdXRCb290c3RhcCIsInN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciIsImJ1dHRvbkNoYW5nZU9ic2VydmVyIiwiZWwiLCJ1cGRhdGVVaSIsInZhbCIsImNhbmNlbF93cmFwcGVyIiwiY3VycmVudFBheW1lbnRNZXRob2QiLCJpc1BheXBhbCIsImlzQ2FyZCIsImlzU2F2ZWRDYXJkIiwiaXNTYXZlZENhcmRTZWxlY3RlZCIsImlzTm90T3VyR2F0ZXdheSIsImRpc2FibGVDcmVkaXRDYXJkRmllbGRzIiwiZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcyIsImFkZENsYXNzIiwiYXR0ciIsInJlbW92ZUNsYXNzIiwic2F2ZWRDYXJkTGlzdCIsIlBheU5vd0Jvb3RzdHJhcCIsInVybFBhcmFtcyIsIlVSTFNlYXJjaFBhcmFtcyIsInNlYXJjaCIsImhhcyIsIlJlbmRlcmVyIiwiY3JlZGl0Q2FyZFJlbmRlcmVyIiwiZGVmYXVsdENvbmZpZyIsIm9uU21hcnRCdXR0b25DbGljayIsImhvc3RlZEZpZWxkc1dyYXBwZXIiLCJjb250ZXh0Q29uZmlnIiwicmVuZGVyQnV0dG9ucyIsImlzQWxyZWFkeVJlbmRlcmVkIiwicGF5cGFsIiwiQnV0dG9ucyIsIm1pbmlfY2FydF9zdHlsZSIsIm9uQ2xpY2siLCJoYXNDaGlsZE5vZGVzIiwiZG9tRWxlbWVudCIsImRpc3BsYXkiLCJkaXNhYmxlRmllbGRzIiwiZW5hYmxlRmllbGRzIiwiZGNjSW5wdXRGYWN0b3J5Iiwib3JpZ2luYWwiLCJzdHlsZXMiLCJnZXRDb21wdXRlZFN0eWxlIiwibmV3RWxlbWVudCIsIk9iamVjdCIsInZhbHVlcyIsInByb3AiLCJpc05hTiIsIkNyZWRpdENhcmRSZW5kZXJlciIsImNhcmRWYWxpZCIsImZvcm1WYWxpZCIsImN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSIsIkhvc3RlZEZpZWxkcyIsImlzRWxpZ2libGUiLCJ3cmFwcGVyRWxlbWVudCIsInBhcmVudE5vZGUiLCJyZW1vdmVDaGlsZCIsInRlYXJkb3duIiwiZ2F0ZVdheUJveCIsIm9sZERpc3BsYXlTdHlsZSIsImhpZGVEY2NHYXRld2F5IiwiY2FyZE51bWJlckZpZWxkIiwic3R5bGVzUmF3IiwiY2FyZE51bWJlciIsInJlcGxhY2VDaGlsZCIsImNhcmRFeHBpcnlGaWVsZCIsImNhcmRFeHBpcnkiLCJjYXJkQ29kZUZpZWxkIiwiY2FyZENvZGUiLCJmb3JtV3JhcHBlciIsImVuZm9yY2VfdmF1bHQiLCJjaGVja2VkIiwiZmllbGRzIiwibnVtYmVyIiwic2VsZWN0b3IiLCJwbGFjZWhvbGRlciIsImNyZWRpdF9jYXJkX251bWJlciIsImN2diIsImV4cGlyYXRpb25EYXRlIiwibW1feXkiLCJob3N0ZWRGaWVsZHMiLCJkaXNwYXRjaEV2ZW50IiwiQ3VzdG9tRXZlbnQiLCJfc3VibWl0IiwiZXZlbnQiLCJjYXJkcyIsInZhbGlkQ2FyZHMiLCJ2YWxpZF9jYXJkcyIsImluZGV4T2YiLCJ0eXBlIiwia2V5cyIsImV2ZXJ5Iiwia2V5IiwiaXNWYWxpZCIsImFkZEV2ZW50TGlzdGVuZXIiLCJwcmV2ZW50RGVmYXVsdCIsImZpZWxkIiwiYXR0cmlidXRlIiwicmVtb3ZlQXR0cmlidXRlIiwic2F2ZV9jYXJkIiwidmF1bHQiLCJnZXRFbGVtZW50QnlJZCIsImNvbnRpbmdlbmN5IiwiaG9zdGVkRmllbGRzRGF0YSIsImNvbnRpbmdlbmNpZXMiLCJjYXJkaG9sZGVyTmFtZSIsImZpcnN0TmFtZSIsImxhc3ROYW1lIiwiY2FyZGhvbGRlcl9uYW1lX3JlcXVpcmVkIiwic3VibWl0IiwicGF5bG9hZCIsIm9yZGVySWQiLCJjYXJkX25vdF9zdXBwb3J0ZWQiLCJmaWVsZHNfbm90X3ZhbGlkIiwic3RvcmFnZUtleSIsInZhbGlkYXRlVG9rZW4iLCJ0b2tlbiIsInVzZXIiLCJjdXJyZW50VGltZSIsIkRhdGUiLCJnZXRUaW1lIiwiaXNFeHBpcmVkIiwiZXhwaXJhdGlvbiIsInN0b3JlZFRva2VuRm9yVXNlciIsInBhcnNlIiwic2Vzc2lvblN0b3JhZ2UiLCJnZXRJdGVtIiwic3RvcmVUb2tlbiIsInNldEl0ZW0iLCJkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyIiwic2NyaXB0IiwiTWVzc2FnZVJlbmRlcmVyIiwiTWVzc2FnZXMiLCJwbGFjZW1lbnQiLCJuZXdXcmFwcGVyIiwic2libGluZyIsIm5leHRTaWJsaW5nIiwicGFyZW50RWxlbWVudCIsImluc2VydEJlZm9yZSIsIlNwaW5uZXIiLCJ0YXJnZXQiLCJzZXRUYXJnZXQiLCJvdmVybGF5Q1NTIiwiYmFja2dyb3VuZCIsIm9wYWNpdHkiLCJib290c3RyYXAiLCJmdW5kaW5nU291cmNlIiwibWVzc2FnZVJlbmRlcmVyIiwibWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCIsIm1pbmlDYXJ0Qm9vdHN0cmFwIiwic2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkIiwic2luZ2xlUHJvZHVjdEJvb3RzdHJhcCIsImNhcnRCb290c3RyYXAiLCJjaGVja291dEJvb3RzdGFwIiwicGF5Tm93Qm9vdHN0cmFwIiwiZGF0YV9jbGllbnRfaWQiLCJoYXNfc3Vic2NyaXB0aW9ucyIsInVybCIsImVudHJpZXMiLCJzY3JpcHRfYXR0cmlidXRlcyIsImtleVZhbHVlIiwic2V0X2F0dHJpYnV0ZSJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///964\n")}},__webpack_exports__={};__webpack_modules__[964]()})();
|
1 |
+
(()=>{"use strict";var __webpack_modules__={210:()=>{eval("\n;// CONCATENATED MODULE: ./resources/js/modules/ErrorHandler.js\nclass ErrorHandler {\n constructor(genericErrorText) {\n this.genericErrorText = genericErrorText;\n this.wrapper = document.querySelector('.woocommerce-notices-wrapper');\n this.messagesList = document.querySelector('ul.woocommerce-error');\n }\n\n genericError() {\n if (this.wrapper.classList.contains('ppcp-persist')) {\n return;\n }\n\n this.clear();\n this.message(this.genericErrorText);\n }\n\n appendPreparedErrorMessageElement(errorMessageElement) {\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n this.messagesList.replaceWith(errorMessageElement);\n }\n\n message(text, persist = false) {\n if (!typeof String || text.length === 0) {\n throw new Error('A new message text must be a non-empty string.');\n }\n\n if (this.messagesList === null) {\n this.prepareMessagesList();\n }\n\n if (persist) {\n this.wrapper.classList.add('ppcp-persist');\n } else {\n this.wrapper.classList.remove('ppcp-persist');\n }\n\n let messageNode = this.prepareMessagesListItem(text);\n this.messagesList.appendChild(messageNode);\n jQuery.scroll_to_notices(jQuery('.woocommerce-notices-wrapper'));\n }\n\n prepareMessagesList() {\n if (this.messagesList === null) {\n this.messagesList = document.createElement('ul');\n this.messagesList.setAttribute('class', 'woocommerce-error');\n this.messagesList.setAttribute('role', 'alert');\n this.wrapper.appendChild(this.messagesList);\n }\n }\n\n prepareMessagesListItem(message) {\n const li = document.createElement('li');\n li.innerHTML = message;\n return li;\n }\n\n sanitize(text) {\n const textarea = document.createElement('textarea');\n textarea.innerHTML = text;\n return textarea.value.replace('Error: ', '');\n }\n\n clear() {\n if (this.messagesList === null) {\n return;\n }\n\n this.messagesList.innerHTML = '';\n }\n\n}\n\n/* harmony default export */ const modules_ErrorHandler = (ErrorHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForContinue.js\nconst onApprove = (context, errorHandler) => {\n return (data, actions) => {\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID,\n funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n if (!data.success) {\n errorHandler.genericError();\n return actions.restart().catch(err => {\n errorHandler.genericError();\n });\n }\n\n location.href = context.config.redirect;\n });\n };\n};\n\n/* harmony default export */ const onApproveForContinue = (onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/PayerData.js\nconst payerData = () => {\n const payer = PayPalCommerceGateway.payer;\n\n if (!payer) {\n return null;\n }\n\n const phone = document.querySelector('#billing_phone') || typeof payer.phone !== 'undefined' ? {\n phone_type: \"HOME\",\n phone_number: {\n national_number: document.querySelector('#billing_phone') ? document.querySelector('#billing_phone').value : payer.phone.phone_number.national_number\n }\n } : null;\n const payerData = {\n email_address: document.querySelector('#billing_email') ? document.querySelector('#billing_email').value : payer.email_address,\n name: {\n surname: document.querySelector('#billing_last_name') ? document.querySelector('#billing_last_name').value : payer.name.surname,\n given_name: document.querySelector('#billing_first_name') ? document.querySelector('#billing_first_name').value : payer.name.given_name\n },\n address: {\n country_code: document.querySelector('#billing_country') ? document.querySelector('#billing_country').value : payer.address.country_code,\n address_line_1: document.querySelector('#billing_address_1') ? document.querySelector('#billing_address_1').value : payer.address.address_line_1,\n address_line_2: document.querySelector('#billing_address_2') ? document.querySelector('#billing_address_2').value : payer.address.address_line_2,\n admin_area_1: document.querySelector('#billing_state') ? document.querySelector('#billing_state').value : payer.address.admin_area_1,\n admin_area_2: document.querySelector('#billing_city') ? document.querySelector('#billing_city').value : payer.address.admin_area_2,\n postal_code: document.querySelector('#billing_postcode') ? document.querySelector('#billing_postcode').value : payer.address.postal_code\n }\n };\n\n if (phone) {\n payerData.phone = phone;\n }\n\n return payerData;\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CartActionHandler.js\n\n\n\nclass CartActionHandler {\n constructor(config, errorHandler) {\n this.config = config;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units: [],\n bn_code: bnCode,\n payer,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CartActionHandler = (CartActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/MiniCartBootstap.js\n\n\n\nclass MiniCartBootstap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.actionHandler = null;\n }\n\n init() {\n this.actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.render();\n jQuery(document.body).on('wc_fragments_loaded wc_fragments_refreshed', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.mini_cart_wrapper) !== null || document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.renderer.render(this.gateway.button.mini_cart_wrapper, this.gateway.hosted_fields.mini_cart_wrapper, this.actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_MiniCartBootstap = (MiniCartBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/UpdateCart.js\n\n\nclass UpdateCart {\n constructor(endpoint, nonce) {\n this.endpoint = endpoint;\n this.nonce = nonce;\n }\n /**\n *\n * @param onResolve\n * @param {Product[]} products\n * @returns {Promise<unknown>}\n */\n\n\n update(onResolve, products) {\n return new Promise((resolve, reject) => {\n fetch(this.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.nonce,\n products\n })\n }).then(result => {\n return result.json();\n }).then(result => {\n if (!result.success) {\n reject(result.data);\n return;\n }\n\n const resolved = onResolve(result.data);\n resolve(resolved);\n });\n });\n }\n\n}\n\n/* harmony default export */ const Helper_UpdateCart = (UpdateCart);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/ButtonsToggleListener.js\n/**\n * When you can't add something to the cart, the PayPal buttons should not show.\n * Therefore we listen for changes on the add to cart button and show/hide the buttons accordingly.\n */\nclass ButtonsToggleListener {\n constructor(element, showCallback, hideCallback) {\n this.element = element;\n this.showCallback = showCallback;\n this.hideCallback = hideCallback;\n this.observer = null;\n }\n\n init() {\n const config = {\n attributes: true\n };\n\n const callback = () => {\n if (this.element.classList.contains('disabled')) {\n this.hideCallback();\n return;\n }\n\n this.showCallback();\n };\n\n this.observer = new MutationObserver(callback);\n this.observer.observe(this.element, config);\n callback();\n }\n\n disconnect() {\n this.observer.disconnect();\n }\n\n}\n\n/* harmony default export */ const Helper_ButtonsToggleListener = (ButtonsToggleListener);\n;// CONCATENATED MODULE: ./resources/js/modules/Entity/Product.js\nclass Product {\n constructor(id, quantity, variations) {\n this.id = id;\n this.quantity = quantity;\n this.variations = variations;\n }\n\n data() {\n return {\n id: this.id,\n quantity: this.quantity,\n variations: this.variations\n };\n }\n\n}\n\n/* harmony default export */ const Entity_Product = (Product);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/SingleProductActionHandler.js\n\n\n\n\n\nclass SingleProductActionHandler {\n constructor(config, updateCart, showButtonCallback, hideButtonCallback, formElement, errorHandler) {\n this.config = config;\n this.updateCart = updateCart;\n this.showButtonCallback = showButtonCallback;\n this.hideButtonCallback = hideButtonCallback;\n this.formElement = formElement;\n this.errorHandler = errorHandler;\n }\n\n configuration() {\n if (this.hasVariations()) {\n const observer = new Helper_ButtonsToggleListener(this.formElement.querySelector('.single_add_to_cart_button'), this.showButtonCallback, this.hideButtonCallback);\n observer.init();\n }\n\n return {\n createOrder: this.createOrder(),\n onApprove: onApproveForContinue(this, this.errorHandler),\n onError: error => {\n this.errorHandler.genericError();\n }\n };\n }\n\n createOrder() {\n var getProducts = null;\n\n if (!this.isGroupedProduct()) {\n getProducts = () => {\n const id = document.querySelector('[name=\"add-to-cart\"]').value;\n const qty = document.querySelector('[name=\"quantity\"]').value;\n const variations = this.variations();\n return [new Entity_Product(id, qty, variations)];\n };\n } else {\n getProducts = () => {\n const products = [];\n this.formElement.querySelectorAll('input[type=\"number\"]').forEach(element => {\n if (!element.value) {\n return;\n }\n\n const elementName = element.getAttribute('name').match(/quantity\\[([\\d]*)\\]/);\n\n if (elementName.length !== 2) {\n return;\n }\n\n const id = parseInt(elementName[1]);\n const quantity = parseInt(element.value);\n products.push(new Entity_Product(id, quantity, null));\n });\n return products;\n };\n }\n\n const createOrder = (data, actions) => {\n this.errorHandler.clear();\n\n const onResolve = purchase_units => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n purchase_units,\n payer,\n bn_code: bnCode,\n context: this.config.context\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n console.error(data);\n throw Error(data.data.message);\n }\n\n return data.data.id;\n });\n };\n\n const promise = this.updateCart.update(onResolve, getProducts());\n return promise;\n };\n\n return createOrder;\n }\n\n variations() {\n if (!this.hasVariations()) {\n return null;\n }\n\n const attributes = [...this.formElement.querySelectorAll(\"[name^='attribute_']\")].map(element => {\n return {\n value: element.value,\n name: element.name\n };\n });\n return attributes;\n }\n\n hasVariations() {\n return this.formElement.classList.contains('variations_form');\n }\n\n isGroupedProduct() {\n return this.formElement.classList.contains('grouped_form');\n }\n\n}\n\n/* harmony default export */ const ActionHandler_SingleProductActionHandler = (SingleProductActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/SingleProductBootstap.js\n\n\n\n\nclass SingleProductBootstap {\n constructor(gateway, renderer, messages) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n }\n\n handleChange() {\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n this.renderer.hideButtons(this.gateway.button.wrapper);\n return;\n }\n\n this.render();\n }\n\n init() {\n document.querySelector('form.cart').addEventListener('change', this.handleChange.bind(this));\n\n if (!this.shouldRender()) {\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n return;\n }\n\n this.render();\n }\n\n shouldRender() {\n return document.querySelector('form.cart') !== null && !this.priceAmountIsZero();\n }\n\n priceAmountIsZero() {\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('.product .woocommerce-Price-amount')) {\n priceText = document.querySelector('.product .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseFloat(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n return amount === 0;\n }\n\n render() {\n const actionHandler = new ActionHandler_SingleProductActionHandler(this.gateway, new Helper_UpdateCart(this.gateway.ajax.change_cart.endpoint, this.gateway.ajax.change_cart.nonce), () => {\n this.renderer.showButtons(this.gateway.button.wrapper);\n this.renderer.showButtons(this.gateway.hosted_fields.wrapper);\n let priceText = \"0\";\n\n if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;\n } else if (document.querySelector('form.cart .woocommerce-Price-amount')) {\n priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;\n }\n\n const amount = parseInt(priceText.replace(/([^\\d,\\.\\s]*)/g, ''));\n this.messages.renderWithAmount(amount);\n }, () => {\n this.renderer.hideButtons(this.gateway.button.wrapper);\n this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);\n }, document.querySelector('form.cart'), new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_SingleProductBootstap = (SingleProductBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CartBootstap.js\n\n\n\nclass CartBootstrap {\n constructor(gateway, renderer) {\n this.gateway = gateway;\n this.renderer = renderer;\n }\n\n init() {\n if (!this.shouldRender()) {\n return;\n }\n\n this.render();\n jQuery(document.body).on('updated_cart_totals updated_checkout', () => {\n this.render();\n });\n }\n\n shouldRender() {\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n const actionHandler = new ActionHandler_CartActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic));\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n }\n\n}\n\n/* harmony default export */ const CartBootstap = (CartBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/OnApproveHandler/onApproveForPayNow.js\nconst onApproveForPayNow_onApprove = (context, errorHandler, spinner) => {\n return (data, actions) => {\n spinner.block();\n errorHandler.clear();\n return fetch(context.config.ajax.approve_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: context.config.ajax.approve_order.nonce,\n order_id: data.orderID,\n funding_source: window.ppcpFundingSource\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n spinner.unblock();\n\n if (!data.success) {\n if (data.data.code === 100) {\n errorHandler.message(data.data.message);\n } else {\n errorHandler.genericError();\n }\n\n if (typeof actions !== 'undefined' && typeof actions.restart !== 'undefined') {\n return actions.restart();\n }\n\n throw new Error(data.data.message);\n }\n\n document.querySelector('#place_order').click();\n });\n };\n};\n\n/* harmony default export */ const onApproveForPayNow = (onApproveForPayNow_onApprove);\n;// CONCATENATED MODULE: ./resources/js/modules/ActionHandler/CheckoutActionHandler.js\n\n\n\nclass CheckoutActionHandler {\n constructor(config, errorHandler, spinner) {\n this.config = config;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n }\n\n configuration() {\n const spinner = this.spinner;\n\n const createOrder = (data, actions) => {\n const payer = payerData();\n const bnCode = typeof this.config.bn_codes[this.config.context] !== 'undefined' ? this.config.bn_codes[this.config.context] : '';\n const errorHandler = this.errorHandler;\n const formSelector = this.config.context === 'checkout' ? 'form.checkout' : 'form#order_review';\n const formValues = jQuery(formSelector).serialize();\n const createaccount = jQuery('#createaccount').is(\":checked\") ? true : false;\n return fetch(this.config.ajax.create_order.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: this.config.ajax.create_order.nonce,\n payer,\n bn_code: bnCode,\n context: this.config.context,\n order_id: this.config.order_id,\n form: formValues,\n createaccount: createaccount\n })\n }).then(function (res) {\n return res.json();\n }).then(function (data) {\n if (!data.success) {\n spinner.unblock(); //handle both messages sent from Woocommerce (data.messages) and this plugin (data.data.message)\n\n if (typeof data.messages !== 'undefined') {\n const domParser = new DOMParser();\n errorHandler.appendPreparedErrorMessageElement(domParser.parseFromString(data.messages, 'text/html').querySelector('ul'));\n } else {\n errorHandler.clear();\n\n if (data.data.details.length > 0) {\n errorHandler.message(data.data.details.map(d => `${d.issue} ${d.description}`).join('<br/>'), true);\n } else {\n errorHandler.message(data.data.message, true);\n }\n }\n\n return;\n }\n\n const input = document.createElement('input');\n input.setAttribute('type', 'hidden');\n input.setAttribute('name', 'ppcp-resume-order');\n input.setAttribute('value', data.data.purchase_units[0].custom_id);\n document.querySelector(formSelector).append(input);\n return data.data.id;\n });\n };\n\n return {\n createOrder,\n onApprove: onApproveForPayNow(this, this.errorHandler, this.spinner),\n onCancel: () => {\n spinner.unblock();\n },\n onError: () => {\n this.errorHandler.genericError();\n spinner.unblock();\n }\n };\n }\n\n}\n\n/* harmony default export */ const ActionHandler_CheckoutActionHandler = (CheckoutActionHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Hiding.js\nconst getElement = selectorOrElement => {\n if (typeof selectorOrElement === 'string') {\n return document.querySelector(selectorOrElement);\n }\n\n return selectorOrElement;\n};\n\nconst isVisible = element => {\n return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);\n};\nconst setVisible = (selectorOrElement, show, important = false) => {\n const element = getElement(selectorOrElement);\n\n if (!element) {\n return;\n }\n\n const currentValue = element.style.getPropertyValue('display');\n\n if (!show) {\n if (currentValue === 'none') {\n return;\n }\n\n element.style.setProperty('display', 'none', important ? 'important' : '');\n } else {\n if (currentValue === 'none') {\n element.style.removeProperty('display');\n } // still not visible (if something else added display: none in CSS)\n\n\n if (!isVisible(element)) {\n element.style.setProperty('display', 'block');\n }\n }\n};\nconst hide = (selectorOrElement, important = false) => {\n setVisible(selectorOrElement, false, important);\n};\nconst show = selectorOrElement => {\n setVisible(selectorOrElement, true);\n};\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/CheckoutMethodState.js\nconst PaymentMethods = {\n PAYPAL: 'ppcp-gateway',\n CARDS: 'ppcp-credit-card-gateway'\n};\nconst ORDER_BUTTON_SELECTOR = '#place_order';\nconst getCurrentPaymentMethod = () => {\n const el = document.querySelector('input[name=\"payment_method\"]:checked');\n\n if (!el) {\n return null;\n }\n\n return el.value;\n};\nconst isSavedCardSelected = () => {\n const savedCardList = document.querySelector('#saved-credit-card');\n return savedCardList && savedCardList.value !== '';\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/CheckoutBootstap.js\n\n\n\n\n\nclass CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n this.gateway = gateway;\n this.renderer = renderer;\n this.messages = messages;\n this.spinner = spinner;\n this.standardOrderButtonSelector = ORDER_BUTTON_SELECTOR;\n this.buttonChangeObserver = new MutationObserver(el => {\n this.updateUi();\n });\n }\n\n init() {\n this.render(); // Unselect saved card.\n // WC saves form values, so with our current UI it would be a bit weird\n // if the user paid with saved, then after some time tries to pay again,\n // but wants to enter a new card, and to do that they have to choose “Select payment” in the list.\n\n jQuery('#saved-credit-card').val(jQuery('#saved-credit-card option:first').val());\n jQuery(document.body).on('updated_checkout', () => {\n this.render();\n });\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n this.updateUi();\n });\n jQuery(document).on('hosted_fields_loaded', () => {\n jQuery('#saved-credit-card').on('change', () => {\n this.updateUi();\n });\n });\n this.updateUi();\n }\n\n shouldRender() {\n if (document.querySelector(this.gateway.button.cancel_wrapper)) {\n return false;\n }\n\n return document.querySelector(this.gateway.button.wrapper) !== null || document.querySelector(this.gateway.hosted_fields.wrapper) !== null;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n if (document.querySelector(this.gateway.hosted_fields.wrapper + '>div')) {\n document.querySelector(this.gateway.hosted_fields.wrapper + '>div').setAttribute('style', '');\n }\n\n const actionHandler = new ActionHandler_CheckoutActionHandler(PayPalCommerceGateway, new modules_ErrorHandler(this.gateway.labels.error.generic), this.spinner);\n this.renderer.render(this.gateway.button.wrapper, this.gateway.hosted_fields.wrapper, actionHandler.configuration());\n this.buttonChangeObserver.observe(document.querySelector(this.standardOrderButtonSelector), {\n attributes: true\n });\n }\n\n updateUi() {\n const currentPaymentMethod = getCurrentPaymentMethod();\n const isPaypal = currentPaymentMethod === PaymentMethods.PAYPAL;\n const isCard = currentPaymentMethod === PaymentMethods.CARDS;\n const isSavedCard = isCard && isSavedCardSelected();\n const isNotOurGateway = !isPaypal && !isCard;\n setVisible(this.standardOrderButtonSelector, isNotOurGateway || isSavedCard, true);\n setVisible(this.gateway.button.wrapper, isPaypal);\n setVisible(this.gateway.messages.wrapper, isPaypal);\n setVisible(this.gateway.hosted_fields.wrapper, isCard && !isSavedCard);\n\n if (isPaypal) {\n this.messages.render();\n }\n\n if (isCard) {\n if (isSavedCard) {\n this.disableCreditCardFields();\n } else {\n this.enableCreditCardFields();\n }\n }\n }\n\n disableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').addClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", true);\n this.renderer.disableCreditCardFields();\n }\n\n enableCreditCardFields() {\n jQuery('label[for=\"ppcp-credit-card-gateway-card-number\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-number').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-expiry\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-expiry').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"ppcp-credit-card-gateway-card-cvc\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-gateway-card-cvc').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('label[for=\"vault\"]').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').removeClass('ppcp-credit-card-gateway-form-field-disabled');\n jQuery('#ppcp-credit-card-vault').attr(\"disabled\", false);\n this.renderer.enableCreditCardFields();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_CheckoutBootstap = (CheckoutBootstap);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Subscriptions.js\nconst isChangePaymentPage = () => {\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.has('change_payment_method');\n};\n;// CONCATENATED MODULE: ./resources/js/modules/ContextBootstrap/PayNowBootstrap.js\n\n\n\nclass PayNowBootstrap extends ContextBootstrap_CheckoutBootstap {\n constructor(gateway, renderer, messages, spinner) {\n super(gateway, renderer, messages, spinner);\n }\n\n updateUi() {\n if (isChangePaymentPage()) {\n return;\n }\n\n super.updateUi();\n }\n\n}\n\n/* harmony default export */ const ContextBootstrap_PayNowBootstrap = (PayNowBootstrap);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/Renderer.js\nclass Renderer {\n constructor(creditCardRenderer, defaultConfig, onSmartButtonClick, onSmartButtonsInit) {\n this.defaultConfig = defaultConfig;\n this.creditCardRenderer = creditCardRenderer;\n this.onSmartButtonClick = onSmartButtonClick;\n this.onSmartButtonsInit = onSmartButtonsInit;\n }\n\n render(wrapper, hostedFieldsWrapper, contextConfig) {\n this.renderButtons(wrapper, contextConfig);\n this.creditCardRenderer.render(hostedFieldsWrapper, contextConfig);\n }\n\n renderButtons(wrapper, contextConfig) {\n if (!document.querySelector(wrapper) || this.isAlreadyRendered(wrapper) || 'undefined' === typeof paypal.Buttons) {\n return;\n }\n\n const style = wrapper === this.defaultConfig.button.wrapper ? this.defaultConfig.button.style : this.defaultConfig.button.mini_cart_style;\n paypal.Buttons({\n style,\n ...contextConfig,\n onClick: this.onSmartButtonClick,\n onInit: this.onSmartButtonsInit\n }).render(wrapper);\n }\n\n isAlreadyRendered(wrapper) {\n return document.querySelector(wrapper).hasChildNodes();\n }\n\n hideButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'none';\n return true;\n }\n\n showButtons(element) {\n const domElement = document.querySelector(element);\n\n if (!domElement) {\n return false;\n }\n\n domElement.style.display = 'block';\n return true;\n }\n\n disableCreditCardFields() {\n this.creditCardRenderer.disableFields();\n }\n\n enableCreditCardFields() {\n this.creditCardRenderer.enableFields();\n }\n\n}\n\n/* harmony default export */ const Renderer_Renderer = (Renderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/DccInputFactory.js\nconst dccInputFactory = original => {\n const styles = window.getComputedStyle(original);\n const newElement = document.createElement('span');\n newElement.setAttribute('id', original.id);\n Object.values(styles).forEach(prop => {\n if (!styles[prop] || !isNaN(prop)) {\n return;\n }\n\n newElement.style.setProperty(prop, '' + styles[prop]);\n });\n return newElement;\n};\n\n/* harmony default export */ const DccInputFactory = (dccInputFactory);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/CreditCardRenderer.js\n\n\nclass CreditCardRenderer {\n constructor(defaultConfig, errorHandler, spinner) {\n this.defaultConfig = defaultConfig;\n this.errorHandler = errorHandler;\n this.spinner = spinner;\n this.cardValid = false;\n this.formValid = false;\n this.currentHostedFieldsInstance = null;\n }\n\n render(wrapper, contextConfig) {\n if (this.defaultConfig.context !== 'checkout' && this.defaultConfig.context !== 'pay-now' || wrapper === null || document.querySelector(wrapper) === null) {\n return;\n }\n\n if (typeof paypal.HostedFields === 'undefined' || !paypal.HostedFields.isEligible()) {\n const wrapperElement = document.querySelector(wrapper);\n wrapperElement.parentNode.removeChild(wrapperElement);\n return;\n }\n\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.teardown().catch(err => console.error(`Hosted fields teardown error: ${err}`));\n this.currentHostedFieldsInstance = null;\n }\n\n const gateWayBox = document.querySelector('.payment_box.payment_method_ppcp-credit-card-gateway');\n const oldDisplayStyle = gateWayBox.style.display;\n gateWayBox.style.display = 'block';\n const hideDccGateway = document.querySelector('#ppcp-hide-dcc');\n\n if (hideDccGateway) {\n hideDccGateway.parentNode.removeChild(hideDccGateway);\n }\n\n const cardNumberField = document.querySelector('#ppcp-credit-card-gateway-card-number');\n const stylesRaw = window.getComputedStyle(cardNumberField);\n let styles = {};\n Object.values(stylesRaw).forEach(prop => {\n if (!stylesRaw[prop]) {\n return;\n }\n\n styles[prop] = '' + stylesRaw[prop];\n });\n const cardNumber = DccInputFactory(cardNumberField);\n cardNumberField.parentNode.replaceChild(cardNumber, cardNumberField);\n const cardExpiryField = document.querySelector('#ppcp-credit-card-gateway-card-expiry');\n const cardExpiry = DccInputFactory(cardExpiryField);\n cardExpiryField.parentNode.replaceChild(cardExpiry, cardExpiryField);\n const cardCodeField = document.querySelector('#ppcp-credit-card-gateway-card-cvc');\n const cardCode = DccInputFactory(cardCodeField);\n cardCodeField.parentNode.replaceChild(cardCode, cardCodeField);\n gateWayBox.style.display = oldDisplayStyle;\n const formWrapper = '.payment_box payment_method_ppcp-credit-card-gateway';\n\n if (this.defaultConfig.enforce_vault && document.querySelector(formWrapper + ' .ppcp-credit-card-vault')) {\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').checked = true;\n document.querySelector(formWrapper + ' .ppcp-credit-card-vault').setAttribute('disabled', true);\n }\n\n paypal.HostedFields.render({\n createOrder: contextConfig.createOrder,\n styles: {\n 'input': styles\n },\n fields: {\n number: {\n selector: '#ppcp-credit-card-gateway-card-number',\n placeholder: this.defaultConfig.hosted_fields.labels.credit_card_number\n },\n cvv: {\n selector: '#ppcp-credit-card-gateway-card-cvc',\n placeholder: this.defaultConfig.hosted_fields.labels.cvv\n },\n expirationDate: {\n selector: '#ppcp-credit-card-gateway-card-expiry',\n placeholder: this.defaultConfig.hosted_fields.labels.mm_yy\n }\n }\n }).then(hostedFields => {\n document.dispatchEvent(new CustomEvent(\"hosted_fields_loaded\"));\n this.currentHostedFieldsInstance = hostedFields;\n hostedFields.on('inputSubmitRequest', () => {\n this._submit(contextConfig);\n });\n hostedFields.on('cardTypeChange', event => {\n if (!event.cards.length) {\n this.cardValid = false;\n return;\n }\n\n const validCards = this.defaultConfig.hosted_fields.valid_cards;\n this.cardValid = validCards.indexOf(event.cards[0].type) !== -1;\n });\n hostedFields.on('validityChange', event => {\n const formValid = Object.keys(event.fields).every(function (key) {\n return event.fields[key].isValid;\n });\n this.formValid = formValid;\n });\n\n if (document.querySelector(wrapper).getAttribute('data-ppcp-subscribed') !== true) {\n document.querySelector(wrapper + ' button').addEventListener('click', event => {\n event.preventDefault();\n\n this._submit(contextConfig);\n });\n document.querySelector(wrapper).setAttribute('data-ppcp-subscribed', true);\n }\n });\n document.querySelector('#payment_method_ppcp-credit-card-gateway').addEventListener('click', () => {\n document.querySelector('label[for=ppcp-credit-card-gateway-card-number]').click();\n });\n }\n\n disableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.setAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.setAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n enableFields() {\n if (this.currentHostedFieldsInstance) {\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'number',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'cvv',\n attribute: 'disabled'\n });\n this.currentHostedFieldsInstance.removeAttribute({\n field: 'expirationDate',\n attribute: 'disabled'\n });\n }\n }\n\n _submit(contextConfig) {\n this.spinner.block();\n this.errorHandler.clear();\n\n if (this.formValid && this.cardValid) {\n const save_card = this.defaultConfig.can_save_vault_token ? true : false;\n let vault = document.getElementById('ppcp-credit-card-vault') ? document.getElementById('ppcp-credit-card-vault').checked : save_card;\n\n if (this.defaultConfig.enforce_vault) {\n vault = true;\n }\n\n const contingency = this.defaultConfig.hosted_fields.contingency;\n const hostedFieldsData = {\n vault: vault\n };\n\n if (contingency !== 'NO_3D_SECURE') {\n hostedFieldsData.contingencies = [contingency];\n }\n\n if (this.defaultConfig.payer) {\n hostedFieldsData.cardholderName = this.defaultConfig.payer.name.given_name + ' ' + this.defaultConfig.payer.name.surname;\n }\n\n if (!hostedFieldsData.cardholderName) {\n const firstName = document.getElementById('billing_first_name') ? document.getElementById('billing_first_name').value : '';\n const lastName = document.getElementById('billing_last_name') ? document.getElementById('billing_last_name').value : '';\n\n if (!firstName || !lastName) {\n this.spinner.unblock();\n this.errorHandler.message(this.defaultConfig.hosted_fields.labels.cardholder_name_required);\n return;\n }\n\n hostedFieldsData.cardholderName = firstName + ' ' + lastName;\n }\n\n this.currentHostedFieldsInstance.submit(hostedFieldsData).then(payload => {\n payload.orderID = payload.orderId;\n this.spinner.unblock();\n return contextConfig.onApprove(payload);\n }).catch(err => {\n this.spinner.unblock();\n this.errorHandler.clear();\n\n if (err.details) {\n this.errorHandler.message(err.details.map(d => `${d.issue} ${d.description}`).join('<br/>'), true);\n }\n });\n } else {\n this.spinner.unblock();\n const message = !this.cardValid ? this.defaultConfig.hosted_fields.labels.card_not_supported : this.defaultConfig.hosted_fields.labels.fields_not_valid;\n this.errorHandler.message(message);\n }\n }\n\n}\n\n/* harmony default export */ const Renderer_CreditCardRenderer = (CreditCardRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/DataClientIdAttributeHandler.js\nconst storageKey = 'ppcp-data-client-id';\n\nconst validateToken = (token, user) => {\n if (!token) {\n return false;\n }\n\n if (token.user !== user) {\n return false;\n }\n\n const currentTime = new Date().getTime();\n const isExpired = currentTime >= token.expiration * 1000;\n return !isExpired;\n};\n\nconst storedTokenForUser = user => {\n const token = JSON.parse(sessionStorage.getItem(storageKey));\n\n if (validateToken(token, user)) {\n return token.token;\n }\n\n return null;\n};\n\nconst storeToken = token => {\n sessionStorage.setItem(storageKey, JSON.stringify(token));\n};\n\nconst dataClientIdAttributeHandler = (script, config) => {\n fetch(config.endpoint, {\n method: 'POST',\n body: JSON.stringify({\n nonce: config.nonce\n })\n }).then(res => {\n return res.json();\n }).then(data => {\n const isValid = validateToken(data, config.user);\n\n if (!isValid) {\n return;\n }\n\n storeToken(data);\n script.setAttribute('data-client-token', data.token);\n document.body.append(script);\n });\n};\n\n/* harmony default export */ const DataClientIdAttributeHandler = (dataClientIdAttributeHandler);\n;// CONCATENATED MODULE: ./resources/js/modules/Renderer/MessageRenderer.js\nclass MessageRenderer {\n constructor(config) {\n this.config = config;\n }\n\n render() {\n if (!this.shouldRender()) {\n return;\n }\n\n paypal.Messages({\n amount: this.config.amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n renderWithAmount(amount) {\n if (!this.shouldRender()) {\n return;\n }\n\n const newWrapper = document.createElement('div');\n newWrapper.setAttribute('id', this.config.wrapper.replace('#', ''));\n const sibling = document.querySelector(this.config.wrapper).nextSibling;\n document.querySelector(this.config.wrapper).parentElement.removeChild(document.querySelector(this.config.wrapper));\n sibling.parentElement.insertBefore(newWrapper, sibling);\n paypal.Messages({\n amount,\n placement: this.config.placement,\n style: this.config.style\n }).render(this.config.wrapper);\n }\n\n shouldRender() {\n if (typeof paypal.Messages === 'undefined' || typeof this.config.wrapper === 'undefined') {\n return false;\n }\n\n if (!document.querySelector(this.config.wrapper)) {\n return false;\n }\n\n return true;\n }\n\n}\n\n/* harmony default export */ const Renderer_MessageRenderer = (MessageRenderer);\n;// CONCATENATED MODULE: ./resources/js/modules/Helper/Spinner.js\nclass Spinner {\n constructor(target = 'form.woocommerce-checkout') {\n this.target = target;\n }\n\n setTarget(target) {\n this.target = target;\n }\n\n block() {\n jQuery(this.target).block({\n message: null,\n overlayCSS: {\n background: '#fff',\n opacity: 0.6\n }\n });\n }\n\n unblock() {\n jQuery(this.target).unblock();\n }\n\n}\n\n/* harmony default export */ const Helper_Spinner = (Spinner);\n;// CONCATENATED MODULE: ./resources/js/button.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst buttonsSpinner = new Helper_Spinner('.ppc-button-wrapper');\n\nconst bootstrap = () => {\n const errorHandler = new modules_ErrorHandler(PayPalCommerceGateway.labels.error.generic);\n const spinner = new Helper_Spinner();\n const creditCardRenderer = new Renderer_CreditCardRenderer(PayPalCommerceGateway, errorHandler, spinner);\n\n const onSmartButtonClick = data => {\n window.ppcpFundingSource = data.fundingSource;\n };\n\n const onSmartButtonsInit = () => {\n buttonsSpinner.unblock();\n };\n\n const renderer = new Renderer_Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick, onSmartButtonsInit);\n const messageRenderer = new Renderer_MessageRenderer(PayPalCommerceGateway.messages);\n const context = PayPalCommerceGateway.context;\n\n if (context === 'mini-cart' || context === 'product') {\n if (PayPalCommerceGateway.mini_cart_buttons_enabled === '1') {\n const miniCartBootstrap = new ContextBootstrap_MiniCartBootstap(PayPalCommerceGateway, renderer);\n miniCartBootstrap.init();\n }\n }\n\n if (context === 'product' && PayPalCommerceGateway.single_product_buttons_enabled === '1') {\n const singleProductBootstrap = new ContextBootstrap_SingleProductBootstap(PayPalCommerceGateway, renderer, messageRenderer);\n singleProductBootstrap.init();\n }\n\n if (context === 'cart') {\n const cartBootstrap = new CartBootstap(PayPalCommerceGateway, renderer);\n cartBootstrap.init();\n }\n\n if (context === 'checkout') {\n const checkoutBootstap = new ContextBootstrap_CheckoutBootstap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n checkoutBootstap.init();\n }\n\n if (context === 'pay-now') {\n const payNowBootstrap = new ContextBootstrap_PayNowBootstrap(PayPalCommerceGateway, renderer, messageRenderer, spinner);\n payNowBootstrap.init();\n }\n\n if (context !== 'checkout') {\n messageRenderer.render();\n }\n};\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (!typeof PayPalCommerceGateway) {\n console.error('PayPal button could not be configured.');\n return;\n }\n\n if (PayPalCommerceGateway.context !== 'checkout' && PayPalCommerceGateway.data_client_id.user === 0 && PayPalCommerceGateway.data_client_id.has_subscriptions) {\n return;\n } // Sometimes PayPal script takes long time to load,\n // so we additionally hide the standard order button here to avoid failed orders.\n // Normally it is hidden later after the script load.\n\n\n const hideOrderButtonIfPpcpGateway = () => {\n // only in checkout and pay now page, otherwise it may break things (e.g. payment via product page),\n // and also the loading spinner may look weird on other pages\n if (!['checkout', 'pay-now'].includes(PayPalCommerceGateway.context) || isChangePaymentPage()) {\n return;\n }\n\n const currentPaymentMethod = getCurrentPaymentMethod();\n const isPaypal = currentPaymentMethod === PaymentMethods.PAYPAL;\n setVisible(ORDER_BUTTON_SELECTOR, !isPaypal, true);\n\n if (isPaypal) {\n // stopped after the first rendering of the buttons, in onInit\n buttonsSpinner.block();\n } else {\n buttonsSpinner.unblock();\n }\n };\n\n let bootstrapped = false;\n hideOrderButtonIfPpcpGateway();\n jQuery(document.body).on('updated_checkout payment_method_selected', () => {\n if (bootstrapped) {\n return;\n }\n\n hideOrderButtonIfPpcpGateway();\n });\n const script = document.createElement('script');\n script.addEventListener('load', event => {\n bootstrapped = true;\n bootstrap();\n });\n script.setAttribute('src', PayPalCommerceGateway.button.url);\n Object.entries(PayPalCommerceGateway.script_attributes).forEach(keyValue => {\n script.setAttribute(keyValue[0], keyValue[1]);\n });\n\n if (PayPalCommerceGateway.data_client_id.set_attribute) {\n DataClientIdAttributeHandler(script, PayPalCommerceGateway.data_client_id);\n return;\n }\n\n document.body.append(script);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LHFCQUFxQixDQUFDNlMsY0FBdEIsQ0FBcUNTLGFBQXpDLEVBQXdEO0FBQ3BEcEMsSUFBQUEsNEJBQTRCLENBQUNDLE1BQUQsRUFBU25SLHFCQUFxQixDQUFDNlMsY0FBL0IsQ0FBNUI7QUFDQTtBQUNIOztBQUVEN1csRUFBQUEsUUFBUSxDQUFDMkMsSUFBVCxDQUFjMkksTUFBZCxDQUFxQjZKLE1BQXJCO0FBQ0gsQ0F6RUwiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRXJyb3JIYW5kbGVyLmpzP2U2NWEiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanM/YzQ1NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1BheWVyRGF0YS5qcz8yYWYxIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyLmpzPzgyY2YiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvTWluaUNhcnRCb290c3RhcC5qcz9kNTUyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvVXBkYXRlQ2FydC5qcz9lNDIyIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyLmpzP2UxOTMiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0VudGl0eS9Qcm9kdWN0LmpzPzlmZmYiLCJ3ZWJwYWNrOi8vcHBjLWJ1dHRvbi8uL3Jlc291cmNlcy9qcy9tb2R1bGVzL0FjdGlvbkhhbmRsZXIvU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIuanM/ZDliNyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAuanM/N2MxOSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9DYXJ0Qm9vdHN0YXAuanM/NWU5NCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JQYXlOb3cuanM/OTMwNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQWN0aW9uSGFuZGxlci9DaGVja291dEFjdGlvbkhhbmRsZXIuanM/ODUxNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0hpZGluZy5qcz8xZDM2Iiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9IZWxwZXIvQ2hlY2tvdXRNZXRob2RTdGF0ZS5qcz84MGEzIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAuanM/Yzg1NSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1N1YnNjcmlwdGlvbnMuanM/Yjg3MCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9QYXlOb3dCb290c3RyYXAuanM/ZDlmNSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvUmVuZGVyZXIvUmVuZGVyZXIuanM/ZmE5MyIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL0RjY0lucHV0RmFjdG9yeS5qcz8yYTJmIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9DcmVkaXRDYXJkUmVuZGVyZXIuanM/Mzg3YSIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvRGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlci5qcz9lZTBiIiwid2VicGFjazovL3BwYy1idXR0b24vLi9yZXNvdXJjZXMvanMvbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXIuanM/Y2QwMiIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL21vZHVsZXMvSGVscGVyL1NwaW5uZXIuanM/MTcwOCIsIndlYnBhY2s6Ly9wcGMtYnV0dG9uLy4vcmVzb3VyY2VzL2pzL2J1dHRvbi5qcz8wNjBmIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEVycm9ySGFuZGxlciB7XG5cbiAgICBjb25zdHJ1Y3RvcihnZW5lcmljRXJyb3JUZXh0KVxuICAgIHtcbiAgICAgICAgdGhpcy5nZW5lcmljRXJyb3JUZXh0ID0gZ2VuZXJpY0Vycm9yVGV4dDtcbiAgICAgICAgdGhpcy53cmFwcGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLndvb2NvbW1lcmNlLW5vdGljZXMtd3JhcHBlcicpO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3VsLndvb2NvbW1lcmNlLWVycm9yJyk7XG4gICAgfVxuXG4gICAgZ2VuZXJpY0Vycm9yKCkge1xuICAgICAgICBpZiAodGhpcy53cmFwcGVyLmNsYXNzTGlzdC5jb250YWlucygncHBjcC1wZXJzaXN0JykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMubWVzc2FnZSh0aGlzLmdlbmVyaWNFcnJvclRleHQpXG4gICAgfVxuXG4gICAgYXBwZW5kUHJlcGFyZWRFcnJvck1lc3NhZ2VFbGVtZW50KGVycm9yTWVzc2FnZUVsZW1lbnQpXG4gICAge1xuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5wcmVwYXJlTWVzc2FnZXNMaXN0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5yZXBsYWNlV2l0aChlcnJvck1lc3NhZ2VFbGVtZW50KTtcbiAgICB9XG5cbiAgICBtZXNzYWdlKHRleHQsIHBlcnNpc3QgPSBmYWxzZSlcbiAgICB7XG4gICAgICAgIGlmKCEgdHlwZW9mIFN0cmluZyB8fCB0ZXh0Lmxlbmd0aCA9PT0gMCl7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgbmV3IG1lc3NhZ2UgdGV4dCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKHRoaXMubWVzc2FnZXNMaXN0ID09PSBudWxsKXtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBlcnNpc3QpIHtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QuYWRkKCdwcGNwLXBlcnNpc3QnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlci5jbGFzc0xpc3QucmVtb3ZlKCdwcGNwLXBlcnNpc3QnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBtZXNzYWdlTm9kZSA9IHRoaXMucHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0odGV4dCk7XG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LmFwcGVuZENoaWxkKG1lc3NhZ2VOb2RlKTtcblxuICAgICAgICBqUXVlcnkuc2Nyb2xsX3RvX25vdGljZXMoalF1ZXJ5KCcud29vY29tbWVyY2Utbm90aWNlcy13cmFwcGVyJykpXG4gICAgfVxuXG4gICAgcHJlcGFyZU1lc3NhZ2VzTGlzdCgpXG4gICAge1xuICAgICAgICBpZih0aGlzLm1lc3NhZ2VzTGlzdCA9PT0gbnVsbCl7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3VsJyk7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3dvb2NvbW1lcmNlLWVycm9yJyk7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VzTGlzdC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnYWxlcnQnKTtcbiAgICAgICAgICAgIHRoaXMud3JhcHBlci5hcHBlbmRDaGlsZCh0aGlzLm1lc3NhZ2VzTGlzdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcmVwYXJlTWVzc2FnZXNMaXN0SXRlbShtZXNzYWdlKVxuICAgIHtcbiAgICAgICAgY29uc3QgbGkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpO1xuICAgICAgICBsaS5pbm5lckhUTUwgPSBtZXNzYWdlO1xuXG4gICAgICAgIHJldHVybiBsaTtcbiAgICB9XG5cbiAgICBzYW5pdGl6ZSh0ZXh0KVxuICAgIHtcbiAgICAgICAgY29uc3QgdGV4dGFyZWEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xuICAgICAgICB0ZXh0YXJlYS5pbm5lckhUTUwgPSB0ZXh0O1xuICAgICAgICByZXR1cm4gdGV4dGFyZWEudmFsdWUucmVwbGFjZSgnRXJyb3I6ICcsICcnKTtcbiAgICB9XG5cbiAgICBjbGVhcigpXG4gICAge1xuICAgICAgICBpZiAodGhpcy5tZXNzYWdlc0xpc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWVzc2FnZXNMaXN0LmlubmVySFRNTCA9ICcnO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRXJyb3JIYW5kbGVyO1xuIiwiY29uc3Qgb25BcHByb3ZlID0gKGNvbnRleHQsIGVycm9ySGFuZGxlcikgPT4ge1xuICAgIHJldHVybiAoZGF0YSwgYWN0aW9ucykgPT4ge1xuICAgICAgICByZXR1cm4gZmV0Y2goY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICBub25jZTogY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgIG9yZGVyX2lkOmRhdGEub3JkZXJJRCxcbiAgICAgICAgICAgICAgICBmdW5kaW5nX3NvdXJjZTogd2luZG93LnBwY3BGdW5kaW5nU291cmNlLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgIH0pLnRoZW4oKGRhdGEpPT57XG4gICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5yZXN0YXJ0KCkuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGNvbnRleHQuY29uZmlnLnJlZGlyZWN0O1xuICAgICAgICB9KTtcblxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgb25BcHByb3ZlO1xuIiwiZXhwb3J0IGNvbnN0IHBheWVyRGF0YSA9ICgpID0+IHtcbiAgICBjb25zdCBwYXllciA9IFBheVBhbENvbW1lcmNlR2F0ZXdheS5wYXllcjtcbiAgICBpZiAoISBwYXllcikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwaG9uZSA9IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19waG9uZScpIHx8IHR5cGVvZiBwYXllci5waG9uZSAhPT0gJ3VuZGVmaW5lZCcpID9cbiAgICB7XG4gICAgICAgIHBob25lX3R5cGU6XCJIT01FXCIsXG4gICAgICAgICAgICBwaG9uZV9udW1iZXI6e1xuICAgICAgICAgICAgbmF0aW9uYWxfbnVtYmVyIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bob25lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcGhvbmUnKS52YWx1ZSA6IHBheWVyLnBob25lLnBob25lX251bWJlci5uYXRpb25hbF9udW1iZXJcbiAgICAgICAgfVxuICAgIH0gOiBudWxsO1xuICAgIGNvbnN0IHBheWVyRGF0YSA9IHtcbiAgICAgICAgZW1haWxfYWRkcmVzczooZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZW1haWwnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19lbWFpbCcpLnZhbHVlIDogcGF5ZXIuZW1haWxfYWRkcmVzcyxcbiAgICAgICAgbmFtZSA6IHtcbiAgICAgICAgICAgIHN1cm5hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19sYXN0X25hbWUnKS52YWx1ZSA6IHBheWVyLm5hbWUuc3VybmFtZSxcbiAgICAgICAgICAgIGdpdmVuX25hbWU6IChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19maXJzdF9uYW1lJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfZmlyc3RfbmFtZScpLnZhbHVlIDogcGF5ZXIubmFtZS5naXZlbl9uYW1lXG4gICAgICAgIH0sXG4gICAgICAgIGFkZHJlc3MgOiB7XG4gICAgICAgICAgICBjb3VudHJ5X2NvZGUgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfY291bnRyeScpKSA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NvdW50cnknKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuY291bnRyeV9jb2RlLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzEgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18xJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8xLFxuICAgICAgICAgICAgYWRkcmVzc19saW5lXzIgOiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfYWRkcmVzc18yJykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkZHJlc3NfbGluZV8yLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8xIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3N0YXRlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfc3RhdGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MuYWRtaW5fYXJlYV8xLFxuICAgICAgICAgICAgYWRtaW5fYXJlYV8yIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX2NpdHknKSkgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYmlsbGluZ19jaXR5JykudmFsdWUgOiBwYXllci5hZGRyZXNzLmFkbWluX2FyZWFfMixcbiAgICAgICAgICAgIHBvc3RhbF9jb2RlIDogKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNiaWxsaW5nX3Bvc3Rjb2RlJykpID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2JpbGxpbmdfcG9zdGNvZGUnKS52YWx1ZSA6IHBheWVyLmFkZHJlc3MucG9zdGFsX2NvZGVcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAocGhvbmUpIHtcbiAgICAgICAgcGF5ZXJEYXRhLnBob25lID0gcGhvbmU7XG4gICAgfVxuICAgIHJldHVybiBwYXllckRhdGE7XG59XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yQ29udGludWUuanMnO1xuaW1wb3J0IHtwYXllckRhdGF9IGZyb20gXCIuLi9IZWxwZXIvUGF5ZXJEYXRhXCI7XG5cbmNsYXNzIENhcnRBY3Rpb25IYW5kbGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZywgZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKCkge1xuICAgICAgICBjb25zdCBjcmVhdGVPcmRlciA9IChkYXRhLCBhY3Rpb25zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwYXllciA9IHBheWVyRGF0YSgpO1xuICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gOiAnJztcbiAgICAgICAgICAgIHJldHVybiBmZXRjaCh0aGlzLmNvbmZpZy5hamF4LmNyZWF0ZV9vcmRlci5lbmRwb2ludCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgbm9uY2U6IHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJuX2NvZGU6Ym5Db2RlLFxuICAgICAgICAgICAgICAgICAgICBwYXllcixcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOiBvbkFwcHJvdmUodGhpcywgdGhpcy5lcnJvckhhbmRsZXIpLFxuICAgICAgICAgICAgb25FcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIuZ2VuZXJpY0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDYXJ0QWN0aW9uSGFuZGxlcjtcbiIsImltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcbmltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcblxuY2xhc3MgTWluaUNhcnRCb290c3RhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLmFjdGlvbkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG5cbiAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbignd2NfZnJhZ21lbnRzX2xvYWRlZCB3Y19mcmFnbWVudHNfcmVmcmVzaGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLm1pbmlfY2FydF93cmFwcGVyKSAhPT0gbnVsbFxuICAgICAgICAgICAgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy5taW5pX2NhcnRfd3JhcHBlcikgIT09IG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmVuZGVyKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi5taW5pX2NhcnRfd3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLm1pbmlfY2FydF93cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5hY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKVxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWluaUNhcnRCb290c3RhcDtcbiIsImltcG9ydCBQcm9kdWN0IGZyb20gXCIuLi9FbnRpdHkvUHJvZHVjdFwiO1xuY2xhc3MgVXBkYXRlQ2FydCB7XG5cbiAgICBjb25zdHJ1Y3RvcihlbmRwb2ludCwgbm9uY2UpXG4gICAge1xuICAgICAgICB0aGlzLmVuZHBvaW50ID0gZW5kcG9pbnQ7XG4gICAgICAgIHRoaXMubm9uY2UgPSBub25jZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSBvblJlc29sdmVcbiAgICAgKiBAcGFyYW0ge1Byb2R1Y3RbXX0gcHJvZHVjdHNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx1bmtub3duPn1cbiAgICAgKi9cbiAgICB1cGRhdGUob25SZXNvbHZlLCBwcm9kdWN0cylcbiAgICB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBmZXRjaChcbiAgICAgICAgICAgICAgICB0aGlzLmVuZHBvaW50LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vbmNlOiB0aGlzLm5vbmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMsXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKS50aGVuKFxuICAgICAgICAgICAgICAgIChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0Lmpzb24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChyZXN1bHQuZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZWQgPSBvblJlc29sdmUocmVzdWx0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc29sdmVkKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICB9KTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVwZGF0ZUNhcnQ7IiwiLyoqXG4gKiBXaGVuIHlvdSBjYW4ndCBhZGQgc29tZXRoaW5nIHRvIHRoZSBjYXJ0LCB0aGUgUGF5UGFsIGJ1dHRvbnMgc2hvdWxkIG5vdCBzaG93LlxuICogVGhlcmVmb3JlIHdlIGxpc3RlbiBmb3IgY2hhbmdlcyBvbiB0aGUgYWRkIHRvIGNhcnQgYnV0dG9uIGFuZCBzaG93L2hpZGUgdGhlIGJ1dHRvbnMgYWNjb3JkaW5nbHkuXG4gKi9cblxuY2xhc3MgQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIHtcbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50LCBzaG93Q2FsbGJhY2ssIGhpZGVDYWxsYmFjaylcbiAgICB7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc2hvd0NhbGxiYWNrID0gc2hvd0NhbGxiYWNrO1xuICAgICAgICB0aGlzLmhpZGVDYWxsYmFjayA9IGhpZGVDYWxsYmFjaztcbiAgICAgICAgdGhpcy5vYnNlcnZlciA9IG51bGw7XG4gICAgfVxuXG4gICAgaW5pdCgpXG4gICAge1xuICAgICAgICBjb25zdCBjb25maWcgPSB7IGF0dHJpYnV0ZXMgOiB0cnVlIH07XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2Rpc2FibGVkJykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVDYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2hvd0NhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGNhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5vYnNlcnZlci5vYnNlcnZlKHRoaXMuZWxlbWVudCwgY29uZmlnKTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICBkaXNjb25uZWN0KClcbiAgICB7XG4gICAgICAgIHRoaXMub2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQnV0dG9uc1RvZ2dsZUxpc3RlbmVyOyIsImNsYXNzIFByb2R1Y3Qge1xuXG4gICAgY29uc3RydWN0b3IoaWQsIHF1YW50aXR5LCB2YXJpYXRpb25zKSB7XG4gICAgICAgIHRoaXMuaWQgPSBpZDtcbiAgICAgICAgdGhpcy5xdWFudGl0eSA9IHF1YW50aXR5O1xuICAgICAgICB0aGlzLnZhcmlhdGlvbnMgPSB2YXJpYXRpb25zO1xuICAgIH1cblxuICAgIGRhdGEoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpZDp0aGlzLmlkLFxuICAgICAgICAgICAgcXVhbnRpdHk6dGhpcy5xdWFudGl0eSxcbiAgICAgICAgICAgIHZhcmlhdGlvbnM6dGhpcy52YXJpYXRpb25zXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFByb2R1Y3Q7IiwiaW1wb3J0IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lciBmcm9tICcuLi9IZWxwZXIvQnV0dG9uc1RvZ2dsZUxpc3RlbmVyJztcbmltcG9ydCBQcm9kdWN0IGZyb20gJy4uL0VudGl0eS9Qcm9kdWN0JztcbmltcG9ydCBvbkFwcHJvdmUgZnJvbSAnLi4vT25BcHByb3ZlSGFuZGxlci9vbkFwcHJvdmVGb3JDb250aW51ZSc7XG5pbXBvcnQge3BheWVyRGF0YX0gZnJvbSBcIi4uL0hlbHBlci9QYXllckRhdGFcIjtcblxuY2xhc3MgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgdXBkYXRlQ2FydCxcbiAgICAgICAgc2hvd0J1dHRvbkNhbGxiYWNrLFxuICAgICAgICBoaWRlQnV0dG9uQ2FsbGJhY2ssXG4gICAgICAgIGZvcm1FbGVtZW50LFxuICAgICAgICBlcnJvckhhbmRsZXJcbiAgICApIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgICAgIHRoaXMudXBkYXRlQ2FydCA9IHVwZGF0ZUNhcnQ7XG4gICAgICAgIHRoaXMuc2hvd0J1dHRvbkNhbGxiYWNrID0gc2hvd0J1dHRvbkNhbGxiYWNrO1xuICAgICAgICB0aGlzLmhpZGVCdXR0b25DYWxsYmFjayA9IGhpZGVCdXR0b25DYWxsYmFjaztcbiAgICAgICAgdGhpcy5mb3JtRWxlbWVudCA9IGZvcm1FbGVtZW50O1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICB9XG5cbiAgICBjb25maWd1cmF0aW9uKClcbiAgICB7XG5cbiAgICAgICAgaWYgKCB0aGlzLmhhc1ZhcmlhdGlvbnMoKSApIHtcbiAgICAgICAgICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IEJ1dHRvbnNUb2dnbGVMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaW5nbGVfYWRkX3RvX2NhcnRfYnV0dG9uJyksXG4gICAgICAgICAgICAgICAgdGhpcy5zaG93QnV0dG9uQ2FsbGJhY2ssXG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlQnV0dG9uQ2FsbGJhY2tcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBvYnNlcnZlci5pbml0KCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3JlYXRlT3JkZXI6IHRoaXMuY3JlYXRlT3JkZXIoKSxcbiAgICAgICAgICAgIG9uQXBwcm92ZTogb25BcHByb3ZlKHRoaXMsIHRoaXMuZXJyb3JIYW5kbGVyKSxcbiAgICAgICAgICAgIG9uRXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY3JlYXRlT3JkZXIoKVxuICAgIHtcbiAgICAgICAgdmFyIGdldFByb2R1Y3RzID0gbnVsbDtcbiAgICAgICAgaWYgKCEgdGhpcy5pc0dyb3VwZWRQcm9kdWN0KCkgKSB7XG4gICAgICAgICAgICBnZXRQcm9kdWN0cyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ1tuYW1lPVwiYWRkLXRvLWNhcnRcIl0nKS52YWx1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBxdHkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbbmFtZT1cInF1YW50aXR5XCJdJykudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFyaWF0aW9ucyA9IHRoaXMudmFyaWF0aW9ucygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBbbmV3IFByb2R1Y3QoaWQsIHF0eSwgdmFyaWF0aW9ucyldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0UHJvZHVjdHMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvZHVjdHMgPSBbXTtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1FbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W3R5cGU9XCJudW1iZXJcIl0nKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIGVsZW1lbnQudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbGVtZW50TmFtZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCduYW1lJykubWF0Y2goL3F1YW50aXR5XFxbKFtcXGRdKilcXF0vKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnROYW1lLmxlbmd0aCAhPT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gcGFyc2VJbnQoZWxlbWVudE5hbWVbMV0pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWFudGl0eSA9IHBhcnNlSW50KGVsZW1lbnQudmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICBwcm9kdWN0cy5wdXNoKG5ldyBQcm9kdWN0KGlkLCBxdWFudGl0eSwgbnVsbCkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb2R1Y3RzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNyZWF0ZU9yZGVyID0gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG5cbiAgICAgICAgICAgIGNvbnN0IG9uUmVzb2x2ZSA9IChwdXJjaGFzZV91bml0cykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBheWVyID0gcGF5ZXJEYXRhKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgYm5Db2RlID0gdHlwZW9mIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnLmJuX2NvZGVzW3RoaXMuY29uZmlnLmNvbnRleHRdIDogJyc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZldGNoKHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdXJjaGFzZV91bml0cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgYm5fY29kZTpibkNvZGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0OnRoaXMuY29uZmlnLmNvbnRleHRcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWRhdGEuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKGRhdGEuZGF0YS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMudXBkYXRlQ2FydC51cGRhdGUob25SZXNvbHZlLCBnZXRQcm9kdWN0cygpKTtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gY3JlYXRlT3JkZXI7XG4gICAgfVxuXG4gICAgdmFyaWF0aW9ucygpXG4gICAge1xuXG4gICAgICAgIGlmICghIHRoaXMuaGFzVmFyaWF0aW9ucygpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0gWy4uLnRoaXMuZm9ybUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltuYW1lXj0nYXR0cmlidXRlXyddXCIpXS5tYXAoXG4gICAgICAgICAgICAoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6ZWxlbWVudC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZTplbGVtZW50Lm5hbWVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBhdHRyaWJ1dGVzO1xuICAgIH1cblxuICAgIGhhc1ZhcmlhdGlvbnMoKVxuICAgIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybUVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCd2YXJpYXRpb25zX2Zvcm0nKTtcbiAgICB9XG5cbiAgICBpc0dyb3VwZWRQcm9kdWN0KClcbiAgICB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1FbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnZ3JvdXBlZF9mb3JtJyk7XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXI7XG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgVXBkYXRlQ2FydCBmcm9tIFwiLi4vSGVscGVyL1VwZGF0ZUNhcnRcIjtcbmltcG9ydCBTaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlciBmcm9tIFwiLi4vQWN0aW9uSGFuZGxlci9TaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlclwiO1xuXG5jbGFzcyBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAge1xuICAgIGNvbnN0cnVjdG9yKGdhdGV3YXksIHJlbmRlcmVyLCBtZXNzYWdlcykge1xuICAgICAgICB0aGlzLmdhdGV3YXkgPSBnYXRld2F5O1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlcztcbiAgICB9XG5cblxuICAgIGhhbmRsZUNoYW5nZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG5cbiAgICBpbml0KCkge1xuXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuaGFuZGxlQ2hhbmdlLmJpbmQodGhpcykpXG5cbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcblxuICAgICAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0JykgIT09IG51bGwgJiYgIXRoaXMucHJpY2VBbW91bnRJc1plcm8oKTtcblxuICAgIH1cblxuICAgIHByaWNlQW1vdW50SXNaZXJvKCkge1xuXG4gICAgICAgIGxldCBwcmljZVRleHQgPSBcIjBcIjtcbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCBpbnMgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpKSB7XG4gICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgaW5zIC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgcHJpY2VUZXh0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKS5pbm5lclRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnByb2R1Y3QgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpKSB7XG4gICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucHJvZHVjdCAud29vY29tbWVyY2UtUHJpY2UtYW1vdW50JykuaW5uZXJUZXh0O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlRmxvYXQocHJpY2VUZXh0LnJlcGxhY2UoLyhbXlxcZCxcXC5cXHNdKikvZywgJycpKTtcbiAgICAgICAgcmV0dXJuIGFtb3VudCA9PT0gMDtcblxuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgYWN0aW9uSGFuZGxlciA9IG5ldyBTaW5nbGVQcm9kdWN0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBVcGRhdGVDYXJ0KFxuICAgICAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5hamF4LmNoYW5nZV9jYXJ0LmVuZHBvaW50LFxuICAgICAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5hamF4LmNoYW5nZV9jYXJ0Lm5vbmNlLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLnNob3dCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5zaG93QnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgICAgICBsZXQgcHJpY2VUZXh0ID0gXCIwXCI7XG4gICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCBpbnMgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIHByaWNlVGV4dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2Zvcm0uY2FydCBpbnMgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpLmlubmVyVGV4dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9ybS5jYXJ0IC53b29jb21tZXJjZS1QcmljZS1hbW91bnQnKSkge1xuICAgICAgICAgICAgICAgICAgICBwcmljZVRleHQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQgLndvb2NvbW1lcmNlLVByaWNlLWFtb3VudCcpLmlubmVyVGV4dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgYW1vdW50ID0gcGFyc2VJbnQocHJpY2VUZXh0LnJlcGxhY2UoLyhbXlxcZCxcXC5cXHNdKikvZywgJycpKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnJlbmRlcldpdGhBbW91bnQoYW1vdW50KVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmhpZGVCdXR0b25zKHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5oaWRlQnV0dG9ucyh0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdmb3JtLmNhcnQnKSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcihcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5idXR0b24ud3JhcHBlcixcbiAgICAgICAgICAgIHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsXG4gICAgICAgICAgICBhY3Rpb25IYW5kbGVyLmNvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNpbmdsZVByb2R1Y3RCb290c3RhcDtcbiIsImltcG9ydCBDYXJ0QWN0aW9uSGFuZGxlciBmcm9tICcuLi9BY3Rpb25IYW5kbGVyL0NhcnRBY3Rpb25IYW5kbGVyJztcbmltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi4vRXJyb3JIYW5kbGVyJztcblxuY2xhc3MgQ2FydEJvb3RzdHJhcCB7XG4gICAgY29uc3RydWN0b3IoZ2F0ZXdheSwgcmVuZGVyZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG4gICAgICAgIGlmICghdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3VwZGF0ZWRfY2FydF90b3RhbHMgdXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHNob3VsZFJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuaG9zdGVkX2ZpZWxkcy53cmFwcGVyKSAhPT1cbiAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IENhcnRBY3Rpb25IYW5kbGVyKFxuICAgICAgICAgICAgUGF5UGFsQ29tbWVyY2VHYXRld2F5LFxuICAgICAgICAgICAgbmV3IEVycm9ySGFuZGxlcih0aGlzLmdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2FydEJvb3RzdHJhcDtcbiIsImNvbnN0IG9uQXBwcm92ZSA9IChjb250ZXh0LCBlcnJvckhhbmRsZXIsIHNwaW5uZXIpID0+IHtcbiAgICByZXR1cm4gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgc3Bpbm5lci5ibG9jaygpO1xuICAgICAgICBlcnJvckhhbmRsZXIuY2xlYXIoKTtcblxuICAgICAgICByZXR1cm4gZmV0Y2goY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICBub25jZTogY29udGV4dC5jb25maWcuYWpheC5hcHByb3ZlX29yZGVyLm5vbmNlLFxuICAgICAgICAgICAgICAgIG9yZGVyX2lkOmRhdGEub3JkZXJJRCxcbiAgICAgICAgICAgICAgICBmdW5kaW5nX3NvdXJjZTogd2luZG93LnBwY3BGdW5kaW5nU291cmNlLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICAgICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gICAgICAgIH0pLnRoZW4oKGRhdGEpPT57XG4gICAgICAgICAgICBzcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuZGF0YS5jb2RlID09PSAxMDApIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLm1lc3NhZ2UoZGF0YS5kYXRhLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5nZW5lcmljRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhY3Rpb25zICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgYWN0aW9ucy5yZXN0YXJ0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9ucy5yZXN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihkYXRhLmRhdGEubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcGxhY2Vfb3JkZXInKS5jbGljaygpXG4gICAgICAgIH0pO1xuXG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBvbkFwcHJvdmU7XG4iLCJpbXBvcnQgb25BcHByb3ZlIGZyb20gJy4uL09uQXBwcm92ZUhhbmRsZXIvb25BcHByb3ZlRm9yUGF5Tm93LmpzJztcbmltcG9ydCB7cGF5ZXJEYXRhfSBmcm9tIFwiLi4vSGVscGVyL1BheWVyRGF0YVwiO1xuXG5jbGFzcyBDaGVja291dEFjdGlvbkhhbmRsZXIge1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnLCBlcnJvckhhbmRsZXIsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gZXJyb3JIYW5kbGVyO1xuICAgICAgICB0aGlzLnNwaW5uZXIgPSBzcGlubmVyO1xuICAgIH1cblxuICAgIGNvbmZpZ3VyYXRpb24oKSB7XG4gICAgICAgIGNvbnN0IHNwaW5uZXIgPSB0aGlzLnNwaW5uZXI7XG4gICAgICAgIGNvbnN0IGNyZWF0ZU9yZGVyID0gKGRhdGEsIGFjdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBheWVyID0gcGF5ZXJEYXRhKCk7XG4gICAgICAgICAgICBjb25zdCBibkNvZGUgPSB0eXBlb2YgdGhpcy5jb25maWcuYm5fY29kZXNbdGhpcy5jb25maWcuY29udGV4dF0gIT09ICd1bmRlZmluZWQnID9cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5ibl9jb2Rlc1t0aGlzLmNvbmZpZy5jb250ZXh0XSA6ICcnO1xuXG4gICAgICAgICAgICBjb25zdCBlcnJvckhhbmRsZXIgPSB0aGlzLmVycm9ySGFuZGxlcjtcblxuICAgICAgICAgICAgY29uc3QgZm9ybVNlbGVjdG9yID0gdGhpcy5jb25maWcuY29udGV4dCA9PT0gJ2NoZWNrb3V0JyA/ICdmb3JtLmNoZWNrb3V0JyA6ICdmb3JtI29yZGVyX3Jldmlldyc7XG4gICAgICAgICAgICBjb25zdCBmb3JtVmFsdWVzID0galF1ZXJ5KGZvcm1TZWxlY3Rvcikuc2VyaWFsaXplKCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWFjY291bnQgPSBqUXVlcnkoJyNjcmVhdGVhY2NvdW50JykuaXMoXCI6Y2hlY2tlZFwiKSA/IHRydWUgOiBmYWxzZTtcblxuICAgICAgICAgICAgcmV0dXJuIGZldGNoKHRoaXMuY29uZmlnLmFqYXguY3JlYXRlX29yZGVyLmVuZHBvaW50LCB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICBub25jZTogdGhpcy5jb25maWcuYWpheC5jcmVhdGVfb3JkZXIubm9uY2UsXG4gICAgICAgICAgICAgICAgICAgIHBheWVyLFxuICAgICAgICAgICAgICAgICAgICBibl9jb2RlOmJuQ29kZSxcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDp0aGlzLmNvbmZpZy5jb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICBvcmRlcl9pZDp0aGlzLmNvbmZpZy5vcmRlcl9pZCxcbiAgICAgICAgICAgICAgICAgICAgZm9ybTpmb3JtVmFsdWVzLFxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVhY2NvdW50OiBjcmVhdGVhY2NvdW50XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXMuanNvbigpO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIGlmICghZGF0YS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgICAgICAvL2hhbmRsZSBib3RoIG1lc3NhZ2VzIHNlbnQgZnJvbSBXb29jb21tZXJjZSAoZGF0YS5tZXNzYWdlcykgYW5kIHRoaXMgcGx1Z2luIChkYXRhLmRhdGEubWVzc2FnZSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZihkYXRhLm1lc3NhZ2VzKSAhPT0gJ3VuZGVmaW5lZCcgKVxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkb21QYXJzZXIgPSBuZXcgRE9NUGFyc2VyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckhhbmRsZXIuYXBwZW5kUHJlcGFyZWRFcnJvck1lc3NhZ2VFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbVBhcnNlci5wYXJzZUZyb21TdHJpbmcoZGF0YS5tZXNzYWdlcywgJ3RleHQvaHRtbCcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5xdWVyeVNlbGVjdG9yKCd1bCcpXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLmNsZWFyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5kYXRhLmRldGFpbHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ySGFuZGxlci5tZXNzYWdlKGRhdGEuZGF0YS5kZXRhaWxzLm1hcChkID0+IGAke2QuaXNzdWV9ICR7ZC5kZXNjcmlwdGlvbn1gKS5qb2luKCc8YnIvPicpLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JIYW5kbGVyLm1lc3NhZ2UoZGF0YS5kYXRhLm1lc3NhZ2UsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCd0eXBlJywgJ2hpZGRlbicpO1xuICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnbmFtZScsICdwcGNwLXJlc3VtZS1vcmRlcicpO1xuICAgICAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgndmFsdWUnLCBkYXRhLmRhdGEucHVyY2hhc2VfdW5pdHNbMF0uY3VzdG9tX2lkKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1TZWxlY3RvcikuYXBwZW5kKGlucHV0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhLmlkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgb25BcHByb3ZlOm9uQXBwcm92ZSh0aGlzLCB0aGlzLmVycm9ySGFuZGxlciwgdGhpcy5zcGlubmVyKSxcbiAgICAgICAgICAgIG9uQ2FuY2VsOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgc3Bpbm5lci51bmJsb2NrKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb25FcnJvcjogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmdlbmVyaWNFcnJvcigpO1xuICAgICAgICAgICAgICAgIHNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGVja291dEFjdGlvbkhhbmRsZXI7XG4iLCJjb25zdCBnZXRFbGVtZW50ID0gKHNlbGVjdG9yT3JFbGVtZW50KSA9PiB7XG4gICAgaWYgKHR5cGVvZiBzZWxlY3Rvck9yRWxlbWVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3JPckVsZW1lbnQpO1xuICAgIH1cbiAgICByZXR1cm4gc2VsZWN0b3JPckVsZW1lbnQ7XG59XG5cbmV4cG9ydCBjb25zdCBpc1Zpc2libGUgPSAoZWxlbWVudCkgPT4ge1xuICAgIHJldHVybiAhIShlbGVtZW50Lm9mZnNldFdpZHRoIHx8IGVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IGVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGgpO1xufVxuXG5leHBvcnQgY29uc3Qgc2V0VmlzaWJsZSA9IChzZWxlY3Rvck9yRWxlbWVudCwgc2hvdywgaW1wb3J0YW50ID0gZmFsc2UpID0+IHtcbiAgICBjb25zdCBlbGVtZW50ID0gZ2V0RWxlbWVudChzZWxlY3Rvck9yRWxlbWVudCk7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSBlbGVtZW50LnN0eWxlLmdldFByb3BlcnR5VmFsdWUoJ2Rpc3BsYXknKTtcblxuICAgIGlmICghc2hvdykge1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlID09PSAnbm9uZScpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJ2Rpc3BsYXknLCAnbm9uZScsIGltcG9ydGFudCA/ICdpbXBvcnRhbnQnIDogJycpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPT09ICdub25lJykge1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgnZGlzcGxheScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gc3RpbGwgbm90IHZpc2libGUgKGlmIHNvbWV0aGluZyBlbHNlIGFkZGVkIGRpc3BsYXk6IG5vbmUgaW4gQ1NTKVxuICAgICAgICBpZiAoIWlzVmlzaWJsZShlbGVtZW50KSkge1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnZGlzcGxheScsICdibG9jaycpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGhpZGUgPSAoc2VsZWN0b3JPckVsZW1lbnQsIGltcG9ydGFudCA9IGZhbHNlKSA9PiB7XG4gICAgc2V0VmlzaWJsZShzZWxlY3Rvck9yRWxlbWVudCwgZmFsc2UsIGltcG9ydGFudCk7XG59O1xuXG5leHBvcnQgY29uc3Qgc2hvdyA9IChzZWxlY3Rvck9yRWxlbWVudCkgPT4ge1xuICAgIHNldFZpc2libGUoc2VsZWN0b3JPckVsZW1lbnQsIHRydWUpO1xufTtcbiIsImV4cG9ydCBjb25zdCBQYXltZW50TWV0aG9kcyA9IHtcbiAgICBQQVlQQUw6ICdwcGNwLWdhdGV3YXknLFxuICAgIENBUkRTOiAncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5Jyxcbn07XG5cbmV4cG9ydCBjb25zdCBPUkRFUl9CVVRUT05fU0VMRUNUT1IgPSAnI3BsYWNlX29yZGVyJztcblxuZXhwb3J0IGNvbnN0IGdldEN1cnJlbnRQYXltZW50TWV0aG9kID0gKCkgPT4ge1xuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT1cInBheW1lbnRfbWV0aG9kXCJdOmNoZWNrZWQnKTtcbiAgICBpZiAoIWVsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBlbC52YWx1ZTtcbn07XG5cbmV4cG9ydCBjb25zdCBpc1NhdmVkQ2FyZFNlbGVjdGVkID0gKCkgPT4ge1xuICAgIGNvbnN0IHNhdmVkQ2FyZExpc3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2F2ZWQtY3JlZGl0LWNhcmQnKTtcbiAgICByZXR1cm4gc2F2ZWRDYXJkTGlzdCAmJiBzYXZlZENhcmRMaXN0LnZhbHVlICE9PSAnJztcbn07XG4iLCJpbXBvcnQgRXJyb3JIYW5kbGVyIGZyb20gJy4uL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ2hlY2tvdXRBY3Rpb25IYW5kbGVyIGZyb20gJy4uL0FjdGlvbkhhbmRsZXIvQ2hlY2tvdXRBY3Rpb25IYW5kbGVyJztcbmltcG9ydCB7IHNldFZpc2libGUgfSBmcm9tICcuLi9IZWxwZXIvSGlkaW5nJztcbmltcG9ydCB7XG4gICAgZ2V0Q3VycmVudFBheW1lbnRNZXRob2QsXG4gICAgaXNTYXZlZENhcmRTZWxlY3RlZCwgT1JERVJfQlVUVE9OX1NFTEVDVE9SLFxuICAgIFBheW1lbnRNZXRob2RzXG59IGZyb20gXCIuLi9IZWxwZXIvQ2hlY2tvdXRNZXRob2RTdGF0ZVwiO1xuXG5jbGFzcyBDaGVja291dEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgdGhpcy5nYXRld2F5ID0gZ2F0ZXdheTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgICB0aGlzLm1lc3NhZ2VzID0gbWVzc2FnZXM7XG4gICAgICAgIHRoaXMuc3Bpbm5lciA9IHNwaW5uZXI7XG5cbiAgICAgICAgdGhpcy5zdGFuZGFyZE9yZGVyQnV0dG9uU2VsZWN0b3IgPSBPUkRFUl9CVVRUT05fU0VMRUNUT1I7XG5cbiAgICAgICAgdGhpcy5idXR0b25DaGFuZ2VPYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChlbCkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBpbml0KCkge1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuXG4gICAgICAgIC8vIFVuc2VsZWN0IHNhdmVkIGNhcmQuXG4gICAgICAgIC8vIFdDIHNhdmVzIGZvcm0gdmFsdWVzLCBzbyB3aXRoIG91ciBjdXJyZW50IFVJIGl0IHdvdWxkIGJlIGEgYml0IHdlaXJkXG4gICAgICAgIC8vIGlmIHRoZSB1c2VyIHBhaWQgd2l0aCBzYXZlZCwgdGhlbiBhZnRlciBzb21lIHRpbWUgdHJpZXMgdG8gcGF5IGFnYWluLFxuICAgICAgICAvLyBidXQgd2FudHMgdG8gZW50ZXIgYSBuZXcgY2FyZCwgYW5kIHRvIGRvIHRoYXQgdGhleSBoYXZlIHRvIGNob29zZSDigJxTZWxlY3QgcGF5bWVudOKAnSBpbiB0aGUgbGlzdC5cbiAgICAgICAgalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQnKS52YWwoalF1ZXJ5KCcjc2F2ZWQtY3JlZGl0LWNhcmQgb3B0aW9uOmZpcnN0JykudmFsKCkpO1xuXG4gICAgICAgIGpRdWVyeShkb2N1bWVudC5ib2R5KS5vbigndXBkYXRlZF9jaGVja291dCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKClcbiAgICAgICAgfSk7XG5cbiAgICAgICAgalF1ZXJ5KGRvY3VtZW50LmJvZHkpLm9uKCd1cGRhdGVkX2NoZWNrb3V0IHBheW1lbnRfbWV0aG9kX3NlbGVjdGVkJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVVaSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQpLm9uKCdob3N0ZWRfZmllbGRzX2xvYWRlZCcsICgpID0+IHtcbiAgICAgICAgICAgIGpRdWVyeSgnI3NhdmVkLWNyZWRpdC1jYXJkJykub24oJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVVpKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnVwZGF0ZVVpKCk7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmdhdGV3YXkuYnV0dG9uLmNhbmNlbF93cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyKSAhPT0gbnVsbCB8fCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIpICE9PSBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnNob3VsZFJlbmRlcigpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2JykpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlciArICc+ZGl2Jykuc2V0QXR0cmlidXRlKCdzdHlsZScsICcnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhY3Rpb25IYW5kbGVyID0gbmV3IENoZWNrb3V0QWN0aW9uSGFuZGxlcihcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIG5ldyBFcnJvckhhbmRsZXIodGhpcy5nYXRld2F5LmxhYmVscy5lcnJvci5nZW5lcmljKSxcbiAgICAgICAgICAgIHRoaXMuc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVuZGVyKFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5LmJ1dHRvbi53cmFwcGVyLFxuICAgICAgICAgICAgdGhpcy5nYXRld2F5Lmhvc3RlZF9maWVsZHMud3JhcHBlcixcbiAgICAgICAgICAgIGFjdGlvbkhhbmRsZXIuY29uZmlndXJhdGlvbigpLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuYnV0dG9uQ2hhbmdlT2JzZXJ2ZXIub2JzZXJ2ZShcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5zdGFuZGFyZE9yZGVyQnV0dG9uU2VsZWN0b3IpLFxuICAgICAgICAgICAge2F0dHJpYnV0ZXM6IHRydWV9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgdXBkYXRlVWkoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0gZ2V0Q3VycmVudFBheW1lbnRNZXRob2QoKTtcbiAgICAgICAgY29uc3QgaXNQYXlwYWwgPSBjdXJyZW50UGF5bWVudE1ldGhvZCA9PT0gUGF5bWVudE1ldGhvZHMuUEFZUEFMO1xuICAgICAgICBjb25zdCBpc0NhcmQgPSBjdXJyZW50UGF5bWVudE1ldGhvZCA9PT0gUGF5bWVudE1ldGhvZHMuQ0FSRFM7XG4gICAgICAgIGNvbnN0IGlzU2F2ZWRDYXJkID0gaXNDYXJkICYmIGlzU2F2ZWRDYXJkU2VsZWN0ZWQoKTtcbiAgICAgICAgY29uc3QgaXNOb3RPdXJHYXRld2F5ID0gIWlzUGF5cGFsICYmICFpc0NhcmQ7XG5cbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLnN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciwgaXNOb3RPdXJHYXRld2F5IHx8IGlzU2F2ZWRDYXJkLCB0cnVlKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkuYnV0dG9uLndyYXBwZXIsIGlzUGF5cGFsKTtcbiAgICAgICAgc2V0VmlzaWJsZSh0aGlzLmdhdGV3YXkubWVzc2FnZXMud3JhcHBlciwgaXNQYXlwYWwpO1xuICAgICAgICBzZXRWaXNpYmxlKHRoaXMuZ2F0ZXdheS5ob3N0ZWRfZmllbGRzLndyYXBwZXIsIGlzQ2FyZCAmJiAhaXNTYXZlZENhcmQpO1xuXG4gICAgICAgIGlmIChpc1BheXBhbCkge1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5yZW5kZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0NhcmQpIHtcbiAgICAgICAgICAgIGlmIChpc1NhdmVkQ2FyZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVDcmVkaXRDYXJkRmllbGRzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkaXNhYmxlQ3JlZGl0Q2FyZEZpZWxkcygpIHtcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXJcIl0nKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXInKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeVwiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjXCJdJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJykuYWRkQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJ2YXVsdFwiXScpLmFkZENsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5hZGRDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykuYXR0cihcImRpc2FibGVkXCIsIHRydWUpXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZGlzYWJsZUNyZWRpdENhcmRGaWVsZHMoKVxuICAgIH1cblxuICAgIGVuYWJsZUNyZWRpdENhcmRGaWVsZHMoKSB7XG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwicHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXCJdJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyJykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCdsYWJlbFtmb3I9XCJwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnlcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1leHBpcnknKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJ2xhYmVsW2Zvcj1cInBwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2Y1wiXScpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycpLnJlbW92ZUNsYXNzKCdwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktZm9ybS1maWVsZC1kaXNhYmxlZCcpXG4gICAgICAgIGpRdWVyeSgnbGFiZWxbZm9yPVwidmF1bHRcIl0nKS5yZW1vdmVDbGFzcygncHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWZvcm0tZmllbGQtZGlzYWJsZWQnKVxuICAgICAgICBqUXVlcnkoJyNwcGNwLWNyZWRpdC1jYXJkLXZhdWx0JykucmVtb3ZlQ2xhc3MoJ3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1mb3JtLWZpZWxkLWRpc2FibGVkJylcbiAgICAgICAgalF1ZXJ5KCcjcHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpLmF0dHIoXCJkaXNhYmxlZFwiLCBmYWxzZSlcbiAgICAgICAgdGhpcy5yZW5kZXJlci5lbmFibGVDcmVkaXRDYXJkRmllbGRzKClcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENoZWNrb3V0Qm9vdHN0YXBcbiIsImV4cG9ydCBjb25zdCBpc0NoYW5nZVBheW1lbnRQYWdlID0gKCkgPT4ge1xuICAgIGNvbnN0IHVybFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaClcbiAgICByZXR1cm4gdXJsUGFyYW1zLmhhcygnY2hhbmdlX3BheW1lbnRfbWV0aG9kJyk7XG59XG4iLCJpbXBvcnQgQ2hlY2tvdXRCb290c3RhcCBmcm9tICcuL0NoZWNrb3V0Qm9vdHN0YXAnXG5pbXBvcnQge2lzQ2hhbmdlUGF5bWVudFBhZ2V9IGZyb20gXCIuLi9IZWxwZXIvU3Vic2NyaXB0aW9uc1wiO1xuXG5jbGFzcyBQYXlOb3dCb290c3RyYXAgZXh0ZW5kcyBDaGVja291dEJvb3RzdGFwIHtcbiAgICBjb25zdHJ1Y3RvcihnYXRld2F5LCByZW5kZXJlciwgbWVzc2FnZXMsIHNwaW5uZXIpIHtcbiAgICAgICAgc3VwZXIoZ2F0ZXdheSwgcmVuZGVyZXIsIG1lc3NhZ2VzLCBzcGlubmVyKVxuICAgIH1cblxuICAgIHVwZGF0ZVVpKCkge1xuICAgICAgICBpZiAoaXNDaGFuZ2VQYXltZW50UGFnZSgpKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIHN1cGVyLnVwZGF0ZVVpKCk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQYXlOb3dCb290c3RyYXA7XG4iLCJjbGFzcyBSZW5kZXJlciB7XG4gICAgY29uc3RydWN0b3IoY3JlZGl0Q2FyZFJlbmRlcmVyLCBkZWZhdWx0Q29uZmlnLCBvblNtYXJ0QnV0dG9uQ2xpY2ssIG9uU21hcnRCdXR0b25zSW5pdCkge1xuICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcgPSBkZWZhdWx0Q29uZmlnO1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlciA9IGNyZWRpdENhcmRSZW5kZXJlcjtcbiAgICAgICAgdGhpcy5vblNtYXJ0QnV0dG9uQ2xpY2sgPSBvblNtYXJ0QnV0dG9uQ2xpY2s7XG4gICAgICAgIHRoaXMub25TbWFydEJ1dHRvbnNJbml0ID0gb25TbWFydEJ1dHRvbnNJbml0O1xuICAgIH1cblxuICAgIHJlbmRlcih3cmFwcGVyLCBob3N0ZWRGaWVsZHNXcmFwcGVyLCBjb250ZXh0Q29uZmlnKSB7XG5cbiAgICAgICAgdGhpcy5yZW5kZXJCdXR0b25zKHdyYXBwZXIsIGNvbnRleHRDb25maWcpO1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5yZW5kZXIoaG9zdGVkRmllbGRzV3JhcHBlciwgY29udGV4dENvbmZpZyk7XG4gICAgfVxuXG4gICAgcmVuZGVyQnV0dG9ucyh3cmFwcGVyLCBjb250ZXh0Q29uZmlnKSB7XG4gICAgICAgIGlmICghIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikgfHwgdGhpcy5pc0FscmVhZHlSZW5kZXJlZCh3cmFwcGVyKSB8fCAndW5kZWZpbmVkJyA9PT0gdHlwZW9mIHBheXBhbC5CdXR0b25zICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3R5bGUgPSB3cmFwcGVyID09PSB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLndyYXBwZXIgPyB0aGlzLmRlZmF1bHRDb25maWcuYnV0dG9uLnN0eWxlIDogdGhpcy5kZWZhdWx0Q29uZmlnLmJ1dHRvbi5taW5pX2NhcnRfc3R5bGU7XG4gICAgICAgIHBheXBhbC5CdXR0b25zKHtcbiAgICAgICAgICAgIHN0eWxlLFxuICAgICAgICAgICAgLi4uY29udGV4dENvbmZpZyxcbiAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMub25TbWFydEJ1dHRvbkNsaWNrLFxuICAgICAgICAgICAgb25Jbml0OiB0aGlzLm9uU21hcnRCdXR0b25zSW5pdCxcbiAgICAgICAgfSkucmVuZGVyKHdyYXBwZXIpO1xuICAgIH1cblxuICAgIGlzQWxyZWFkeVJlbmRlcmVkKHdyYXBwZXIpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcikuaGFzQ2hpbGROb2RlcygpO1xuICAgIH1cblxuICAgIGhpZGVCdXR0b25zKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZG9tRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgICAgIGlmICghIGRvbUVsZW1lbnQgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZG9tRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBzaG93QnV0dG9ucyhlbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGRvbUVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsZW1lbnQpO1xuICAgICAgICBpZiAoISBkb21FbGVtZW50ICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGRvbUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGRpc2FibGVDcmVkaXRDYXJkRmllbGRzKCkge1xuICAgICAgICB0aGlzLmNyZWRpdENhcmRSZW5kZXJlci5kaXNhYmxlRmllbGRzKCk7XG4gICAgfVxuXG4gICAgZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcygpIHtcbiAgICAgICAgdGhpcy5jcmVkaXRDYXJkUmVuZGVyZXIuZW5hYmxlRmllbGRzKCk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSZW5kZXJlcjtcbiIsImNvbnN0IGRjY0lucHV0RmFjdG9yeSA9IChvcmlnaW5hbCkgPT4ge1xuICAgIGNvbnN0IHN0eWxlcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKG9yaWdpbmFsKTtcbiAgICBjb25zdCBuZXdFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIG5ld0VsZW1lbnQuc2V0QXR0cmlidXRlKCdpZCcsIG9yaWdpbmFsLmlkKTtcbiAgICBPYmplY3QudmFsdWVzKHN0eWxlcykuZm9yRWFjaCggKHByb3ApID0+IHtcbiAgICAgICAgaWYgKCEgc3R5bGVzW3Byb3BdIHx8ICEgaXNOYU4ocHJvcCkgKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbmV3RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eShwcm9wLCcnICsgc3R5bGVzW3Byb3BdKTtcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3RWxlbWVudDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZGNjSW5wdXRGYWN0b3J5OyIsImltcG9ydCBkY2NJbnB1dEZhY3RvcnkgZnJvbSBcIi4uL0hlbHBlci9EY2NJbnB1dEZhY3RvcnlcIjtcblxuY2xhc3MgQ3JlZGl0Q2FyZFJlbmRlcmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKGRlZmF1bHRDb25maWcsIGVycm9ySGFuZGxlciwgc3Bpbm5lcikge1xuICAgICAgICB0aGlzLmRlZmF1bHRDb25maWcgPSBkZWZhdWx0Q29uZmlnO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlciA9IGVycm9ySGFuZGxlcjtcbiAgICAgICAgdGhpcy5zcGlubmVyID0gc3Bpbm5lcjtcbiAgICAgICAgdGhpcy5jYXJkVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5mb3JtVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UgPSBudWxsO1xuICAgIH1cblxuICAgIHJlbmRlcih3cmFwcGVyLCBjb250ZXh0Q29uZmlnKSB7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgKFxuICAgICAgICAgICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZy5jb250ZXh0ICE9PSAnY2hlY2tvdXQnXG4gICAgICAgICAgICAgICAgJiYgdGhpcy5kZWZhdWx0Q29uZmlnLmNvbnRleHQgIT09ICdwYXktbm93J1xuICAgICAgICAgICAgKVxuICAgICAgICAgICAgfHwgd3JhcHBlciA9PT0gbnVsbFxuICAgICAgICAgICAgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKSA9PT0gbnVsbFxuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlb2YgcGF5cGFsLkhvc3RlZEZpZWxkcyA9PT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgIHx8ICEgcGF5cGFsLkhvc3RlZEZpZWxkcy5pc0VsaWdpYmxlKClcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVyRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Iod3JhcHBlcik7XG4gICAgICAgICAgICB3cmFwcGVyRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHdyYXBwZXJFbGVtZW50KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UudGVhcmRvd24oKVxuICAgICAgICAgICAgICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihgSG9zdGVkIGZpZWxkcyB0ZWFyZG93biBlcnJvcjogJHtlcnJ9YCkpO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZ2F0ZVdheUJveCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wYXltZW50X2JveC5wYXltZW50X21ldGhvZF9wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKTtcbiAgICAgICAgY29uc3Qgb2xkRGlzcGxheVN0eWxlID0gZ2F0ZVdheUJveC5zdHlsZS5kaXNwbGF5O1xuICAgICAgICBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXG4gICAgICAgIGNvbnN0IGhpZGVEY2NHYXRld2F5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtaGlkZS1kY2MnKTtcbiAgICAgICAgaWYgKGhpZGVEY2NHYXRld2F5KSB7XG4gICAgICAgICAgICBoaWRlRGNjR2F0ZXdheS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGhpZGVEY2NHYXRld2F5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNhcmROdW1iZXJGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXktY2FyZC1udW1iZXInKTtcblxuICAgICAgICBjb25zdCBzdHlsZXNSYXcgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShjYXJkTnVtYmVyRmllbGQpO1xuICAgICAgICBsZXQgc3R5bGVzID0ge307XG4gICAgICAgIE9iamVjdC52YWx1ZXMoc3R5bGVzUmF3KS5mb3JFYWNoKCAocHJvcCkgPT4ge1xuICAgICAgICAgICAgaWYgKCEgc3R5bGVzUmF3W3Byb3BdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3R5bGVzW3Byb3BdID0gJycgKyBzdHlsZXNSYXdbcHJvcF07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNhcmROdW1iZXIgPSBkY2NJbnB1dEZhY3RvcnkoY2FyZE51bWJlckZpZWxkKTtcbiAgICAgICAgY2FyZE51bWJlckZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmROdW1iZXIsIGNhcmROdW1iZXJGaWVsZCk7XG5cbiAgICAgICAgY29uc3QgY2FyZEV4cGlyeUZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWV4cGlyeScpO1xuICAgICAgICBjb25zdCBjYXJkRXhwaXJ5ID0gZGNjSW5wdXRGYWN0b3J5KGNhcmRFeHBpcnlGaWVsZCk7XG4gICAgICAgIGNhcmRFeHBpcnlGaWVsZC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjYXJkRXhwaXJ5LCBjYXJkRXhwaXJ5RmllbGQpO1xuXG4gICAgICAgIGNvbnN0IGNhcmRDb2RlRmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtY3ZjJyk7XG4gICAgICAgIGNvbnN0IGNhcmRDb2RlID0gZGNjSW5wdXRGYWN0b3J5KGNhcmRDb2RlRmllbGQpO1xuICAgICAgICBjYXJkQ29kZUZpZWxkLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNhcmRDb2RlLCBjYXJkQ29kZUZpZWxkKTtcblxuICAgICAgICBnYXRlV2F5Qm94LnN0eWxlLmRpc3BsYXkgPSBvbGREaXNwbGF5U3R5bGU7XG5cbiAgICAgICAgY29uc3QgZm9ybVdyYXBwZXIgPSAnLnBheW1lbnRfYm94IHBheW1lbnRfbWV0aG9kX3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheSc7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdENvbmZpZy5lbmZvcmNlX3ZhdWx0XG4gICAgICAgICAgICAmJiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGZvcm1XcmFwcGVyICsgJyAucHBjcC1jcmVkaXQtY2FyZC12YXVsdCcpXG4gICAgICAgICkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihmb3JtV3JhcHBlciArICcgLnBwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5jaGVja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZm9ybVdyYXBwZXIgKyAnIC5wcGNwLWNyZWRpdC1jYXJkLXZhdWx0Jykuc2V0QXR0cmlidXRlKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHBheXBhbC5Ib3N0ZWRGaWVsZHMucmVuZGVyKHtcbiAgICAgICAgICAgIGNyZWF0ZU9yZGVyOiBjb250ZXh0Q29uZmlnLmNyZWF0ZU9yZGVyLFxuICAgICAgICAgICAgc3R5bGVzOiB7XG4gICAgICAgICAgICAgICAgJ2lucHV0Jzogc3R5bGVzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgICAgICAgbnVtYmVyOiB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yOiAnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLW51bWJlcicsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuY3JlZGl0X2NhcmRfbnVtYmVyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY3Z2OiB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yOiAnI3BwY3AtY3JlZGl0LWNhcmQtZ2F0ZXdheS1jYXJkLWN2YycsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5sYWJlbHMuY3Z2LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXhwaXJhdGlvbkRhdGU6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICcjcHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtZXhwaXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5tbV95eSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pLnRoZW4oaG9zdGVkRmllbGRzID0+IHtcbiAgICAgICAgICAgIGRvY3VtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwiaG9zdGVkX2ZpZWxkc19sb2FkZWRcIikpO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UgPSBob3N0ZWRGaWVsZHM7XG5cbiAgICAgICAgICAgIGhvc3RlZEZpZWxkcy5vbignaW5wdXRTdWJtaXRSZXF1ZXN0JywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N1Ym1pdChjb250ZXh0Q29uZmlnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaG9zdGVkRmllbGRzLm9uKCdjYXJkVHlwZUNoYW5nZScsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICggISBldmVudC5jYXJkcy5sZW5ndGggKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2FyZFZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsaWRDYXJkcyA9IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLnZhbGlkX2NhcmRzO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FyZFZhbGlkID0gdmFsaWRDYXJkcy5pbmRleE9mKGV2ZW50LmNhcmRzWzBdLnR5cGUpICE9PSAtMTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBob3N0ZWRGaWVsZHMub24oJ3ZhbGlkaXR5Q2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZm9ybVZhbGlkID0gT2JqZWN0LmtleXMoZXZlbnQuZmllbGRzKS5ldmVyeShmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBldmVudC5maWVsZHNba2V5XS5pc1ZhbGlkO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWQgPSBmb3JtVmFsaWQ7XG5cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5nZXRBdHRyaWJ1dGUoJ2RhdGEtcHBjcC1zdWJzY3JpYmVkJykgIT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHdyYXBwZXIgKyAnIGJ1dHRvbicpLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgICAgICdjbGljaycsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdWJtaXQoY29udGV4dENvbmZpZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih3cmFwcGVyKS5zZXRBdHRyaWJ1dGUoJ2RhdGEtcHBjcC1zdWJzY3JpYmVkJywgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwYXltZW50X21ldGhvZF9wcGNwLWNyZWRpdC1jYXJkLWdhdGV3YXknKS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ2NsaWNrJyxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdsYWJlbFtmb3I9cHBjcC1jcmVkaXQtY2FyZC1nYXRld2F5LWNhcmQtbnVtYmVyXScpLmNsaWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIClcbiAgICB9XG5cbiAgICBkaXNhYmxlRmllbGRzKCkge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnNldEF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdudW1iZXInLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnNldEF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdjdnYnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnNldEF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdleHBpcmF0aW9uRGF0ZScsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZW5hYmxlRmllbGRzKCkge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50SG9zdGVkRmllbGRzSW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnJlbW92ZUF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdudW1iZXInLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnJlbW92ZUF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdjdnYnLFxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogJ2Rpc2FibGVkJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEhvc3RlZEZpZWxkc0luc3RhbmNlLnJlbW92ZUF0dHJpYnV0ZSh7XG4gICAgICAgICAgICAgICAgZmllbGQ6ICdleHBpcmF0aW9uRGF0ZScsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlOiAnZGlzYWJsZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3N1Ym1pdChjb250ZXh0Q29uZmlnKSB7XG4gICAgICAgIHRoaXMuc3Bpbm5lci5ibG9jaygpO1xuICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgIGlmICh0aGlzLmZvcm1WYWxpZCAmJiB0aGlzLmNhcmRWYWxpZCkge1xuICAgICAgICAgICAgY29uc3Qgc2F2ZV9jYXJkID0gdGhpcy5kZWZhdWx0Q29uZmlnLmNhbl9zYXZlX3ZhdWx0X3Rva2VuID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICAgICAgbGV0IHZhdWx0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKSA/XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BwY3AtY3JlZGl0LWNhcmQtdmF1bHQnKS5jaGVja2VkIDogc2F2ZV9jYXJkO1xuICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbmZpZy5lbmZvcmNlX3ZhdWx0KSB7XG4gICAgICAgICAgICAgICAgdmF1bHQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY29udGluZ2VuY3kgPSB0aGlzLmRlZmF1bHRDb25maWcuaG9zdGVkX2ZpZWxkcy5jb250aW5nZW5jeTtcbiAgICAgICAgICAgIGNvbnN0IGhvc3RlZEZpZWxkc0RhdGEgPSB7XG4gICAgICAgICAgICAgICAgdmF1bHQ6IHZhdWx0XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGNvbnRpbmdlbmN5ICE9PSAnTk9fM0RfU0VDVVJFJykge1xuICAgICAgICAgICAgICAgIGhvc3RlZEZpZWxkc0RhdGEuY29udGluZ2VuY2llcyA9IFtjb250aW5nZW5jeV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmRlZmF1bHRDb25maWcucGF5ZXIpIHtcbiAgICAgICAgICAgICAgICBob3N0ZWRGaWVsZHNEYXRhLmNhcmRob2xkZXJOYW1lID0gdGhpcy5kZWZhdWx0Q29uZmlnLnBheWVyLm5hbWUuZ2l2ZW5fbmFtZSArICcgJyArIHRoaXMuZGVmYXVsdENvbmZpZy5wYXllci5uYW1lLnN1cm5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWhvc3RlZEZpZWxkc0RhdGEuY2FyZGhvbGRlck5hbWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaXJzdE5hbWUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZ19maXJzdF9uYW1lJykgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYmlsbGluZ19maXJzdF9uYW1lJykudmFsdWUgOiAnJztcbiAgICAgICAgICAgICAgICBjb25zdCBsYXN0TmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaWxsaW5nX2xhc3RfbmFtZScpID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2JpbGxpbmdfbGFzdF9uYW1lJykudmFsdWUgOiAnJztcblxuICAgICAgICAgICAgICAgIGlmICghZmlyc3ROYW1lIHx8ICFsYXN0TmFtZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5tZXNzYWdlKHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5jYXJkaG9sZGVyX25hbWVfcmVxdWlyZWQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaG9zdGVkRmllbGRzRGF0YS5jYXJkaG9sZGVyTmFtZSA9IGZpcnN0TmFtZSArICcgJyArIGxhc3ROYW1lO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZS5zdWJtaXQoaG9zdGVkRmllbGRzRGF0YSkudGhlbigocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgIHBheWxvYWQub3JkZXJJRCA9IHBheWxvYWQub3JkZXJJZDtcbiAgICAgICAgICAgICAgICB0aGlzLnNwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0Q29uZmlnLm9uQXBwcm92ZShwYXlsb2FkKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5jbGVhcigpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5kZXRhaWxzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLm1lc3NhZ2UoZXJyLmRldGFpbHMubWFwKGQgPT4gYCR7ZC5pc3N1ZX0gJHtkLmRlc2NyaXB0aW9ufWApLmpvaW4oJzxici8+JyksIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zcGlubmVyLnVuYmxvY2soKTtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSAhIHRoaXMuY2FyZFZhbGlkID8gdGhpcy5kZWZhdWx0Q29uZmlnLmhvc3RlZF9maWVsZHMubGFiZWxzLmNhcmRfbm90X3N1cHBvcnRlZCA6IHRoaXMuZGVmYXVsdENvbmZpZy5ob3N0ZWRfZmllbGRzLmxhYmVscy5maWVsZHNfbm90X3ZhbGlkO1xuICAgICAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IENyZWRpdENhcmRSZW5kZXJlcjtcbiIsImNvbnN0IHN0b3JhZ2VLZXkgPSAncHBjcC1kYXRhLWNsaWVudC1pZCc7XG5cbmNvbnN0IHZhbGlkYXRlVG9rZW4gPSAodG9rZW4sIHVzZXIpID0+IHtcbiAgICBpZiAoISB0b2tlbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0b2tlbi51c2VyICE9PSB1c2VyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBpc0V4cGlyZWQgPSBjdXJyZW50VGltZSA+PSB0b2tlbi5leHBpcmF0aW9uICogMTAwMDtcbiAgICByZXR1cm4gISBpc0V4cGlyZWQ7XG59XG5cbmNvbnN0IHN0b3JlZFRva2VuRm9yVXNlciA9ICh1c2VyKSA9PiB7XG4gICAgY29uc3QgdG9rZW4gPSBKU09OLnBhcnNlKHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oc3RvcmFnZUtleSkpO1xuICAgIGlmICh2YWxpZGF0ZVRva2VuKHRva2VuLCB1c2VyKSkge1xuICAgICAgICByZXR1cm4gdG9rZW4udG9rZW47XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBzdG9yZVRva2VuID0gKHRva2VuKSA9PiB7XG4gICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeSh0b2tlbikpO1xufVxuXG5jb25zdCBkYXRhQ2xpZW50SWRBdHRyaWJ1dGVIYW5kbGVyID0gKHNjcmlwdCwgY29uZmlnKSA9PiB7XG4gICAgZmV0Y2goY29uZmlnLmVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBub25jZTogY29uZmlnLm5vbmNlXG4gICAgICAgIH0pXG4gICAgfSkudGhlbigocmVzKT0+e1xuICAgICAgICByZXR1cm4gcmVzLmpzb24oKTtcbiAgICB9KS50aGVuKChkYXRhKT0+e1xuICAgICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRhdGVUb2tlbihkYXRhLCBjb25maWcudXNlcik7XG4gICAgICAgIGlmICghaXNWYWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0b3JlVG9rZW4oZGF0YSk7XG4gICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtY2xpZW50LXRva2VuJywgZGF0YS50b2tlbik7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKHNjcmlwdCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXI7XG4iLCJjbGFzcyBNZXNzYWdlUmVuZGVyZXIge1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGF5cGFsLk1lc3NhZ2VzKHtcbiAgICAgICAgICAgIGFtb3VudDogdGhpcy5jb25maWcuYW1vdW50LFxuICAgICAgICAgICAgcGxhY2VtZW50OiB0aGlzLmNvbmZpZy5wbGFjZW1lbnQsXG4gICAgICAgICAgICBzdHlsZTogdGhpcy5jb25maWcuc3R5bGVcbiAgICAgICAgfSkucmVuZGVyKHRoaXMuY29uZmlnLndyYXBwZXIpO1xuICAgIH1cblxuICAgIHJlbmRlcldpdGhBbW91bnQoYW1vdW50KSB7XG5cbiAgICAgICAgaWYgKCEgdGhpcy5zaG91bGRSZW5kZXIoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3V3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBuZXdXcmFwcGVyLnNldEF0dHJpYnV0ZSgnaWQnLCB0aGlzLmNvbmZpZy53cmFwcGVyLnJlcGxhY2UoJyMnLCAnJykpO1xuXG4gICAgICAgIGNvbnN0IHNpYmxpbmcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLm5leHRTaWJsaW5nO1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuY29uZmlnLndyYXBwZXIpLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSk7XG4gICAgICAgIHNpYmxpbmcucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUobmV3V3JhcHBlciwgc2libGluZyk7XG4gICAgICAgIHBheXBhbC5NZXNzYWdlcyh7XG4gICAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgICBwbGFjZW1lbnQ6IHRoaXMuY29uZmlnLnBsYWNlbWVudCxcbiAgICAgICAgICAgIHN0eWxlOiB0aGlzLmNvbmZpZy5zdHlsZVxuICAgICAgICB9KS5yZW5kZXIodGhpcy5jb25maWcud3JhcHBlcik7XG4gICAgfVxuXG4gICAgc2hvdWxkUmVuZGVyKCkge1xuXG4gICAgICAgIGlmICh0eXBlb2YgcGF5cGFsLk1lc3NhZ2VzID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgdGhpcy5jb25maWcud3JhcHBlciA9PT0gJ3VuZGVmaW5lZCcgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbmZpZy53cmFwcGVyKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IE1lc3NhZ2VSZW5kZXJlcjsiLCJjbGFzcyBTcGlubmVyIHtcblxuICAgIGNvbnN0cnVjdG9yKHRhcmdldCA9ICdmb3JtLndvb2NvbW1lcmNlLWNoZWNrb3V0Jykge1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICB9XG5cbiAgICBzZXRUYXJnZXQodGFyZ2V0KSB7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIH1cblxuICAgIGJsb2NrKCkge1xuXG4gICAgICAgIGpRdWVyeSggdGhpcy50YXJnZXQgKS5ibG9jayh7XG4gICAgICAgICAgICBtZXNzYWdlOiBudWxsLFxuICAgICAgICAgICAgb3ZlcmxheUNTUzoge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICcjZmZmJyxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLjZcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdW5ibG9jaygpIHtcblxuICAgICAgICBqUXVlcnkoIHRoaXMudGFyZ2V0ICkudW5ibG9jaygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgU3Bpbm5lcjtcbiIsImltcG9ydCBNaW5pQ2FydEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL01pbmlDYXJ0Qm9vdHN0YXAnO1xuaW1wb3J0IFNpbmdsZVByb2R1Y3RCb290c3RhcCBmcm9tICcuL21vZHVsZXMvQ29udGV4dEJvb3RzdHJhcC9TaW5nbGVQcm9kdWN0Qm9vdHN0YXAnO1xuaW1wb3J0IENhcnRCb290c3RyYXAgZnJvbSAnLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvQ2FydEJvb3RzdGFwJztcbmltcG9ydCBDaGVja291dEJvb3RzdGFwIGZyb20gJy4vbW9kdWxlcy9Db250ZXh0Qm9vdHN0cmFwL0NoZWNrb3V0Qm9vdHN0YXAnO1xuaW1wb3J0IFBheU5vd0Jvb3RzdHJhcCBmcm9tIFwiLi9tb2R1bGVzL0NvbnRleHRCb290c3RyYXAvUGF5Tm93Qm9vdHN0cmFwXCI7XG5pbXBvcnQgUmVuZGVyZXIgZnJvbSAnLi9tb2R1bGVzL1JlbmRlcmVyL1JlbmRlcmVyJztcbmltcG9ydCBFcnJvckhhbmRsZXIgZnJvbSAnLi9tb2R1bGVzL0Vycm9ySGFuZGxlcic7XG5pbXBvcnQgQ3JlZGl0Q2FyZFJlbmRlcmVyIGZyb20gXCIuL21vZHVsZXMvUmVuZGVyZXIvQ3JlZGl0Q2FyZFJlbmRlcmVyXCI7XG5pbXBvcnQgZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciBmcm9tIFwiLi9tb2R1bGVzL0RhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXJcIjtcbmltcG9ydCBNZXNzYWdlUmVuZGVyZXIgZnJvbSBcIi4vbW9kdWxlcy9SZW5kZXJlci9NZXNzYWdlUmVuZGVyZXJcIjtcbmltcG9ydCBTcGlubmVyIGZyb20gXCIuL21vZHVsZXMvSGVscGVyL1NwaW5uZXJcIjtcbmltcG9ydCB7XG4gICAgZ2V0Q3VycmVudFBheW1lbnRNZXRob2QsXG4gICAgT1JERVJfQlVUVE9OX1NFTEVDVE9SLFxuICAgIFBheW1lbnRNZXRob2RzXG59IGZyb20gXCIuL21vZHVsZXMvSGVscGVyL0NoZWNrb3V0TWV0aG9kU3RhdGVcIjtcbmltcG9ydCB7aGlkZSwgc2V0VmlzaWJsZX0gZnJvbSBcIi4vbW9kdWxlcy9IZWxwZXIvSGlkaW5nXCI7XG5pbXBvcnQge2lzQ2hhbmdlUGF5bWVudFBhZ2V9IGZyb20gXCIuL21vZHVsZXMvSGVscGVyL1N1YnNjcmlwdGlvbnNcIjtcblxuY29uc3QgYnV0dG9uc1NwaW5uZXIgPSBuZXcgU3Bpbm5lcignLnBwYy1idXR0b24td3JhcHBlcicpO1xuXG5jb25zdCBib290c3RyYXAgPSAoKSA9PiB7XG4gICAgY29uc3QgZXJyb3JIYW5kbGVyID0gbmV3IEVycm9ySGFuZGxlcihQYXlQYWxDb21tZXJjZUdhdGV3YXkubGFiZWxzLmVycm9yLmdlbmVyaWMpO1xuICAgIGNvbnN0IHNwaW5uZXIgPSBuZXcgU3Bpbm5lcigpO1xuICAgIGNvbnN0IGNyZWRpdENhcmRSZW5kZXJlciA9IG5ldyBDcmVkaXRDYXJkUmVuZGVyZXIoUGF5UGFsQ29tbWVyY2VHYXRld2F5LCBlcnJvckhhbmRsZXIsIHNwaW5uZXIpO1xuICAgIGNvbnN0IG9uU21hcnRCdXR0b25DbGljayA9IGRhdGEgPT4ge1xuICAgICAgICB3aW5kb3cucHBjcEZ1bmRpbmdTb3VyY2UgPSBkYXRhLmZ1bmRpbmdTb3VyY2U7XG4gICAgfTtcbiAgICBjb25zdCBvblNtYXJ0QnV0dG9uc0luaXQgPSAoKSA9PiB7XG4gICAgICAgIGJ1dHRvbnNTcGlubmVyLnVuYmxvY2soKTtcbiAgICB9O1xuICAgIGNvbnN0IHJlbmRlcmVyID0gbmV3IFJlbmRlcmVyKGNyZWRpdENhcmRSZW5kZXJlciwgUGF5UGFsQ29tbWVyY2VHYXRld2F5LCBvblNtYXJ0QnV0dG9uQ2xpY2ssIG9uU21hcnRCdXR0b25zSW5pdCk7XG4gICAgY29uc3QgbWVzc2FnZVJlbmRlcmVyID0gbmV3IE1lc3NhZ2VSZW5kZXJlcihQYXlQYWxDb21tZXJjZUdhdGV3YXkubWVzc2FnZXMpO1xuICAgIGNvbnN0IGNvbnRleHQgPSBQYXlQYWxDb21tZXJjZUdhdGV3YXkuY29udGV4dDtcbiAgICBpZiAoY29udGV4dCA9PT0gJ21pbmktY2FydCcgfHwgY29udGV4dCA9PT0gJ3Byb2R1Y3QnKSB7XG4gICAgICAgIGlmIChQYXlQYWxDb21tZXJjZUdhdGV3YXkubWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCA9PT0gJzEnKSB7XG4gICAgICAgICAgICBjb25zdCBtaW5pQ2FydEJvb3RzdHJhcCA9IG5ldyBNaW5pQ2FydEJvb3RzdGFwKFxuICAgICAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgICAgICByZW5kZXJlclxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgbWluaUNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgPT09ICdwcm9kdWN0JyAmJiBQYXlQYWxDb21tZXJjZUdhdGV3YXkuc2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkID09PSAnMScpIHtcbiAgICAgICAgY29uc3Qgc2luZ2xlUHJvZHVjdEJvb3RzdHJhcCA9IG5ldyBTaW5nbGVQcm9kdWN0Qm9vdHN0YXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgKTtcblxuICAgICAgICBzaW5nbGVQcm9kdWN0Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCA9PT0gJ2NhcnQnKSB7XG4gICAgICAgIGNvbnN0IGNhcnRCb290c3RyYXAgPSBuZXcgQ2FydEJvb3RzdHJhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICApO1xuXG4gICAgICAgIGNhcnRCb290c3RyYXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAnY2hlY2tvdXQnKSB7XG4gICAgICAgIGNvbnN0IGNoZWNrb3V0Qm9vdHN0YXAgPSBuZXcgQ2hlY2tvdXRCb290c3RhcChcbiAgICAgICAgICAgIFBheVBhbENvbW1lcmNlR2F0ZXdheSxcbiAgICAgICAgICAgIHJlbmRlcmVyLFxuICAgICAgICAgICAgbWVzc2FnZVJlbmRlcmVyLFxuICAgICAgICAgICAgc3Bpbm5lclxuICAgICAgICApO1xuXG4gICAgICAgIGNoZWNrb3V0Qm9vdHN0YXAuaW5pdCgpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ID09PSAncGF5LW5vdycgKSB7XG4gICAgICAgIGNvbnN0IHBheU5vd0Jvb3RzdHJhcCA9IG5ldyBQYXlOb3dCb290c3RyYXAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXksXG4gICAgICAgICAgICByZW5kZXJlcixcbiAgICAgICAgICAgIG1lc3NhZ2VSZW5kZXJlcixcbiAgICAgICAgICAgIHNwaW5uZXJcbiAgICAgICAgKTtcbiAgICAgICAgcGF5Tm93Qm9vdHN0cmFwLmluaXQoKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCAhPT0gJ2NoZWNrb3V0Jykge1xuICAgICAgICBtZXNzYWdlUmVuZGVyZXIucmVuZGVyKCk7XG4gICAgfVxufTtcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgJ0RPTUNvbnRlbnRMb2FkZWQnLFxuICAgICgpID0+IHtcbiAgICAgICAgaWYgKCF0eXBlb2YgKFBheVBhbENvbW1lcmNlR2F0ZXdheSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1BheVBhbCBidXR0b24gY291bGQgbm90IGJlIGNvbmZpZ3VyZWQuJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBQYXlQYWxDb21tZXJjZUdhdGV3YXkuY29udGV4dCAhPT0gJ2NoZWNrb3V0J1xuICAgICAgICAgICAgJiYgUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkLnVzZXIgPT09IDBcbiAgICAgICAgICAgICYmIFBheVBhbENvbW1lcmNlR2F0ZXdheS5kYXRhX2NsaWVudF9pZC5oYXNfc3Vic2NyaXB0aW9uc1xuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNvbWV0aW1lcyBQYXlQYWwgc2NyaXB0IHRha2VzIGxvbmcgdGltZSB0byBsb2FkLFxuICAgICAgICAvLyBzbyB3ZSBhZGRpdGlvbmFsbHkgaGlkZSB0aGUgc3RhbmRhcmQgb3JkZXIgYnV0dG9uIGhlcmUgdG8gYXZvaWQgZmFpbGVkIG9yZGVycy5cbiAgICAgICAgLy8gTm9ybWFsbHkgaXQgaXMgaGlkZGVuIGxhdGVyIGFmdGVyIHRoZSBzY3JpcHQgbG9hZC5cbiAgICAgICAgY29uc3QgaGlkZU9yZGVyQnV0dG9uSWZQcGNwR2F0ZXdheSA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIG9ubHkgaW4gY2hlY2tvdXQgYW5kIHBheSBub3cgcGFnZSwgb3RoZXJ3aXNlIGl0IG1heSBicmVhayB0aGluZ3MgKGUuZy4gcGF5bWVudCB2aWEgcHJvZHVjdCBwYWdlKSxcbiAgICAgICAgICAgIC8vIGFuZCBhbHNvIHRoZSBsb2FkaW5nIHNwaW5uZXIgbWF5IGxvb2sgd2VpcmQgb24gb3RoZXIgcGFnZXNcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAhWydjaGVja291dCcsICdwYXktbm93J10uaW5jbHVkZXMoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmNvbnRleHQpXG4gICAgICAgICAgICAgICAgfHwgaXNDaGFuZ2VQYXltZW50UGFnZSgpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRQYXltZW50TWV0aG9kID0gZ2V0Q3VycmVudFBheW1lbnRNZXRob2QoKTtcbiAgICAgICAgICAgIGNvbnN0IGlzUGF5cGFsID0gY3VycmVudFBheW1lbnRNZXRob2QgPT09IFBheW1lbnRNZXRob2RzLlBBWVBBTDtcblxuICAgICAgICAgICAgc2V0VmlzaWJsZShPUkRFUl9CVVRUT05fU0VMRUNUT1IsICFpc1BheXBhbCwgdHJ1ZSk7XG5cbiAgICAgICAgICAgIGlmIChpc1BheXBhbCkge1xuICAgICAgICAgICAgICAgIC8vIHN0b3BwZWQgYWZ0ZXIgdGhlIGZpcnN0IHJlbmRlcmluZyBvZiB0aGUgYnV0dG9ucywgaW4gb25Jbml0XG4gICAgICAgICAgICAgICAgYnV0dG9uc1NwaW5uZXIuYmxvY2soKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYnV0dG9uc1NwaW5uZXIudW5ibG9jaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGJvb3RzdHJhcHBlZCA9IGZhbHNlO1xuXG4gICAgICAgIGhpZGVPcmRlckJ1dHRvbklmUHBjcEdhdGV3YXkoKTtcblxuICAgICAgICBqUXVlcnkoZG9jdW1lbnQuYm9keSkub24oJ3VwZGF0ZWRfY2hlY2tvdXQgcGF5bWVudF9tZXRob2Rfc2VsZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoYm9vdHN0cmFwcGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBoaWRlT3JkZXJCdXR0b25JZlBwY3BHYXRld2F5KCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICBzY3JpcHQuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgYm9vdHN0cmFwcGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgYm9vdHN0cmFwKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBzY3JpcHQuc2V0QXR0cmlidXRlKCdzcmMnLCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuYnV0dG9uLnVybCk7XG4gICAgICAgIE9iamVjdC5lbnRyaWVzKFBheVBhbENvbW1lcmNlR2F0ZXdheS5zY3JpcHRfYXR0cmlidXRlcykuZm9yRWFjaChcbiAgICAgICAgICAgIChrZXlWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHNjcmlwdC5zZXRBdHRyaWJ1dGUoa2V5VmFsdWVbMF0sIGtleVZhbHVlWzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoUGF5UGFsQ29tbWVyY2VHYXRld2F5LmRhdGFfY2xpZW50X2lkLnNldF9hdHRyaWJ1dGUpIHtcbiAgICAgICAgICAgIGRhdGFDbGllbnRJZEF0dHJpYnV0ZUhhbmRsZXIoc2NyaXB0LCBQYXlQYWxDb21tZXJjZUdhdGV3YXkuZGF0YV9jbGllbnRfaWQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoc2NyaXB0KTtcbiAgICB9LFxuKTtcbiJdLCJuYW1lcyI6WyJFcnJvckhhbmRsZXIiLCJjb25zdHJ1Y3RvciIsImdlbmVyaWNFcnJvclRleHQiLCJ3cmFwcGVyIiwiZG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yIiwibWVzc2FnZXNMaXN0IiwiZ2VuZXJpY0Vycm9yIiwiY2xhc3NMaXN0IiwiY29udGFpbnMiLCJjbGVhciIsIm1lc3NhZ2UiLCJhcHBlbmRQcmVwYXJlZEVycm9yTWVzc2FnZUVsZW1lbnQiLCJlcnJvck1lc3NhZ2VFbGVtZW50IiwicHJlcGFyZU1lc3NhZ2VzTGlzdCIsInJlcGxhY2VXaXRoIiwidGV4dCIsInBlcnNpc3QiLCJTdHJpbmciLCJsZW5ndGgiLCJFcnJvciIsImFkZCIsInJlbW92ZSIsIm1lc3NhZ2VOb2RlIiwicHJlcGFyZU1lc3NhZ2VzTGlzdEl0ZW0iLCJhcHBlbmRDaGlsZCIsImpRdWVyeSIsInNjcm9sbF90b19ub3RpY2VzIiwiY3JlYXRlRWxlbWVudCIsInNldEF0dHJpYnV0ZSIsImxpIiwiaW5uZXJIVE1MIiwic2FuaXRpemUiLCJ0ZXh0YXJlYSIsInZhbHVlIiwicmVwbGFjZSIsIm9uQXBwcm92ZSIsImNvbnRleHQiLCJlcnJvckhhbmRsZXIiLCJkYXRhIiwiYWN0aW9ucyIsImZldGNoIiwiY29uZmlnIiwiYWpheCIsImFwcHJvdmVfb3JkZXIiLCJlbmRwb2ludCIsIm1ldGhvZCIsImJvZHkiLCJKU09OIiwic3RyaW5naWZ5Iiwibm9uY2UiLCJvcmRlcl9pZCIsIm9yZGVySUQiLCJmdW5kaW5nX3NvdXJjZSIsIndpbmRvdyIsInBwY3BGdW5kaW5nU291cmNlIiwidGhlbiIsInJlcyIsImpzb24iLCJzdWNjZXNzIiwicmVzdGFydCIsImNhdGNoIiwiZXJyIiwibG9jYXRpb24iLCJocmVmIiwicmVkaXJlY3QiLCJwYXllckRhdGEiLCJwYXllciIsIlBheVBhbENvbW1lcmNlR2F0ZXdheSIsInBob25lIiwicGhvbmVfdHlwZSIsInBob25lX251bWJlciIsIm5hdGlvbmFsX251bWJlciIsImVtYWlsX2FkZHJlc3MiLCJuYW1lIiwic3VybmFtZSIsImdpdmVuX25hbWUiLCJhZGRyZXNzIiwiY291bnRyeV9jb2RlIiwiYWRkcmVzc19saW5lXzEiLCJhZGRyZXNzX2xpbmVfMiIsImFkbWluX2FyZWFfMSIsImFkbWluX2FyZWFfMiIsInBvc3RhbF9jb2RlIiwiQ2FydEFjdGlvbkhhbmRsZXIiLCJjb25maWd1cmF0aW9uIiwiY3JlYXRlT3JkZXIiLCJibkNvZGUiLCJibl9jb2RlcyIsImNyZWF0ZV9vcmRlciIsInB1cmNoYXNlX3VuaXRzIiwiYm5fY29kZSIsImNvbnNvbGUiLCJlcnJvciIsImlkIiwib25FcnJvciIsIk1pbmlDYXJ0Qm9vdHN0YXAiLCJnYXRld2F5IiwicmVuZGVyZXIiLCJhY3Rpb25IYW5kbGVyIiwiaW5pdCIsImxhYmVscyIsImdlbmVyaWMiLCJyZW5kZXIiLCJvbiIsInNob3VsZFJlbmRlciIsImJ1dHRvbiIsIm1pbmlfY2FydF93cmFwcGVyIiwiaG9zdGVkX2ZpZWxkcyIsIlByb2R1Y3QiLCJVcGRhdGVDYXJ0IiwidXBkYXRlIiwib25SZXNvbHZlIiwicHJvZHVjdHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsInJlc3VsdCIsInJlc29sdmVkIiwiQnV0dG9uc1RvZ2dsZUxpc3RlbmVyIiwiZWxlbWVudCIsInNob3dDYWxsYmFjayIsImhpZGVDYWxsYmFjayIsIm9ic2VydmVyIiwiYXR0cmlidXRlcyIsImNhbGxiYWNrIiwiTXV0YXRpb25PYnNlcnZlciIsIm9ic2VydmUiLCJkaXNjb25uZWN0IiwicXVhbnRpdHkiLCJ2YXJpYXRpb25zIiwiU2luZ2xlUHJvZHVjdEFjdGlvbkhhbmRsZXIiLCJ1cGRhdGVDYXJ0Iiwic2hvd0J1dHRvbkNhbGxiYWNrIiwiaGlkZUJ1dHRvbkNhbGxiYWNrIiwiZm9ybUVsZW1lbnQiLCJoYXNWYXJpYXRpb25zIiwiZ2V0UHJvZHVjdHMiLCJpc0dyb3VwZWRQcm9kdWN0IiwicXR5IiwicXVlcnlTZWxlY3RvckFsbCIsImZvckVhY2giLCJlbGVtZW50TmFtZSIsImdldEF0dHJpYnV0ZSIsIm1hdGNoIiwicGFyc2VJbnQiLCJwdXNoIiwicHJvbWlzZSIsIm1hcCIsIlNpbmdsZVByb2R1Y3RCb290c3RhcCIsIm1lc3NhZ2VzIiwiaGFuZGxlQ2hhbmdlIiwiaGlkZUJ1dHRvbnMiLCJhZGRFdmVudExpc3RlbmVyIiwiYmluZCIsInByaWNlQW1vdW50SXNaZXJvIiwicHJpY2VUZXh0IiwiaW5uZXJUZXh0IiwiYW1vdW50IiwicGFyc2VGbG9hdCIsImNoYW5nZV9jYXJ0Iiwic2hvd0J1dHRvbnMiLCJyZW5kZXJXaXRoQW1vdW50IiwiQ2FydEJvb3RzdHJhcCIsInNwaW5uZXIiLCJibG9jayIsInVuYmxvY2siLCJjb2RlIiwiY2xpY2siLCJDaGVja291dEFjdGlvbkhhbmRsZXIiLCJmb3JtU2VsZWN0b3IiLCJmb3JtVmFsdWVzIiwic2VyaWFsaXplIiwiY3JlYXRlYWNjb3VudCIsImlzIiwiZm9ybSIsImRvbVBhcnNlciIsIkRPTVBhcnNlciIsInBhcnNlRnJvbVN0cmluZyIsImRldGFpbHMiLCJkIiwiaXNzdWUiLCJkZXNjcmlwdGlvbiIsImpvaW4iLCJpbnB1dCIsImN1c3RvbV9pZCIsImFwcGVuZCIsIm9uQ2FuY2VsIiwiZ2V0RWxlbWVudCIsInNlbGVjdG9yT3JFbGVtZW50IiwiaXNWaXNpYmxlIiwib2Zmc2V0V2lkdGgiLCJvZmZzZXRIZWlnaHQiLCJnZXRDbGllbnRSZWN0cyIsInNldFZpc2libGUiLCJzaG93IiwiaW1wb3J0YW50IiwiY3VycmVudFZhbHVlIiwic3R5bGUiLCJnZXRQcm9wZXJ0eVZhbHVlIiwic2V0UHJvcGVydHkiLCJyZW1vdmVQcm9wZXJ0eSIsImhpZGUiLCJQYXltZW50TWV0aG9kcyIsIlBBWVBBTCIsIkNBUkRTIiwiT1JERVJfQlVUVE9OX1NFTEVDVE9SIiwiZ2V0Q3VycmVudFBheW1lbnRNZXRob2QiLCJlbCIsImlzU2F2ZWRDYXJkU2VsZWN0ZWQiLCJzYXZlZENhcmRMaXN0IiwiQ2hlY2tvdXRCb290c3RhcCIsInN0YW5kYXJkT3JkZXJCdXR0b25TZWxlY3RvciIsImJ1dHRvbkNoYW5nZU9ic2VydmVyIiwidXBkYXRlVWkiLCJ2YWwiLCJjYW5jZWxfd3JhcHBlciIsImN1cnJlbnRQYXltZW50TWV0aG9kIiwiaXNQYXlwYWwiLCJpc0NhcmQiLCJpc1NhdmVkQ2FyZCIsImlzTm90T3VyR2F0ZXdheSIsImRpc2FibGVDcmVkaXRDYXJkRmllbGRzIiwiZW5hYmxlQ3JlZGl0Q2FyZEZpZWxkcyIsImFkZENsYXNzIiwiYXR0ciIsInJlbW92ZUNsYXNzIiwiaXNDaGFuZ2VQYXltZW50UGFnZSIsInVybFBhcmFtcyIsIlVSTFNlYXJjaFBhcmFtcyIsInNlYXJjaCIsImhhcyIsIlBheU5vd0Jvb3RzdHJhcCIsIlJlbmRlcmVyIiwiY3JlZGl0Q2FyZFJlbmRlcmVyIiwiZGVmYXVsdENvbmZpZyIsIm9uU21hcnRCdXR0b25DbGljayIsIm9uU21hcnRCdXR0b25zSW5pdCIsImhvc3RlZEZpZWxkc1dyYXBwZXIiLCJjb250ZXh0Q29uZmlnIiwicmVuZGVyQnV0dG9ucyIsImlzQWxyZWFkeVJlbmRlcmVkIiwicGF5cGFsIiwiQnV0dG9ucyIsIm1pbmlfY2FydF9zdHlsZSIsIm9uQ2xpY2siLCJvbkluaXQiLCJoYXNDaGlsZE5vZGVzIiwiZG9tRWxlbWVudCIsImRpc3BsYXkiLCJkaXNhYmxlRmllbGRzIiwiZW5hYmxlRmllbGRzIiwiZGNjSW5wdXRGYWN0b3J5Iiwib3JpZ2luYWwiLCJzdHlsZXMiLCJnZXRDb21wdXRlZFN0eWxlIiwibmV3RWxlbWVudCIsIk9iamVjdCIsInZhbHVlcyIsInByb3AiLCJpc05hTiIsIkNyZWRpdENhcmRSZW5kZXJlciIsImNhcmRWYWxpZCIsImZvcm1WYWxpZCIsImN1cnJlbnRIb3N0ZWRGaWVsZHNJbnN0YW5jZSIsIkhvc3RlZEZpZWxkcyIsImlzRWxpZ2libGUiLCJ3cmFwcGVyRWxlbWVudCIsInBhcmVudE5vZGUiLCJyZW1vdmVDaGlsZCIsInRlYXJkb3duIiwiZ2F0ZVdheUJveCIsIm9sZERpc3BsYXlTdHlsZSIsImhpZGVEY2NHYXRld2F5IiwiY2FyZE51bWJlckZpZWxkIiwic3R5bGVzUmF3IiwiY2FyZE51bWJlciIsInJlcGxhY2VDaGlsZCIsImNhcmRFeHBpcnlGaWVsZCIsImNhcmRFeHBpcnkiLCJjYXJkQ29kZUZpZWxkIiwiY2FyZENvZGUiLCJmb3JtV3JhcHBlciIsImVuZm9yY2VfdmF1bHQiLCJjaGVja2VkIiwiZmllbGRzIiwibnVtYmVyIiwic2VsZWN0b3IiLCJwbGFjZWhvbGRlciIsImNyZWRpdF9jYXJkX251bWJlciIsImN2diIsImV4cGlyYXRpb25EYXRlIiwibW1feXkiLCJob3N0ZWRGaWVsZHMiLCJkaXNwYXRjaEV2ZW50IiwiQ3VzdG9tRXZlbnQiLCJfc3VibWl0IiwiZXZlbnQiLCJjYXJkcyIsInZhbGlkQ2FyZHMiLCJ2YWxpZF9jYXJkcyIsImluZGV4T2YiLCJ0eXBlIiwia2V5cyIsImV2ZXJ5Iiwia2V5IiwiaXNWYWxpZCIsInByZXZlbnREZWZhdWx0IiwiZmllbGQiLCJhdHRyaWJ1dGUiLCJyZW1vdmVBdHRyaWJ1dGUiLCJzYXZlX2NhcmQiLCJjYW5fc2F2ZV92YXVsdF90b2tlbiIsInZhdWx0IiwiZ2V0RWxlbWVudEJ5SWQiLCJjb250aW5nZW5jeSIsImhvc3RlZEZpZWxkc0RhdGEiLCJjb250aW5nZW5jaWVzIiwiY2FyZGhvbGRlck5hbWUiLCJmaXJzdE5hbWUiLCJsYXN0TmFtZSIsImNhcmRob2xkZXJfbmFtZV9yZXF1aXJlZCIsInN1Ym1pdCIsInBheWxvYWQiLCJvcmRlcklkIiwiY2FyZF9ub3Rfc3VwcG9ydGVkIiwiZmllbGRzX25vdF92YWxpZCIsInN0b3JhZ2VLZXkiLCJ2YWxpZGF0ZVRva2VuIiwidG9rZW4iLCJ1c2VyIiwiY3VycmVudFRpbWUiLCJEYXRlIiwiZ2V0VGltZSIsImlzRXhwaXJlZCIsImV4cGlyYXRpb24iLCJzdG9yZWRUb2tlbkZvclVzZXIiLCJwYXJzZSIsInNlc3Npb25TdG9yYWdlIiwiZ2V0SXRlbSIsInN0b3JlVG9rZW4iLCJzZXRJdGVtIiwiZGF0YUNsaWVudElkQXR0cmlidXRlSGFuZGxlciIsInNjcmlwdCIsIk1lc3NhZ2VSZW5kZXJlciIsIk1lc3NhZ2VzIiwicGxhY2VtZW50IiwibmV3V3JhcHBlciIsInNpYmxpbmciLCJuZXh0U2libGluZyIsInBhcmVudEVsZW1lbnQiLCJpbnNlcnRCZWZvcmUiLCJTcGlubmVyIiwidGFyZ2V0Iiwic2V0VGFyZ2V0Iiwib3ZlcmxheUNTUyIsImJhY2tncm91bmQiLCJvcGFjaXR5IiwiYnV0dG9uc1NwaW5uZXIiLCJib290c3RyYXAiLCJmdW5kaW5nU291cmNlIiwibWVzc2FnZVJlbmRlcmVyIiwibWluaV9jYXJ0X2J1dHRvbnNfZW5hYmxlZCIsIm1pbmlDYXJ0Qm9vdHN0cmFwIiwic2luZ2xlX3Byb2R1Y3RfYnV0dG9uc19lbmFibGVkIiwic2luZ2xlUHJvZHVjdEJvb3RzdHJhcCIsImNhcnRCb290c3RyYXAiLCJjaGVja291dEJvb3RzdGFwIiwicGF5Tm93Qm9vdHN0cmFwIiwiZGF0YV9jbGllbnRfaWQiLCJoYXNfc3Vic2NyaXB0aW9ucyIsImhpZGVPcmRlckJ1dHRvbklmUHBjcEdhdGV3YXkiLCJpbmNsdWRlcyIsImJvb3RzdHJhcHBlZCIsInVybCIsImVudHJpZXMiLCJzY3JpcHRfYXR0cmlidXRlcyIsImtleVZhbHVlIiwic2V0X2F0dHJpYnV0ZSJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///210\n")}},__webpack_exports__={};__webpack_modules__[210]()})();
|
modules/ppcp-button/resources/js/button.js
CHANGED
@@ -9,6 +9,15 @@ import CreditCardRenderer from "./modules/Renderer/CreditCardRenderer";
|
|
9 |
import dataClientIdAttributeHandler from "./modules/DataClientIdAttributeHandler";
|
10 |
import MessageRenderer from "./modules/Renderer/MessageRenderer";
|
11 |
import Spinner from "./modules/Helper/Spinner";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
const bootstrap = () => {
|
14 |
const errorHandler = new ErrorHandler(PayPalCommerceGateway.labels.error.generic);
|
@@ -17,7 +26,10 @@ const bootstrap = () => {
|
|
17 |
const onSmartButtonClick = data => {
|
18 |
window.ppcpFundingSource = data.fundingSource;
|
19 |
};
|
20 |
-
const
|
|
|
|
|
|
|
21 |
const messageRenderer = new MessageRenderer(PayPalCommerceGateway.messages);
|
22 |
const context = PayPalCommerceGateway.context;
|
23 |
if (context === 'mini-cart' || context === 'product') {
|
@@ -91,8 +103,48 @@ document.addEventListener(
|
|
91 |
return;
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
const script = document.createElement('script');
|
95 |
script.addEventListener('load', (event) => {
|
|
|
|
|
96 |
bootstrap();
|
97 |
});
|
98 |
script.setAttribute('src', PayPalCommerceGateway.button.url);
|
9 |
import dataClientIdAttributeHandler from "./modules/DataClientIdAttributeHandler";
|
10 |
import MessageRenderer from "./modules/Renderer/MessageRenderer";
|
11 |
import Spinner from "./modules/Helper/Spinner";
|
12 |
+
import {
|
13 |
+
getCurrentPaymentMethod,
|
14 |
+
ORDER_BUTTON_SELECTOR,
|
15 |
+
PaymentMethods
|
16 |
+
} from "./modules/Helper/CheckoutMethodState";
|
17 |
+
import {hide, setVisible} from "./modules/Helper/Hiding";
|
18 |
+
import {isChangePaymentPage} from "./modules/Helper/Subscriptions";
|
19 |
+
|
20 |
+
const buttonsSpinner = new Spinner('.ppc-button-wrapper');
|
21 |
|
22 |
const bootstrap = () => {
|
23 |
const errorHandler = new ErrorHandler(PayPalCommerceGateway.labels.error.generic);
|
26 |
const onSmartButtonClick = data => {
|
27 |
window.ppcpFundingSource = data.fundingSource;
|
28 |
};
|
29 |
+
const onSmartButtonsInit = () => {
|
30 |
+
buttonsSpinner.unblock();
|
31 |
+
};
|
32 |
+
const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick, onSmartButtonsInit);
|
33 |
const messageRenderer = new MessageRenderer(PayPalCommerceGateway.messages);
|
34 |
const context = PayPalCommerceGateway.context;
|
35 |
if (context === 'mini-cart' || context === 'product') {
|
103 |
return;
|
104 |
}
|
105 |
|
106 |
+
// Sometimes PayPal script takes long time to load,
|
107 |
+
// so we additionally hide the standard order button here to avoid failed orders.
|
108 |
+
// Normally it is hidden later after the script load.
|
109 |
+
const hideOrderButtonIfPpcpGateway = () => {
|
110 |
+
// only in checkout and pay now page, otherwise it may break things (e.g. payment via product page),
|
111 |
+
// and also the loading spinner may look weird on other pages
|
112 |
+
if (
|
113 |
+
!['checkout', 'pay-now'].includes(PayPalCommerceGateway.context)
|
114 |
+
|| isChangePaymentPage()
|
115 |
+
) {
|
116 |
+
return;
|
117 |
+
}
|
118 |
+
|
119 |
+
const currentPaymentMethod = getCurrentPaymentMethod();
|
120 |
+
const isPaypal = currentPaymentMethod === PaymentMethods.PAYPAL;
|
121 |
+
|
122 |
+
setVisible(ORDER_BUTTON_SELECTOR, !isPaypal, true);
|
123 |
+
|
124 |
+
if (isPaypal) {
|
125 |
+
// stopped after the first rendering of the buttons, in onInit
|
126 |
+
buttonsSpinner.block();
|
127 |
+
} else {
|
128 |
+
buttonsSpinner.unblock();
|
129 |
+
}
|
130 |
+
}
|
131 |
+
|
132 |
+
let bootstrapped = false;
|
133 |
+
|
134 |
+
hideOrderButtonIfPpcpGateway();
|
135 |
+
|
136 |
+
jQuery(document.body).on('updated_checkout payment_method_selected', () => {
|
137 |
+
if (bootstrapped) {
|
138 |
+
return;
|
139 |
+
}
|
140 |
+
|
141 |
+
hideOrderButtonIfPpcpGateway();
|
142 |
+
});
|
143 |
+
|
144 |
const script = document.createElement('script');
|
145 |
script.addEventListener('load', (event) => {
|
146 |
+
bootstrapped = true;
|
147 |
+
|
148 |
bootstrap();
|
149 |
});
|
150 |
script.setAttribute('src', PayPalCommerceGateway.button.url);
|
modules/ppcp-button/resources/js/modules/ContextBootstrap/CheckoutBootstap.js
CHANGED
@@ -1,6 +1,11 @@
|
|
1 |
import ErrorHandler from '../ErrorHandler';
|
2 |
import CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';
|
3 |
import { setVisible } from '../Helper/Hiding';
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
class CheckoutBootstap {
|
6 |
constructor(gateway, renderer, messages, spinner) {
|
@@ -9,7 +14,7 @@ class CheckoutBootstap {
|
|
9 |
this.messages = messages;
|
10 |
this.spinner = spinner;
|
11 |
|
12 |
-
this.standardOrderButtonSelector =
|
13 |
|
14 |
this.buttonChangeObserver = new MutationObserver((el) => {
|
15 |
this.updateUi();
|
@@ -76,10 +81,10 @@ class CheckoutBootstap {
|
|
76 |
}
|
77 |
|
78 |
updateUi() {
|
79 |
-
const currentPaymentMethod =
|
80 |
-
const isPaypal = currentPaymentMethod ===
|
81 |
-
const isCard = currentPaymentMethod ===
|
82 |
-
const isSavedCard = isCard &&
|
83 |
const isNotOurGateway = !isPaypal && !isCard;
|
84 |
|
85 |
setVisible(this.standardOrderButtonSelector, isNotOurGateway || isSavedCard, true);
|
@@ -125,15 +130,6 @@ class CheckoutBootstap {
|
|
125 |
jQuery('#ppcp-credit-card-vault').attr("disabled", false)
|
126 |
this.renderer.enableCreditCardFields()
|
127 |
}
|
128 |
-
|
129 |
-
currentPaymentMethod() {
|
130 |
-
return jQuery('input[name="payment_method"]:checked').val();
|
131 |
-
}
|
132 |
-
|
133 |
-
isSavedCardSelected() {
|
134 |
-
const savedCardList = jQuery('#saved-credit-card');
|
135 |
-
return savedCardList.length && savedCardList.val() !== '';
|
136 |
-
}
|
137 |
}
|
138 |
|
139 |
export default CheckoutBootstap
|
1 |
import ErrorHandler from '../ErrorHandler';
|
2 |
import CheckoutActionHandler from '../ActionHandler/CheckoutActionHandler';
|
3 |
import { setVisible } from '../Helper/Hiding';
|
4 |
+
import {
|
5 |
+
getCurrentPaymentMethod,
|
6 |
+
isSavedCardSelected, ORDER_BUTTON_SELECTOR,
|
7 |
+
PaymentMethods
|
8 |
+
} from "../Helper/CheckoutMethodState";
|
9 |
|
10 |
class CheckoutBootstap {
|
11 |
constructor(gateway, renderer, messages, spinner) {
|
14 |
this.messages = messages;
|
15 |
this.spinner = spinner;
|
16 |
|
17 |
+
this.standardOrderButtonSelector = ORDER_BUTTON_SELECTOR;
|
18 |
|
19 |
this.buttonChangeObserver = new MutationObserver((el) => {
|
20 |
this.updateUi();
|
81 |
}
|
82 |
|
83 |
updateUi() {
|
84 |
+
const currentPaymentMethod = getCurrentPaymentMethod();
|
85 |
+
const isPaypal = currentPaymentMethod === PaymentMethods.PAYPAL;
|
86 |
+
const isCard = currentPaymentMethod === PaymentMethods.CARDS;
|
87 |
+
const isSavedCard = isCard && isSavedCardSelected();
|
88 |
const isNotOurGateway = !isPaypal && !isCard;
|
89 |
|
90 |
setVisible(this.standardOrderButtonSelector, isNotOurGateway || isSavedCard, true);
|
130 |
jQuery('#ppcp-credit-card-vault').attr("disabled", false)
|
131 |
this.renderer.enableCreditCardFields()
|
132 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
134 |
|
135 |
export default CheckoutBootstap
|
modules/ppcp-button/resources/js/modules/ContextBootstrap/MiniCartBootstap.js
CHANGED
@@ -22,9 +22,8 @@ class MiniCartBootstap {
|
|
22 |
}
|
23 |
|
24 |
shouldRender() {
|
25 |
-
return document.querySelector(this.gateway.button.mini_cart_wrapper) !==
|
26 |
-
|
27 |
-
null;
|
28 |
}
|
29 |
|
30 |
render() {
|
@@ -40,4 +39,4 @@ class MiniCartBootstap {
|
|
40 |
}
|
41 |
}
|
42 |
|
43 |
-
export default MiniCartBootstap;
|
22 |
}
|
23 |
|
24 |
shouldRender() {
|
25 |
+
return document.querySelector(this.gateway.button.mini_cart_wrapper) !== null
|
26 |
+
|| document.querySelector(this.gateway.hosted_fields.mini_cart_wrapper) !== null;
|
|
|
27 |
}
|
28 |
|
29 |
render() {
|
39 |
}
|
40 |
}
|
41 |
|
42 |
+
export default MiniCartBootstap;
|
modules/ppcp-button/resources/js/modules/ContextBootstrap/PayNowBootstrap.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import CheckoutBootstap from './CheckoutBootstap'
|
|
|
2 |
|
3 |
class PayNowBootstrap extends CheckoutBootstap {
|
4 |
constructor(gateway, renderer, messages, spinner) {
|
@@ -6,8 +7,7 @@ class PayNowBootstrap extends CheckoutBootstap {
|
|
6 |
}
|
7 |
|
8 |
updateUi() {
|
9 |
-
|
10 |
-
if (urlParams.has('change_payment_method')) {
|
11 |
return
|
12 |
}
|
13 |
|
1 |
import CheckoutBootstap from './CheckoutBootstap'
|
2 |
+
import {isChangePaymentPage} from "../Helper/Subscriptions";
|
3 |
|
4 |
class PayNowBootstrap extends CheckoutBootstap {
|
5 |
constructor(gateway, renderer, messages, spinner) {
|
7 |
}
|
8 |
|
9 |
updateUi() {
|
10 |
+
if (isChangePaymentPage()) {
|
|
|
11 |
return
|
12 |
}
|
13 |
|
modules/ppcp-button/resources/js/modules/ContextBootstrap/SingleProductBootstap.js
CHANGED
@@ -9,21 +9,51 @@ class SingleProductBootstap {
|
|
9 |
this.messages = messages;
|
10 |
}
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
init() {
|
|
|
|
|
|
|
13 |
if (!this.shouldRender()) {
|
14 |
-
|
15 |
return;
|
16 |
}
|
17 |
|
18 |
this.render();
|
|
|
19 |
}
|
20 |
|
21 |
shouldRender() {
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
}
|
|
|
|
|
25 |
|
26 |
-
return true;
|
27 |
}
|
28 |
|
29 |
render() {
|
@@ -62,4 +92,4 @@ class SingleProductBootstap {
|
|
62 |
}
|
63 |
}
|
64 |
|
65 |
-
export default SingleProductBootstap;
|
9 |
this.messages = messages;
|
10 |
}
|
11 |
|
12 |
+
|
13 |
+
handleChange() {
|
14 |
+
if (!this.shouldRender()) {
|
15 |
+
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
16 |
+
this.renderer.hideButtons(this.gateway.button.wrapper);
|
17 |
+
return;
|
18 |
+
}
|
19 |
+
|
20 |
+
this.render();
|
21 |
+
}
|
22 |
+
|
23 |
init() {
|
24 |
+
|
25 |
+
document.querySelector('form.cart').addEventListener('change', this.handleChange.bind(this))
|
26 |
+
|
27 |
if (!this.shouldRender()) {
|
28 |
+
this.renderer.hideButtons(this.gateway.hosted_fields.wrapper);
|
29 |
return;
|
30 |
}
|
31 |
|
32 |
this.render();
|
33 |
+
|
34 |
}
|
35 |
|
36 |
shouldRender() {
|
37 |
+
|
38 |
+
return document.querySelector('form.cart') !== null && !this.priceAmountIsZero();
|
39 |
+
|
40 |
+
}
|
41 |
+
|
42 |
+
priceAmountIsZero() {
|
43 |
+
|
44 |
+
let priceText = "0";
|
45 |
+
if (document.querySelector('form.cart ins .woocommerce-Price-amount')) {
|
46 |
+
priceText = document.querySelector('form.cart ins .woocommerce-Price-amount').innerText;
|
47 |
+
}
|
48 |
+
else if (document.querySelector('form.cart .woocommerce-Price-amount')) {
|
49 |
+
priceText = document.querySelector('form.cart .woocommerce-Price-amount').innerText;
|
50 |
+
}
|
51 |
+
else if (document.querySelector('.product .woocommerce-Price-amount')) {
|
52 |
+
priceText = document.querySelector('.product .woocommerce-Price-amount').innerText;
|
53 |
}
|
54 |
+
const amount = parseFloat(priceText.replace(/([^\d,\.\s]*)/g, ''));
|
55 |
+
return amount === 0;
|
56 |
|
|
|
57 |
}
|
58 |
|
59 |
render() {
|
92 |
}
|
93 |
}
|
94 |
|
95 |
+
export default SingleProductBootstap;
|
modules/ppcp-button/resources/js/modules/Helper/CheckoutMethodState.js
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export const PaymentMethods = {
|
2 |
+
PAYPAL: 'ppcp-gateway',
|
3 |
+
CARDS: 'ppcp-credit-card-gateway',
|
4 |
+
};
|
5 |
+
|
6 |
+
export const ORDER_BUTTON_SELECTOR = '#place_order';
|
7 |
+
|
8 |
+
export const getCurrentPaymentMethod = () => {
|
9 |
+
const el = document.querySelector('input[name="payment_method"]:checked');
|
10 |
+
if (!el) {
|
11 |
+
return null;
|
12 |
+
}
|
13 |
+
|
14 |
+
return el.value;
|
15 |
+
};
|
16 |
+
|
17 |
+
export const isSavedCardSelected = () => {
|
18 |
+
const savedCardList = document.querySelector('#saved-credit-card');
|
19 |
+
return savedCardList && savedCardList.value !== '';
|
20 |
+
};
|
modules/ppcp-button/resources/js/modules/Helper/Spinner.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
class Spinner {
|
2 |
|
3 |
-
constructor() {
|
4 |
-
this.target =
|
5 |
}
|
6 |
|
7 |
setTarget(target) {
|
1 |
class Spinner {
|
2 |
|
3 |
+
constructor(target = 'form.woocommerce-checkout') {
|
4 |
+
this.target = target;
|
5 |
}
|
6 |
|
7 |
setTarget(target) {
|
modules/ppcp-button/resources/js/modules/Helper/Subscriptions.js
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
export const isChangePaymentPage = () => {
|
2 |
+
const urlParams = new URLSearchParams(window.location.search)
|
3 |
+
return urlParams.has('change_payment_method');
|
4 |
+
}
|
modules/ppcp-button/resources/js/modules/Renderer/CreditCardRenderer.js
CHANGED
@@ -181,7 +181,7 @@ class CreditCardRenderer {
|
|
181 |
this.errorHandler.clear();
|
182 |
|
183 |
if (this.formValid && this.cardValid) {
|
184 |
-
const save_card = this.defaultConfig.
|
185 |
let vault = document.getElementById('ppcp-credit-card-vault') ?
|
186 |
document.getElementById('ppcp-credit-card-vault').checked : save_card;
|
187 |
if (this.defaultConfig.enforce_vault) {
|
@@ -216,8 +216,12 @@ class CreditCardRenderer {
|
|
216 |
this.spinner.unblock();
|
217 |
return contextConfig.onApprove(payload);
|
218 |
}).catch(err => {
|
219 |
-
console.error(err);
|
220 |
this.spinner.unblock();
|
|
|
|
|
|
|
|
|
|
|
221 |
});
|
222 |
} else {
|
223 |
this.spinner.unblock();
|
181 |
this.errorHandler.clear();
|
182 |
|
183 |
if (this.formValid && this.cardValid) {
|
184 |
+
const save_card = this.defaultConfig.can_save_vault_token ? true : false;
|
185 |
let vault = document.getElementById('ppcp-credit-card-vault') ?
|
186 |
document.getElementById('ppcp-credit-card-vault').checked : save_card;
|
187 |
if (this.defaultConfig.enforce_vault) {
|
216 |
this.spinner.unblock();
|
217 |
return contextConfig.onApprove(payload);
|
218 |
}).catch(err => {
|
|
|
219 |
this.spinner.unblock();
|
220 |
+
this.errorHandler.clear();
|
221 |
+
|
222 |
+
if (err.details) {
|
223 |
+
this.errorHandler.message(err.details.map(d => `${d.issue} ${d.description}`).join('<br/>'), true);
|
224 |
+
}
|
225 |
});
|
226 |
} else {
|
227 |
this.spinner.unblock();
|
modules/ppcp-button/resources/js/modules/Renderer/Renderer.js
CHANGED
@@ -1,8 +1,9 @@
|
|
1 |
class Renderer {
|
2 |
-
constructor(creditCardRenderer, defaultConfig, onSmartButtonClick) {
|
3 |
this.defaultConfig = defaultConfig;
|
4 |
this.creditCardRenderer = creditCardRenderer;
|
5 |
this.onSmartButtonClick = onSmartButtonClick;
|
|
|
6 |
}
|
7 |
|
8 |
render(wrapper, hostedFieldsWrapper, contextConfig) {
|
@@ -21,6 +22,7 @@ class Renderer {
|
|
21 |
style,
|
22 |
...contextConfig,
|
23 |
onClick: this.onSmartButtonClick,
|
|
|
24 |
}).render(wrapper);
|
25 |
}
|
26 |
|
1 |
class Renderer {
|
2 |
+
constructor(creditCardRenderer, defaultConfig, onSmartButtonClick, onSmartButtonsInit) {
|
3 |
this.defaultConfig = defaultConfig;
|
4 |
this.creditCardRenderer = creditCardRenderer;
|
5 |
this.onSmartButtonClick = onSmartButtonClick;
|
6 |
+
this.onSmartButtonsInit = onSmartButtonsInit;
|
7 |
}
|
8 |
|
9 |
render(wrapper, hostedFieldsWrapper, contextConfig) {
|
22 |
style,
|
23 |
...contextConfig,
|
24 |
onClick: this.onSmartButtonClick,
|
25 |
+
onInit: this.onSmartButtonsInit,
|
26 |
}).render(wrapper);
|
27 |
}
|
28 |
|
modules/ppcp-button/src/Assets/SmartButton.php
CHANGED
@@ -336,22 +336,6 @@ class SmartButton implements SmartButtonInterface {
|
|
336 |
*/
|
337 |
private function render_button_wrapper_registrar(): bool {
|
338 |
|
339 |
-
$not_enabled_on_cart = $this->settings->has( 'button_cart_enabled' ) &&
|
340 |
-
! $this->settings->get( 'button_cart_enabled' );
|
341 |
-
if (
|
342 |
-
is_cart()
|
343 |
-
&& ! $not_enabled_on_cart
|
344 |
-
) {
|
345 |
-
add_action(
|
346 |
-
$this->proceed_to_checkout_button_renderer_hook(),
|
347 |
-
array(
|
348 |
-
$this,
|
349 |
-
'button_renderer',
|
350 |
-
),
|
351 |
-
20
|
352 |
-
);
|
353 |
-
}
|
354 |
-
|
355 |
$not_enabled_on_product_page = $this->settings->has( 'button_single_product_enabled' ) &&
|
356 |
! $this->settings->get( 'button_single_product_enabled' );
|
357 |
if (
|
@@ -368,14 +352,20 @@ class SmartButton implements SmartButtonInterface {
|
|
368 |
);
|
369 |
}
|
370 |
|
|
|
|
|
371 |
$not_enabled_on_minicart = $this->settings->has( 'button_mini_cart_enabled' ) &&
|
372 |
! $this->settings->get( 'button_mini_cart_enabled' );
|
373 |
if (
|
374 |
-
|
375 |
) {
|
376 |
add_action(
|
377 |
$this->mini_cart_button_renderer_hook(),
|
378 |
-
|
|
|
|
|
|
|
|
|
379 |
echo '<p
|
380 |
id="ppc-button-minicart"
|
381 |
class="woocommerce-mini-cart__buttons buttons"
|
@@ -385,8 +375,27 @@ class SmartButton implements SmartButtonInterface {
|
|
385 |
);
|
386 |
}
|
387 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
add_action( $this->checkout_button_renderer_hook(), array( $this, 'button_renderer' ), 10 );
|
389 |
-
add_action( $this->pay_order_renderer_hook(), array( $this, 'button_renderer' ), 10 );
|
390 |
|
391 |
return true;
|
392 |
}
|
@@ -449,6 +458,7 @@ class SmartButton implements SmartButtonInterface {
|
|
449 |
|| ! $product->is_in_stock()
|
450 |
)
|
451 |
) {
|
|
|
452 |
return;
|
453 |
}
|
454 |
|
@@ -458,7 +468,9 @@ class SmartButton implements SmartButtonInterface {
|
|
458 |
return;
|
459 |
}
|
460 |
|
461 |
-
|
|
|
|
|
462 |
}
|
463 |
|
464 |
/**
|
@@ -584,12 +596,12 @@ class SmartButton implements SmartButtonInterface {
|
|
584 |
return;
|
585 |
}
|
586 |
|
587 |
-
|
588 |
$label = 'checkout' === $this->context() ? apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ) : __( 'Pay for order', 'woocommerce' );
|
589 |
|
590 |
printf(
|
591 |
'<div id="%1$s" style="display:none;">
|
592 |
-
<button class="button alt ppcp-dcc-order-button">%2$s</button>
|
593 |
</div><div id="payments-sdk__contingency-lightbox"></div><style id="ppcp-hide-dcc">.payment_method_ppcp-credit-card-gateway {display:none;}</style>',
|
594 |
esc_attr( $id ),
|
595 |
esc_html( $label )
|
@@ -664,7 +676,7 @@ class SmartButton implements SmartButtonInterface {
|
|
664 |
'script_attributes' => $this->attributes(),
|
665 |
'data_client_id' => array(
|
666 |
'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() ) || $this->can_save_vault_token(),
|
667 |
-
'endpoint' =>
|
668 |
'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ),
|
669 |
'user' => get_current_user_id(),
|
670 |
'has_subscriptions' => $this->has_subscriptions(),
|
@@ -673,20 +685,20 @@ class SmartButton implements SmartButtonInterface {
|
|
673 |
'context' => $this->context(),
|
674 |
'ajax' => array(
|
675 |
'change_cart' => array(
|
676 |
-
'endpoint' =>
|
677 |
'nonce' => wp_create_nonce( ChangeCartEndpoint::nonce() ),
|
678 |
),
|
679 |
'create_order' => array(
|
680 |
-
'endpoint' =>
|
681 |
'nonce' => wp_create_nonce( CreateOrderEndpoint::nonce() ),
|
682 |
),
|
683 |
'approve_order' => array(
|
684 |
-
'endpoint' =>
|
685 |
'nonce' => wp_create_nonce( ApproveOrderEndpoint::nonce() ),
|
686 |
),
|
687 |
),
|
688 |
'enforce_vault' => $this->has_subscriptions(),
|
689 |
-
'
|
690 |
'bn_codes' => $this->bn_codes(),
|
691 |
'payer' => $this->payerData(),
|
692 |
'button' => array(
|
@@ -1104,4 +1116,14 @@ class SmartButton implements SmartButtonInterface {
|
|
1104 |
*/
|
1105 |
return (string) apply_filters( 'woocommerce_paypal_payments_single_product_renderer_hook', 'woocommerce_single_product_summary' );
|
1106 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1107 |
}
|
336 |
*/
|
337 |
private function render_button_wrapper_registrar(): bool {
|
338 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
$not_enabled_on_product_page = $this->settings->has( 'button_single_product_enabled' ) &&
|
340 |
! $this->settings->get( 'button_single_product_enabled' );
|
341 |
if (
|
352 |
);
|
353 |
}
|
354 |
|
355 |
+
add_action( $this->pay_order_renderer_hook(), array( $this, 'button_renderer' ), 10 );
|
356 |
+
|
357 |
$not_enabled_on_minicart = $this->settings->has( 'button_mini_cart_enabled' ) &&
|
358 |
! $this->settings->get( 'button_mini_cart_enabled' );
|
359 |
if (
|
360 |
+
! $not_enabled_on_minicart
|
361 |
) {
|
362 |
add_action(
|
363 |
$this->mini_cart_button_renderer_hook(),
|
364 |
+
function () {
|
365 |
+
if ( $this->is_cart_price_total_zero() ) {
|
366 |
+
return;
|
367 |
+
}
|
368 |
+
|
369 |
echo '<p
|
370 |
id="ppc-button-minicart"
|
371 |
class="woocommerce-mini-cart__buttons buttons"
|
375 |
);
|
376 |
}
|
377 |
|
378 |
+
if ( $this->is_cart_price_total_zero() ) {
|
379 |
+
return false;
|
380 |
+
}
|
381 |
+
|
382 |
+
$not_enabled_on_cart = $this->settings->has( 'button_cart_enabled' ) &&
|
383 |
+
! $this->settings->get( 'button_cart_enabled' );
|
384 |
+
if (
|
385 |
+
is_cart()
|
386 |
+
&& ! $not_enabled_on_cart
|
387 |
+
) {
|
388 |
+
add_action(
|
389 |
+
$this->proceed_to_checkout_button_renderer_hook(),
|
390 |
+
array(
|
391 |
+
$this,
|
392 |
+
'button_renderer',
|
393 |
+
),
|
394 |
+
20
|
395 |
+
);
|
396 |
+
}
|
397 |
+
|
398 |
add_action( $this->checkout_button_renderer_hook(), array( $this, 'button_renderer' ), 10 );
|
|
|
399 |
|
400 |
return true;
|
401 |
}
|
458 |
|| ! $product->is_in_stock()
|
459 |
)
|
460 |
) {
|
461 |
+
|
462 |
return;
|
463 |
}
|
464 |
|
468 |
return;
|
469 |
}
|
470 |
|
471 |
+
// The wrapper is needed for the loading spinner,
|
472 |
+
// otherwise jQuery block() prevents buttons rendering.
|
473 |
+
echo '<div class="ppc-button-wrapper"><div id="ppc-button"></div></div>';
|
474 |
}
|
475 |
|
476 |
/**
|
596 |
return;
|
597 |
}
|
598 |
|
599 |
+
// phpcs:ignore WordPress.WP.I18n.TextDomainMismatch
|
600 |
$label = 'checkout' === $this->context() ? apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ) : __( 'Pay for order', 'woocommerce' );
|
601 |
|
602 |
printf(
|
603 |
'<div id="%1$s" style="display:none;">
|
604 |
+
<button type="submit" class="button alt ppcp-dcc-order-button">%2$s</button>
|
605 |
</div><div id="payments-sdk__contingency-lightbox"></div><style id="ppcp-hide-dcc">.payment_method_ppcp-credit-card-gateway {display:none;}</style>',
|
606 |
esc_attr( $id ),
|
607 |
esc_html( $label )
|
676 |
'script_attributes' => $this->attributes(),
|
677 |
'data_client_id' => array(
|
678 |
'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() ) || $this->can_save_vault_token(),
|
679 |
+
'endpoint' => \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ),
|
680 |
'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ),
|
681 |
'user' => get_current_user_id(),
|
682 |
'has_subscriptions' => $this->has_subscriptions(),
|
685 |
'context' => $this->context(),
|
686 |
'ajax' => array(
|
687 |
'change_cart' => array(
|
688 |
+
'endpoint' => \WC_AJAX::get_endpoint( ChangeCartEndpoint::ENDPOINT ),
|
689 |
'nonce' => wp_create_nonce( ChangeCartEndpoint::nonce() ),
|
690 |
),
|
691 |
'create_order' => array(
|
692 |
+
'endpoint' => \WC_AJAX::get_endpoint( CreateOrderEndpoint::ENDPOINT ),
|
693 |
'nonce' => wp_create_nonce( CreateOrderEndpoint::nonce() ),
|
694 |
),
|
695 |
'approve_order' => array(
|
696 |
+
'endpoint' => \WC_AJAX::get_endpoint( ApproveOrderEndpoint::ENDPOINT ),
|
697 |
'nonce' => wp_create_nonce( ApproveOrderEndpoint::nonce() ),
|
698 |
),
|
699 |
),
|
700 |
'enforce_vault' => $this->has_subscriptions(),
|
701 |
+
'can_save_vault_token' => $this->can_save_vault_token(),
|
702 |
'bn_codes' => $this->bn_codes(),
|
703 |
'payer' => $this->payerData(),
|
704 |
'button' => array(
|
1116 |
*/
|
1117 |
return (string) apply_filters( 'woocommerce_paypal_payments_single_product_renderer_hook', 'woocommerce_single_product_summary' );
|
1118 |
}
|
1119 |
+
|
1120 |
+
/**
|
1121 |
+
* Check if cart product price total is 0.
|
1122 |
+
*
|
1123 |
+
* @return bool true if is 0, otherwise false.
|
1124 |
+
*/
|
1125 |
+
protected function is_cart_price_total_zero(): bool {
|
1126 |
+
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
1127 |
+
return WC()->cart->get_cart_contents_total() == 0;
|
1128 |
+
}
|
1129 |
}
|
modules/ppcp-button/src/Helper/MessagesApply.php
CHANGED
@@ -26,6 +26,8 @@ class MessagesApply {
|
|
26 |
'GB',
|
27 |
'FR',
|
28 |
'AU',
|
|
|
|
|
29 |
);
|
30 |
|
31 |
/**
|
26 |
'GB',
|
27 |
'FR',
|
28 |
'AU',
|
29 |
+
'IT',
|
30 |
+
'ES',
|
31 |
);
|
32 |
|
33 |
/**
|
modules/ppcp-button/src/Helper/MessagesDisclaimers.php
CHANGED
@@ -23,19 +23,25 @@ class MessagesDisclaimers {
|
|
23 |
*/
|
24 |
private $disclaimers = array(
|
25 |
'US' => array(
|
26 |
-
'link' => 'https://developer.paypal.com/docs/commerce-platforms/
|
27 |
),
|
28 |
'GB' => array(
|
29 |
-
'link' => 'https://developer.paypal.com/docs/commerce-platforms/
|
30 |
),
|
31 |
'DE' => array(
|
32 |
-
'link' => 'https://developer.paypal.com/docs/commerce-platforms/
|
33 |
),
|
34 |
'AU' => array(
|
35 |
-
'link' => 'https://developer.paypal.com/docs/commerce-platforms/
|
36 |
),
|
37 |
'FR' => array(
|
38 |
-
'link' => 'https://developer.paypal.com/docs/commerce-platforms/
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
),
|
40 |
);
|
41 |
|
23 |
*/
|
24 |
private $disclaimers = array(
|
25 |
'US' => array(
|
26 |
+
'link' => 'https://developer.paypal.com/docs/checkout/pay-later/us/commerce-platforms/woocommerce/',
|
27 |
),
|
28 |
'GB' => array(
|
29 |
+
'link' => 'https://developer.paypal.com/docs/checkout/pay-later/gb/commerce-platforms/woocommerce/',
|
30 |
),
|
31 |
'DE' => array(
|
32 |
+
'link' => 'https://developer.paypal.com/docs/checkout/pay-later/de/commerce-platforms/woocommerce/',
|
33 |
),
|
34 |
'AU' => array(
|
35 |
+
'link' => 'https://developer.paypal.com/docs/checkout/pay-later/au/commerce-platforms/woocommerce/',
|
36 |
),
|
37 |
'FR' => array(
|
38 |
+
'link' => 'https://developer.paypal.com/docs/checkout/pay-later/fr/commerce-platforms/woocommerce/',
|
39 |
+
),
|
40 |
+
'IT' => array(
|
41 |
+
'link' => 'https://developer.paypal.com/docs/checkout/pay-later/it/commerce-platforms/woocommerce/',
|
42 |
+
),
|
43 |
+
'ES' => array(
|
44 |
+
'link' => 'https://developer.paypal.com/docs/checkout/pay-later/es/commerce-platforms/woocommerce/',
|
45 |
),
|
46 |
);
|
47 |
|
modules/ppcp-onboarding/src/Assets/OnboardingAssets.php
CHANGED
@@ -135,7 +135,7 @@ class OnboardingAssets {
|
|
135 |
*/
|
136 |
public function get_script_data() {
|
137 |
return array(
|
138 |
-
'endpoint' =>
|
139 |
'nonce' => wp_create_nonce( $this->login_seller_endpoint::nonce() ),
|
140 |
'paypal_js_url' => 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js',
|
141 |
'sandbox_state' => State::get_state_name( $this->state->sandbox_state() ),
|
135 |
*/
|
136 |
public function get_script_data() {
|
137 |
return array(
|
138 |
+
'endpoint' => \WC_AJAX::get_endpoint( LoginSellerEndpoint::ENDPOINT ),
|
139 |
'nonce' => wp_create_nonce( $this->login_seller_endpoint::nonce() ),
|
140 |
'paypal_js_url' => 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js',
|
141 |
'sandbox_state' => State::get_state_name( $this->state->sandbox_state() ),
|
modules/ppcp-vaulting/services.php
CHANGED
@@ -41,4 +41,14 @@ return array(
|
|
41 |
$container->get( 'woocommerce.logger.woocommerce' )
|
42 |
);
|
43 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
);
|
41 |
$container->get( 'woocommerce.logger.woocommerce' )
|
42 |
);
|
43 |
},
|
44 |
+
'vaulting.payment-token-checker' => function( ContainerInterface $container ) : PaymentTokenChecker {
|
45 |
+
return new PaymentTokenChecker(
|
46 |
+
$container->get( 'vaulting.repository.payment-token' ),
|
47 |
+
$container->get( 'wcgateway.settings' ),
|
48 |
+
$container->get( 'wcgateway.processor.authorized-payments' ),
|
49 |
+
$container->get( 'api.endpoint.order' ),
|
50 |
+
$container->get( 'api.endpoint.payments' ),
|
51 |
+
$container->get( 'woocommerce.logger.woocommerce' )
|
52 |
+
);
|
53 |
+
},
|
54 |
);
|
modules/ppcp-vaulting/src/Assets/MyAccountPaymentsAssets.php
CHANGED
@@ -68,7 +68,7 @@ class MyAccountPaymentsAssets {
|
|
68 |
'PayPalCommerceGatewayVaulting',
|
69 |
array(
|
70 |
'delete' => array(
|
71 |
-
'endpoint' =>
|
72 |
'nonce' => wp_create_nonce( DeletePaymentTokenEndpoint::nonce() ),
|
73 |
),
|
74 |
)
|
68 |
'PayPalCommerceGatewayVaulting',
|
69 |
array(
|
70 |
'delete' => array(
|
71 |
+
'endpoint' => \WC_AJAX::get_endpoint( DeletePaymentTokenEndpoint::ENDPOINT ),
|
72 |
'nonce' => wp_create_nonce( DeletePaymentTokenEndpoint::nonce() ),
|
73 |
),
|
74 |
)
|
modules/ppcp-vaulting/src/PaymentTokenChecker.php
ADDED
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Check if payment token is saved and updates order accordingly.
|
4 |
+
*
|
5 |
+
* @package WooCommerce\PayPalCommerce\Vaulting
|
6 |
+
*/
|
7 |
+
|
8 |
+
declare(strict_types=1);
|
9 |
+
|
10 |
+
namespace WooCommerce\PayPalCommerce\Vaulting;
|
11 |
+
|
12 |
+
use Exception;
|
13 |
+
use Psr\Log\LoggerInterface;
|
14 |
+
use RuntimeException;
|
15 |
+
use WC_Order;
|
16 |
+
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
17 |
+
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
18 |
+
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
|
19 |
+
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
20 |
+
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
21 |
+
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
22 |
+
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Class PaymentTokenChecker
|
26 |
+
*/
|
27 |
+
class PaymentTokenChecker {
|
28 |
+
|
29 |
+
/**
|
30 |
+
* The payment token repository.
|
31 |
+
*
|
32 |
+
* @var PaymentTokenRepository
|
33 |
+
*/
|
34 |
+
protected $payment_token_repository;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* The settings.
|
38 |
+
*
|
39 |
+
* @var Settings
|
40 |
+
*/
|
41 |
+
protected $settings;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* The authorized payments processor.
|
45 |
+
*
|
46 |
+
* @var AuthorizedPaymentsProcessor
|
47 |
+
*/
|
48 |
+
protected $authorized_payments_processor;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* The order endpoint.
|
52 |
+
*
|
53 |
+
* @var OrderEndpoint
|
54 |
+
*/
|
55 |
+
protected $order_endpoint;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* The payments endpoint.
|
59 |
+
*
|
60 |
+
* @var PaymentsEndpoint
|
61 |
+
*/
|
62 |
+
protected $payments_endpoint;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* The logger.
|
66 |
+
*
|
67 |
+
* @var LoggerInterface
|
68 |
+
*/
|
69 |
+
protected $logger;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* PaymentTokenChecker constructor.
|
73 |
+
*
|
74 |
+
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
|
75 |
+
* @param Settings $settings The settings.
|
76 |
+
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The authorized payments processor.
|
77 |
+
* @param OrderEndpoint $order_endpoint The order endpoint.
|
78 |
+
* @param PaymentsEndpoint $payments_endpoint The payments endpoint.
|
79 |
+
* @param LoggerInterface $logger The logger.
|
80 |
+
*/
|
81 |
+
public function __construct(
|
82 |
+
PaymentTokenRepository $payment_token_repository,
|
83 |
+
Settings $settings,
|
84 |
+
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
85 |
+
OrderEndpoint $order_endpoint,
|
86 |
+
PaymentsEndpoint $payments_endpoint,
|
87 |
+
LoggerInterface $logger
|
88 |
+
) {
|
89 |
+
$this->payment_token_repository = $payment_token_repository;
|
90 |
+
$this->settings = $settings;
|
91 |
+
$this->authorized_payments_processor = $authorized_payments_processor;
|
92 |
+
$this->order_endpoint = $order_endpoint;
|
93 |
+
$this->payments_endpoint = $payments_endpoint;
|
94 |
+
$this->logger = $logger;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Check if payment token exist and updates order accordingly.
|
99 |
+
*
|
100 |
+
* @param int $order_id The order ID.
|
101 |
+
* @param int $customer_id The customer ID.
|
102 |
+
* @param string $intent The intent from settings when order was created.
|
103 |
+
* @return void
|
104 |
+
*/
|
105 |
+
public function check_and_update( int $order_id, int $customer_id, string $intent ):void {
|
106 |
+
$wc_order = wc_get_order( $order_id );
|
107 |
+
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
108 |
+
return;
|
109 |
+
}
|
110 |
+
|
111 |
+
if ( $wc_order->get_status() === 'processing' || 'capture' !== $intent ) {
|
112 |
+
return;
|
113 |
+
}
|
114 |
+
|
115 |
+
$tokens = $this->payment_token_repository->all_for_user_id( $customer_id );
|
116 |
+
if ( $tokens ) {
|
117 |
+
try {
|
118 |
+
$this->capture_authorized_payment( $wc_order );
|
119 |
+
} catch ( Exception $exception ) {
|
120 |
+
$this->logger->error( $exception->getMessage() );
|
121 |
+
}
|
122 |
+
|
123 |
+
return;
|
124 |
+
}
|
125 |
+
|
126 |
+
$this->logger->error( "Payment for subscription parent order #{$order_id} was not saved on PayPal." );
|
127 |
+
|
128 |
+
try {
|
129 |
+
$order = $this->get_order( $wc_order );
|
130 |
+
$this->void_authorizations( $order );
|
131 |
+
} catch ( RuntimeException $exception ) {
|
132 |
+
$this->logger->warning( $exception->getMessage() );
|
133 |
+
}
|
134 |
+
|
135 |
+
$this->update_failed_status( $wc_order );
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Captures authorized payments for the given WC order.
|
140 |
+
*
|
141 |
+
* @param WC_Order $wc_order The WC order.
|
142 |
+
* @throws Exception When there is a problem capturing the payment.
|
143 |
+
*/
|
144 |
+
private function capture_authorized_payment( WC_Order $wc_order ): void {
|
145 |
+
if ( $this->settings->has( 'intent' ) && strtoupper( (string) $this->settings->get( 'intent' ) ) === 'CAPTURE' ) {
|
146 |
+
if ( ! $this->authorized_payments_processor->capture_authorized_payment( $wc_order ) ) {
|
147 |
+
throw new Exception( "Could not capture payment for order: #{$wc_order->get_id()}" );
|
148 |
+
}
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Voids authorizations for the given PayPal order.
|
154 |
+
*
|
155 |
+
* @param Order $order The PayPal order.
|
156 |
+
* @return void
|
157 |
+
* @throws RuntimeException When there is a problem voiding authorizations.
|
158 |
+
*/
|
159 |
+
private function void_authorizations( Order $order ): void {
|
160 |
+
$purchase_units = $order->purchase_units();
|
161 |
+
if ( ! $purchase_units ) {
|
162 |
+
throw new RuntimeException( 'No purchase units.' );
|
163 |
+
}
|
164 |
+
|
165 |
+
$payments = $purchase_units[0]->payments();
|
166 |
+
if ( ! $payments ) {
|
167 |
+
throw new RuntimeException( 'No payments.' );
|
168 |
+
}
|
169 |
+
|
170 |
+
$voidable_authorizations = array_filter(
|
171 |
+
$payments->authorizations(),
|
172 |
+
function ( Authorization $authorization ): bool {
|
173 |
+
return $authorization->is_voidable();
|
174 |
+
}
|
175 |
+
);
|
176 |
+
if ( ! $voidable_authorizations ) {
|
177 |
+
throw new RuntimeException( 'No voidable authorizations.' );
|
178 |
+
}
|
179 |
+
|
180 |
+
foreach ( $voidable_authorizations as $authorization ) {
|
181 |
+
$this->payments_endpoint->void( $authorization );
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Gets a PayPal order from the given WooCommerce order.
|
187 |
+
*
|
188 |
+
* @param WC_Order $wc_order The WooCommerce order.
|
189 |
+
* @return Order The PayPal order.
|
190 |
+
* @throws RuntimeException When there is a problem getting the PayPal order.
|
191 |
+
*/
|
192 |
+
private function get_order( WC_Order $wc_order ): Order {
|
193 |
+
$paypal_order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
194 |
+
if ( ! $paypal_order_id ) {
|
195 |
+
throw new RuntimeException( 'PayPal order ID not found in meta.' );
|
196 |
+
}
|
197 |
+
|
198 |
+
return $this->order_endpoint->order( $paypal_order_id );
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Updates WC order and subscription status to failed and canceled respectively.
|
203 |
+
*
|
204 |
+
* @param WC_Order $wc_order The WC order.
|
205 |
+
*/
|
206 |
+
private function update_failed_status( WC_Order $wc_order ): void {
|
207 |
+
$error_message = __( 'Could not process order because it was not possible to save the payment on PayPal.', 'woocommerce-paypal-payments' );
|
208 |
+
$wc_order->update_status( 'failed', $error_message );
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Function already exist in Subscription plugin
|
212 |
+
*
|
213 |
+
* @psalm-suppress UndefinedFunction
|
214 |
+
*/
|
215 |
+
$subscriptions = wcs_get_subscriptions_for_order( $wc_order->get_id() );
|
216 |
+
foreach ( $subscriptions as $key => $subscription ) {
|
217 |
+
if ( $subscription->get_parent_id() === $wc_order->get_id() ) {
|
218 |
+
try {
|
219 |
+
$subscription->update_status( 'cancelled' );
|
220 |
+
break;
|
221 |
+
} catch ( Exception $exception ) {
|
222 |
+
$this->logger->error( "Could not update cancelled status on subscription #{$subscription->get_id()} " . $exception->getMessage() );
|
223 |
+
}
|
224 |
+
}
|
225 |
+
}
|
226 |
+
}
|
227 |
+
}
|
modules/ppcp-vaulting/src/VaultingModule.php
CHANGED
@@ -129,6 +129,16 @@ class VaultingModule implements ModuleInterface {
|
|
129 |
$endpoint->handle_request();
|
130 |
}
|
131 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
}
|
133 |
|
134 |
/**
|
129 |
$endpoint->handle_request();
|
130 |
}
|
131 |
);
|
132 |
+
|
133 |
+
add_action(
|
134 |
+
'woocommerce_paypal_payments_check_saved_payment',
|
135 |
+
function ( int $order_id, int $customer_id, string $intent ) use ( $container ) {
|
136 |
+
$payment_token_checker = $container->get( 'vaulting.payment-token-checker' );
|
137 |
+
$payment_token_checker->check_and_update( $order_id, $customer_id, $intent );
|
138 |
+
},
|
139 |
+
10,
|
140 |
+
3
|
141 |
+
);
|
142 |
}
|
143 |
|
144 |
/**
|
modules/ppcp-wc-gateway/services.php
CHANGED
@@ -216,6 +216,7 @@ return array(
|
|
216 |
$settings = $container->get( 'wcgateway.settings' );
|
217 |
$environment = $container->get( 'onboarding.environment' );
|
218 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
|
|
219 |
return new OrderProcessor(
|
220 |
$session_handler,
|
221 |
$order_endpoint,
|
@@ -224,7 +225,8 @@ return array(
|
|
224 |
$authorized_payments_processor,
|
225 |
$settings,
|
226 |
$logger,
|
227 |
-
$environment
|
|
|
228 |
);
|
229 |
},
|
230 |
'wcgateway.processor.refunds' => static function ( ContainerInterface $container ): RefundProcessor {
|
@@ -238,7 +240,16 @@ return array(
|
|
238 |
$payments_endpoint = $container->get( 'api.endpoint.payments' );
|
239 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
240 |
$notice = $container->get( 'wcgateway.notice.authorize-order-action' );
|
241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
},
|
243 |
'wcgateway.admin.render-authorize-action' => static function ( ContainerInterface $container ): RenderAuthorizeAction {
|
244 |
$column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
216 |
$settings = $container->get( 'wcgateway.settings' );
|
217 |
$environment = $container->get( 'onboarding.environment' );
|
218 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
219 |
+
$subscription_helper = $container->get( 'subscription.helper' );
|
220 |
return new OrderProcessor(
|
221 |
$session_handler,
|
222 |
$order_endpoint,
|
225 |
$authorized_payments_processor,
|
226 |
$settings,
|
227 |
$logger,
|
228 |
+
$environment,
|
229 |
+
$subscription_helper
|
230 |
);
|
231 |
},
|
232 |
'wcgateway.processor.refunds' => static function ( ContainerInterface $container ): RefundProcessor {
|
240 |
$payments_endpoint = $container->get( 'api.endpoint.payments' );
|
241 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
242 |
$notice = $container->get( 'wcgateway.notice.authorize-order-action' );
|
243 |
+
$settings = $container->get( 'wcgateway.settings' );
|
244 |
+
$subscription_helper = $container->get( 'subscription.helper' );
|
245 |
+
return new AuthorizedPaymentsProcessor(
|
246 |
+
$order_endpoint,
|
247 |
+
$payments_endpoint,
|
248 |
+
$logger,
|
249 |
+
$notice,
|
250 |
+
$settings,
|
251 |
+
$subscription_helper
|
252 |
+
);
|
253 |
},
|
254 |
'wcgateway.admin.render-authorize-action' => static function ( ContainerInterface $container ): RenderAuthorizeAction {
|
255 |
$column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
modules/ppcp-wc-gateway/src/Gateway/ProcessPaymentTrait.php
CHANGED
@@ -10,8 +10,6 @@ declare( strict_types=1 );
|
|
10 |
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
11 |
|
12 |
use Exception;
|
13 |
-
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
|
14 |
-
use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
17 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
@@ -173,96 +171,16 @@ trait ProcessPaymentTrait {
|
|
173 |
|
174 |
try {
|
175 |
if ( $this->order_processor->process( $wc_order ) ) {
|
176 |
-
|
177 |
if ( $this->subscription_helper->has_subscription( $order_id ) ) {
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
$this->authorized_payments_processor->capture_authorized_payment( $wc_order );
|
186 |
-
}
|
187 |
-
|
188 |
-
$this->session_handler->destroy_session_data();
|
189 |
-
|
190 |
-
return array(
|
191 |
-
'result' => 'success',
|
192 |
-
'redirect' => $this->get_return_url( $wc_order ),
|
193 |
-
);
|
194 |
-
}
|
195 |
-
|
196 |
-
$this->logger->error( "Payment for subscription parent order #{$order_id} was not saved." );
|
197 |
-
|
198 |
-
$paypal_order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
199 |
-
if ( ! $paypal_order_id ) {
|
200 |
-
throw new RuntimeException( 'PayPal order ID not found in meta.' );
|
201 |
-
}
|
202 |
-
$order = $this->order_endpoint->order( $paypal_order_id );
|
203 |
-
|
204 |
-
$purchase_units = $order->purchase_units();
|
205 |
-
if ( ! $purchase_units ) {
|
206 |
-
throw new RuntimeException( 'No purchase units.' );
|
207 |
-
}
|
208 |
-
|
209 |
-
$payments = $purchase_units[0]->payments();
|
210 |
-
if ( ! $payments ) {
|
211 |
-
throw new RuntimeException( 'No payments.' );
|
212 |
-
}
|
213 |
-
|
214 |
-
$this->logger->debug(
|
215 |
-
sprintf(
|
216 |
-
'Trying to void order %1$s, payments: %2$s.',
|
217 |
-
$order->id(),
|
218 |
-
wp_json_encode( $payments->to_array() )
|
219 |
-
)
|
220 |
-
);
|
221 |
-
|
222 |
-
$voidable_authorizations = array_filter(
|
223 |
-
$payments->authorizations(),
|
224 |
-
function ( Authorization $authorization ): bool {
|
225 |
-
return $authorization->is_voidable();
|
226 |
-
}
|
227 |
-
);
|
228 |
-
if ( ! $voidable_authorizations ) {
|
229 |
-
throw new RuntimeException( 'No voidable authorizations.' );
|
230 |
-
}
|
231 |
-
|
232 |
-
foreach ( $voidable_authorizations as $authorization ) {
|
233 |
-
$this->payments_endpoint->void( $authorization );
|
234 |
-
}
|
235 |
-
|
236 |
-
$this->logger->debug(
|
237 |
-
sprintf(
|
238 |
-
'Order %1$s voided successfully.',
|
239 |
-
$order->id()
|
240 |
)
|
241 |
);
|
242 |
-
|
243 |
-
$error_message = __( 'Could not process order because it was not possible to save the payment.', 'woocommerce-paypal-payments' );
|
244 |
-
$wc_order->update_status( 'failed', $error_message );
|
245 |
-
|
246 |
-
$subscriptions = wcs_get_subscriptions_for_order( $order_id );
|
247 |
-
foreach ( $subscriptions as $key => $subscription ) {
|
248 |
-
if ( $subscription->get_parent_id() === $order_id ) {
|
249 |
-
try {
|
250 |
-
$subscription->update_status( 'cancelled' );
|
251 |
-
break;
|
252 |
-
} catch ( Exception $exception ) {
|
253 |
-
$this->logger->error( "Could not update cancelled status on subscription #{$subscription->get_id()} " . $exception->getMessage() );
|
254 |
-
}
|
255 |
-
}
|
256 |
-
}
|
257 |
-
|
258 |
-
// Adds retry counter meta to avoid duplicate invoice id error on consequent tries.
|
259 |
-
$wc_order->update_meta_data( 'ppcp-retry', (int) $wc_order->get_meta( 'ppcp-retry' ) + 1 );
|
260 |
-
$wc_order->save_meta_data();
|
261 |
-
|
262 |
-
$this->session_handler->destroy_session_data();
|
263 |
-
wc_add_notice( $error_message, 'error' );
|
264 |
-
|
265 |
-
return $failure_data;
|
266 |
}
|
267 |
|
268 |
WC()->cart->empty_cart();
|
10 |
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
11 |
|
12 |
use Exception;
|
|
|
|
|
13 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
14 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
171 |
|
172 |
try {
|
173 |
if ( $this->order_processor->process( $wc_order ) ) {
|
|
|
174 |
if ( $this->subscription_helper->has_subscription( $order_id ) ) {
|
175 |
+
as_schedule_single_action(
|
176 |
+
time() + ( 1 * MINUTE_IN_SECONDS ),
|
177 |
+
'woocommerce_paypal_payments_check_saved_payment',
|
178 |
+
array(
|
179 |
+
'order_id' => $order_id,
|
180 |
+
'customer_id' => $wc_order->get_customer_id(),
|
181 |
+
'intent' => $this->config->has( 'intent' ) ? $this->config->get( 'intent' ) : '',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
)
|
183 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
}
|
185 |
|
186 |
WC()->cart->empty_cart();
|
modules/ppcp-wc-gateway/src/Processor/AuthorizedPaymentsProcessor.php
CHANGED
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|
10 |
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
11 |
|
12 |
use Exception;
|
|
|
13 |
use Psr\Log\LoggerInterface;
|
14 |
use WC_Order;
|
15 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
@@ -20,6 +21,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
|
|
20 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
|
21 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
22 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
|
|
23 |
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
24 |
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
25 |
|
@@ -74,6 +76,20 @@ class AuthorizedPaymentsProcessor {
|
|
74 |
*/
|
75 |
private $notice;
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
/**
|
78 |
* AuthorizedPaymentsProcessor constructor.
|
79 |
*
|
@@ -81,18 +97,24 @@ class AuthorizedPaymentsProcessor {
|
|
81 |
* @param PaymentsEndpoint $payments_endpoint The Payments endpoint.
|
82 |
* @param LoggerInterface $logger The logger.
|
83 |
* @param AuthorizeOrderActionNotice $notice The notice.
|
|
|
|
|
84 |
*/
|
85 |
public function __construct(
|
86 |
OrderEndpoint $order_endpoint,
|
87 |
PaymentsEndpoint $payments_endpoint,
|
88 |
LoggerInterface $logger,
|
89 |
-
AuthorizeOrderActionNotice $notice
|
|
|
|
|
90 |
) {
|
91 |
|
92 |
-
$this->order_endpoint
|
93 |
-
$this->payments_endpoint
|
94 |
-
$this->logger
|
95 |
-
$this->notice
|
|
|
|
|
96 |
}
|
97 |
|
98 |
/**
|
@@ -190,6 +212,38 @@ class AuthorizedPaymentsProcessor {
|
|
190 |
return false;
|
191 |
}
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
/**
|
194 |
* Displays the notice for a status.
|
195 |
*
|
10 |
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
11 |
|
12 |
use Exception;
|
13 |
+
use Psr\Container\ContainerInterface;
|
14 |
use Psr\Log\LoggerInterface;
|
15 |
use WC_Order;
|
16 |
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
21 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
|
22 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
23 |
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
24 |
+
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
25 |
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
26 |
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
27 |
|
76 |
*/
|
77 |
private $notice;
|
78 |
|
79 |
+
/**
|
80 |
+
* The settings.
|
81 |
+
*
|
82 |
+
* @var ContainerInterface
|
83 |
+
*/
|
84 |
+
private $config;
|
85 |
+
|
86 |
+
/**
|
87 |
+
* The subscription helper.
|
88 |
+
*
|
89 |
+
* @var SubscriptionHelper
|
90 |
+
*/
|
91 |
+
private $subscription_helper;
|
92 |
+
|
93 |
/**
|
94 |
* AuthorizedPaymentsProcessor constructor.
|
95 |
*
|
97 |
* @param PaymentsEndpoint $payments_endpoint The Payments endpoint.
|
98 |
* @param LoggerInterface $logger The logger.
|
99 |
* @param AuthorizeOrderActionNotice $notice The notice.
|
100 |
+
* @param ContainerInterface $config The settings.
|
101 |
+
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
102 |
*/
|
103 |
public function __construct(
|
104 |
OrderEndpoint $order_endpoint,
|
105 |
PaymentsEndpoint $payments_endpoint,
|
106 |
LoggerInterface $logger,
|
107 |
+
AuthorizeOrderActionNotice $notice,
|
108 |
+
ContainerInterface $config,
|
109 |
+
SubscriptionHelper $subscription_helper
|
110 |
) {
|
111 |
|
112 |
+
$this->order_endpoint = $order_endpoint;
|
113 |
+
$this->payments_endpoint = $payments_endpoint;
|
114 |
+
$this->logger = $logger;
|
115 |
+
$this->notice = $notice;
|
116 |
+
$this->config = $config;
|
117 |
+
$this->subscription_helper = $subscription_helper;
|
118 |
}
|
119 |
|
120 |
/**
|
212 |
return false;
|
213 |
}
|
214 |
|
215 |
+
/**
|
216 |
+
* Captures the authorized payments for the given customer.
|
217 |
+
*
|
218 |
+
* @param int $customer_id The customer id.
|
219 |
+
*/
|
220 |
+
public function capture_authorized_payments_for_customer( int $customer_id ): void {
|
221 |
+
|
222 |
+
$wc_orders = wc_get_orders(
|
223 |
+
array(
|
224 |
+
'customer_id' => $customer_id,
|
225 |
+
'status' => array( 'wc-on-hold' ),
|
226 |
+
'limit' => -1,
|
227 |
+
)
|
228 |
+
);
|
229 |
+
|
230 |
+
if (
|
231 |
+
$this->config->has( 'intent' )
|
232 |
+
&& strtoupper( (string) $this->config->get( 'intent' ) ) === 'CAPTURE'
|
233 |
+
&& is_array( $wc_orders )
|
234 |
+
) {
|
235 |
+
foreach ( $wc_orders as $wc_order ) {
|
236 |
+
if (
|
237 |
+
$this->subscription_helper->has_subscription( $wc_order->get_id() )
|
238 |
+
&& $wc_order->get_meta( '_ppcp_captured_vault_webhook' ) === 'false'
|
239 |
+
) {
|
240 |
+
$this->capture_authorized_payment( $wc_order );
|
241 |
+
$wc_order->update_meta_data( '_ppcp_captured_vault_webhook', 'true' );
|
242 |
+
}
|
243 |
+
}
|
244 |
+
}
|
245 |
+
}
|
246 |
+
|
247 |
/**
|
248 |
* Displays the notice for a status.
|
249 |
*
|
modules/ppcp-wc-gateway/src/Processor/OrderProcessor.php
CHANGED
@@ -17,6 +17,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
|
17 |
use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
|
18 |
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
19 |
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
|
|
20 |
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
21 |
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
22 |
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
@@ -98,6 +99,13 @@ class OrderProcessor {
|
|
98 |
*/
|
99 |
private $logger;
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
/**
|
102 |
* OrderProcessor constructor.
|
103 |
*
|
@@ -109,6 +117,7 @@ class OrderProcessor {
|
|
109 |
* @param Settings $settings The Settings.
|
110 |
* @param LoggerInterface $logger A logger service.
|
111 |
* @param Environment $environment The environment.
|
|
|
112 |
*/
|
113 |
public function __construct(
|
114 |
SessionHandler $session_handler,
|
@@ -118,7 +127,8 @@ class OrderProcessor {
|
|
118 |
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
119 |
Settings $settings,
|
120 |
LoggerInterface $logger,
|
121 |
-
Environment $environment
|
|
|
122 |
) {
|
123 |
|
124 |
$this->session_handler = $session_handler;
|
@@ -129,6 +139,7 @@ class OrderProcessor {
|
|
129 |
$this->settings = $settings;
|
130 |
$this->environment = $environment;
|
131 |
$this->logger = $logger;
|
|
|
132 |
}
|
133 |
|
134 |
/**
|
@@ -173,6 +184,10 @@ class OrderProcessor {
|
|
173 |
$order = $this->order_endpoint->authorize( $order );
|
174 |
|
175 |
$wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
|
|
|
|
|
|
|
|
|
176 |
}
|
177 |
|
178 |
$transaction_id = $this->get_paypal_order_transaction_id( $order );
|
17 |
use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
|
18 |
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
19 |
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
20 |
+
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
21 |
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
22 |
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
23 |
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
99 |
*/
|
100 |
private $logger;
|
101 |
|
102 |
+
/**
|
103 |
+
* The subscription helper.
|
104 |
+
*
|
105 |
+
* @var SubscriptionHelper
|
106 |
+
*/
|
107 |
+
private $subscription_helper;
|
108 |
+
|
109 |
/**
|
110 |
* OrderProcessor constructor.
|
111 |
*
|
117 |
* @param Settings $settings The Settings.
|
118 |
* @param LoggerInterface $logger A logger service.
|
119 |
* @param Environment $environment The environment.
|
120 |
+
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
121 |
*/
|
122 |
public function __construct(
|
123 |
SessionHandler $session_handler,
|
127 |
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
128 |
Settings $settings,
|
129 |
LoggerInterface $logger,
|
130 |
+
Environment $environment,
|
131 |
+
SubscriptionHelper $subscription_helper
|
132 |
) {
|
133 |
|
134 |
$this->session_handler = $session_handler;
|
139 |
$this->settings = $settings;
|
140 |
$this->environment = $environment;
|
141 |
$this->logger = $logger;
|
142 |
+
$this->subscription_helper = $subscription_helper;
|
143 |
}
|
144 |
|
145 |
/**
|
184 |
$order = $this->order_endpoint->authorize( $order );
|
185 |
|
186 |
$wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'false' );
|
187 |
+
|
188 |
+
if ( $this->subscription_helper->has_subscription( $wc_order->get_id() ) ) {
|
189 |
+
$wc_order->update_meta_data( '_ppcp_captured_vault_webhook', 'false' );
|
190 |
+
}
|
191 |
}
|
192 |
|
193 |
$transaction_id = $this->get_paypal_order_transaction_id( $order );
|
modules/ppcp-webhooks/services.php
CHANGED
@@ -23,6 +23,8 @@ use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureCompleted;
|
|
23 |
use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureRefunded;
|
24 |
use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureReversed;
|
25 |
use Psr\Container\ContainerInterface;
|
|
|
|
|
26 |
use WooCommerce\PayPalCommerce\Webhooks\Status\Assets\WebhooksStatusPageAssets;
|
27 |
use WooCommerce\PayPalCommerce\Webhooks\Status\WebhookSimulation;
|
28 |
|
@@ -67,12 +69,15 @@ return array(
|
|
67 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
68 |
$prefix = $container->get( 'api.prefix' );
|
69 |
$order_endpoint = $container->get( 'api.endpoint.order' );
|
|
|
70 |
return array(
|
71 |
new CheckoutOrderApproved( $logger, $prefix, $order_endpoint ),
|
72 |
new CheckoutOrderCompleted( $logger, $prefix ),
|
73 |
new PaymentCaptureRefunded( $logger, $prefix ),
|
74 |
new PaymentCaptureReversed( $logger, $prefix ),
|
75 |
new PaymentCaptureCompleted( $logger, $prefix, $order_endpoint ),
|
|
|
|
|
76 |
);
|
77 |
},
|
78 |
|
23 |
use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureRefunded;
|
24 |
use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureReversed;
|
25 |
use Psr\Container\ContainerInterface;
|
26 |
+
use WooCommerce\PayPalCommerce\Webhooks\Handler\VaultCreditCardCreated;
|
27 |
+
use WooCommerce\PayPalCommerce\Webhooks\Handler\VaultPaymentTokenCreated;
|
28 |
use WooCommerce\PayPalCommerce\Webhooks\Status\Assets\WebhooksStatusPageAssets;
|
29 |
use WooCommerce\PayPalCommerce\Webhooks\Status\WebhookSimulation;
|
30 |
|
69 |
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
70 |
$prefix = $container->get( 'api.prefix' );
|
71 |
$order_endpoint = $container->get( 'api.endpoint.order' );
|
72 |
+
$authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' );
|
73 |
return array(
|
74 |
new CheckoutOrderApproved( $logger, $prefix, $order_endpoint ),
|
75 |
new CheckoutOrderCompleted( $logger, $prefix ),
|
76 |
new PaymentCaptureRefunded( $logger, $prefix ),
|
77 |
new PaymentCaptureReversed( $logger, $prefix ),
|
78 |
new PaymentCaptureCompleted( $logger, $prefix, $order_endpoint ),
|
79 |
+
new VaultPaymentTokenCreated( $logger, $prefix, $authorized_payments_processor ),
|
80 |
+
new VaultCreditCardCreated( $logger, $prefix ),
|
81 |
);
|
82 |
},
|
83 |
|
modules/ppcp-webhooks/src/Handler/RequestHandler.php
CHANGED
@@ -9,6 +9,9 @@ declare(strict_types=1);
|
|
9 |
|
10 |
namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
|
11 |
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Interface RequestHandler
|
14 |
*/
|
@@ -24,18 +27,18 @@ interface RequestHandler {
|
|
24 |
/**
|
25 |
* Whether a handler is responsible for a given request or not.
|
26 |
*
|
27 |
-
* @param
|
28 |
*
|
29 |
* @return bool
|
30 |
*/
|
31 |
-
public function responsible_for_request(
|
32 |
|
33 |
/**
|
34 |
* Responsible for handling the request.
|
35 |
*
|
36 |
-
* @param
|
37 |
*
|
38 |
-
* @return
|
39 |
*/
|
40 |
-
public function handle_request(
|
41 |
}
|
9 |
|
10 |
namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
|
11 |
|
12 |
+
use WP_REST_Request;
|
13 |
+
use WP_REST_Response;
|
14 |
+
|
15 |
/**
|
16 |
* Interface RequestHandler
|
17 |
*/
|
27 |
/**
|
28 |
* Whether a handler is responsible for a given request or not.
|
29 |
*
|
30 |
+
* @param WP_REST_Request $request The request.
|
31 |
*
|
32 |
* @return bool
|
33 |
*/
|
34 |
+
public function responsible_for_request( WP_REST_Request $request): bool;
|
35 |
|
36 |
/**
|
37 |
* Responsible for handling the request.
|
38 |
*
|
39 |
+
* @param WP_REST_Request $request The request.
|
40 |
*
|
41 |
+
* @return WP_REST_Response
|
42 |
*/
|
43 |
+
public function handle_request( WP_REST_Request $request): WP_REST_Response;
|
44 |
}
|
modules/ppcp-webhooks/src/Handler/VaultCreditCardCreated.php
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Handles the Webhook VAULT.CREDIT-CARD.CREATED
|
4 |
+
*
|
5 |
+
* @package WooCommerce\PayPalCommerce\Webhooks\Handler
|
6 |
+
*/
|
7 |
+
|
8 |
+
declare(strict_types=1);
|
9 |
+
|
10 |
+
namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
|
11 |
+
|
12 |
+
use Psr\Log\LoggerInterface;
|
13 |
+
use WP_REST_Request;
|
14 |
+
use WP_REST_Response;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Class VaultCreditCardCreated
|
18 |
+
*/
|
19 |
+
class VaultCreditCardCreated implements RequestHandler {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* The logger.
|
23 |
+
*
|
24 |
+
* @var LoggerInterface
|
25 |
+
*/
|
26 |
+
protected $logger;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* The prefix.
|
30 |
+
*
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
protected $prefix;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* VaultCreditCardCreated constructor.
|
37 |
+
*
|
38 |
+
* @param LoggerInterface $logger The logger.
|
39 |
+
* @param string $prefix The prefix.
|
40 |
+
*/
|
41 |
+
public function __construct( LoggerInterface $logger, string $prefix ) {
|
42 |
+
$this->logger = $logger;
|
43 |
+
$this->prefix = $prefix;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* The event types a handler handles.
|
48 |
+
*
|
49 |
+
* @return string[]
|
50 |
+
*/
|
51 |
+
public function event_types(): array {
|
52 |
+
return array(
|
53 |
+
'VAULT.CREDIT-CARD.CREATED',
|
54 |
+
);
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Whether a handler is responsible for a given request or not.
|
59 |
+
*
|
60 |
+
* @param WP_REST_Request $request The request.
|
61 |
+
*
|
62 |
+
* @return bool
|
63 |
+
*/
|
64 |
+
public function responsible_for_request( WP_REST_Request $request ): bool {
|
65 |
+
return in_array( $request['event_type'], $this->event_types(), true );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Responsible for handling the request.
|
70 |
+
*
|
71 |
+
* @param WP_REST_Request $request The request.
|
72 |
+
*
|
73 |
+
* @return WP_REST_Response
|
74 |
+
*/
|
75 |
+
public function handle_request( WP_REST_Request $request ): WP_REST_Response {
|
76 |
+
// TODO currently this webhook is not triggered from PayPal, implement it once is available.
|
77 |
+
|
78 |
+
$message = 'VAULT.CREDIT-CARD.CREATED received.';
|
79 |
+
$this->logger->log( 'info', $message );
|
80 |
+
$response = array(
|
81 |
+
'success' => true,
|
82 |
+
'message' => $message,
|
83 |
+
);
|
84 |
+
|
85 |
+
return new WP_REST_Response( $response );
|
86 |
+
}
|
87 |
+
}
|
modules/ppcp-webhooks/src/Handler/VaultPaymentTokenCreated.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Handles the Webhook VAULT.PAYMENT-TOKEN.CREATED
|
4 |
+
*
|
5 |
+
* @package WooCommerce\PayPalCommerce\Webhooks\Handler
|
6 |
+
*/
|
7 |
+
|
8 |
+
declare(strict_types=1);
|
9 |
+
|
10 |
+
namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
|
11 |
+
|
12 |
+
use Psr\Log\LoggerInterface;
|
13 |
+
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
14 |
+
use WP_REST_Request;
|
15 |
+
use WP_REST_Response;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Class VaultPaymentTokenCreated
|
19 |
+
*/
|
20 |
+
class VaultPaymentTokenCreated implements RequestHandler {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* The logger.
|
24 |
+
*
|
25 |
+
* @var LoggerInterface
|
26 |
+
*/
|
27 |
+
protected $logger;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* The prefix.
|
31 |
+
*
|
32 |
+
* @var string
|
33 |
+
*/
|
34 |
+
protected $prefix;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* The authorized payment processor.
|
38 |
+
*
|
39 |
+
* @var AuthorizedPaymentsProcessor
|
40 |
+
*/
|
41 |
+
protected $authorized_payments_processor;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* VaultPaymentTokenCreated constructor.
|
45 |
+
*
|
46 |
+
* @param LoggerInterface $logger The logger.
|
47 |
+
* @param string $prefix The prefix.
|
48 |
+
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The authorized payment processor.
|
49 |
+
*/
|
50 |
+
public function __construct( LoggerInterface $logger, string $prefix, AuthorizedPaymentsProcessor $authorized_payments_processor ) {
|
51 |
+
$this->logger = $logger;
|
52 |
+
$this->prefix = $prefix;
|
53 |
+
$this->authorized_payments_processor = $authorized_payments_processor;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* The event types a handler handles.
|
58 |
+
*
|
59 |
+
* @return string[]
|
60 |
+
*/
|
61 |
+
public function event_types(): array {
|
62 |
+
return array(
|
63 |
+
'VAULT.PAYMENT-TOKEN.CREATED',
|
64 |
+
);
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Whether a handler is responsible for a given request or not.
|
69 |
+
*
|
70 |
+
* @param WP_REST_Request $request The request.
|
71 |
+
*
|
72 |
+
* @return bool
|
73 |
+
*/
|
74 |
+
public function responsible_for_request( WP_REST_Request $request ): bool {
|
75 |
+
return in_array( $request['event_type'], $this->event_types(), true );
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Responsible for handling the request.
|
80 |
+
*
|
81 |
+
* @param WP_REST_Request $request The request.
|
82 |
+
*
|
83 |
+
* @return WP_REST_Response
|
84 |
+
*/
|
85 |
+
public function handle_request( WP_REST_Request $request ): WP_REST_Response {
|
86 |
+
$response = array( 'success' => false );
|
87 |
+
|
88 |
+
$customer_id = null !== $request['resource'] && isset( $request['resource']['customer_id'] )
|
89 |
+
? $request['resource']['customer_id']
|
90 |
+
: '';
|
91 |
+
if ( ! $customer_id ) {
|
92 |
+
$message = 'No customer id was found.';
|
93 |
+
$this->logger->warning( $message, array( 'request' => $request ) );
|
94 |
+
$response['message'] = $message;
|
95 |
+
return new WP_REST_Response( $response );
|
96 |
+
}
|
97 |
+
|
98 |
+
$wc_customer_id = (int) str_replace( $this->prefix, '', $customer_id );
|
99 |
+
$this->authorized_payments_processor->capture_authorized_payments_for_customer( $wc_customer_id );
|
100 |
+
|
101 |
+
$response['success'] = true;
|
102 |
+
return new WP_REST_Response( $response );
|
103 |
+
}
|
104 |
+
}
|
modules/ppcp-webhooks/src/Status/Assets/WebhooksStatusPageAssets.php
CHANGED
@@ -83,20 +83,20 @@ class WebhooksStatusPageAssets {
|
|
83 |
public function get_script_data() {
|
84 |
return array(
|
85 |
'resubscribe' => array(
|
86 |
-
'endpoint' =>
|
87 |
'nonce' => wp_create_nonce( ResubscribeEndpoint::nonce() ),
|
88 |
'button' => '.ppcp-webhooks-resubscribe',
|
89 |
'failureMessage' => __( 'Operation failed. Check WooCommerce logs for more details.', 'woocommerce-paypal-payments' ),
|
90 |
),
|
91 |
'simulation' => array(
|
92 |
'start' => array(
|
93 |
-
'endpoint' =>
|
94 |
'nonce' => wp_create_nonce( SimulateEndpoint::nonce() ),
|
95 |
'button' => '.ppcp-webhooks-simulate',
|
96 |
'failureMessage' => __( 'Operation failed. Check WooCommerce logs for more details.', 'woocommerce-paypal-payments' ),
|
97 |
),
|
98 |
'state' => array(
|
99 |
-
'endpoint' =>
|
100 |
'successState' => WebhookSimulation::STATE_RECEIVED,
|
101 |
'waitingMessage' => __( 'Waiting for the webhook to arrive...', 'woocommerce-paypal-payments' ),
|
102 |
'successMessage' => __( 'The webhook was received successfully.', 'woocommerce-paypal-payments' ),
|
83 |
public function get_script_data() {
|
84 |
return array(
|
85 |
'resubscribe' => array(
|
86 |
+
'endpoint' => \WC_AJAX::get_endpoint( ResubscribeEndpoint::ENDPOINT ),
|
87 |
'nonce' => wp_create_nonce( ResubscribeEndpoint::nonce() ),
|
88 |
'button' => '.ppcp-webhooks-resubscribe',
|
89 |
'failureMessage' => __( 'Operation failed. Check WooCommerce logs for more details.', 'woocommerce-paypal-payments' ),
|
90 |
),
|
91 |
'simulation' => array(
|
92 |
'start' => array(
|
93 |
+
'endpoint' => \WC_AJAX::get_endpoint( SimulateEndpoint::ENDPOINT ),
|
94 |
'nonce' => wp_create_nonce( SimulateEndpoint::nonce() ),
|
95 |
'button' => '.ppcp-webhooks-simulate',
|
96 |
'failureMessage' => __( 'Operation failed. Check WooCommerce logs for more details.', 'woocommerce-paypal-payments' ),
|
97 |
),
|
98 |
'state' => array(
|
99 |
+
'endpoint' => \WC_AJAX::get_endpoint( SimulationStateEndpoint::ENDPOINT ),
|
100 |
'successState' => WebhookSimulation::STATE_RECEIVED,
|
101 |
'waitingMessage' => __( 'Waiting for the webhook to arrive...', 'woocommerce-paypal-payments' ),
|
102 |
'successMessage' => __( 'The webhook was received successfully.', 'woocommerce-paypal-payments' ),
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: woocommerce, paypal, payments, ecommerce, e-commerce, store, sales, sell,
|
|
4 |
Requires at least: 5.3
|
5 |
Tested up to: 5.9
|
6 |
Requires PHP: 7.1
|
7 |
-
Stable tag: 1.7.
|
8 |
License: GPLv2
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -81,6 +81,19 @@ Follow the steps below to connect the plugin to your PayPal account:
|
|
81 |
|
82 |
== Changelog ==
|
83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
= 1.7.0 =
|
85 |
* Fix - DCC orders randomly failing #503
|
86 |
* Fix - Multi-currency broke #481
|
4 |
Requires at least: 5.3
|
5 |
Tested up to: 5.9
|
6 |
Requires PHP: 7.1
|
7 |
+
Stable tag: 1.7.1
|
8 |
License: GPLv2
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
81 |
|
82 |
== Changelog ==
|
83 |
|
84 |
+
= 1.7.1 =
|
85 |
+
* Fix - Hide smart buttons for free products and zero-sum carts #499
|
86 |
+
* Fix - Unprocessable Entity when paying with AMEX card #516
|
87 |
+
* Fix - Multisite path doubled in ajax URLs #528
|
88 |
+
* Fix - "Place order" button looking unstyled in the Twenty Twenty-Two theme #478
|
89 |
+
* Fix - PayPal options available on minicart when adding subscription to the cart from shop page without vaulting enabled #518
|
90 |
+
* Fix - Buttons not visible on products page #551
|
91 |
+
* Fix - Buttons not visible in mini-cart #553
|
92 |
+
* Fix - PayPal button missing on pay for order page #555
|
93 |
+
* Enhancement - PayPal buttons loading time #533
|
94 |
+
* Enhancement - Improve payment token checking for subscriptions #525
|
95 |
+
* Enhancement - Add Spain and Italy to messaging #497
|
96 |
+
|
97 |
= 1.7.0 =
|
98 |
* Fix - DCC orders randomly failing #503
|
99 |
* Fix - Multi-currency broke #481
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInitd9d5a07d2a80f7ccbdaae9d6cdd2640f::getLoader();
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -22,15 +22,15 @@ class ComposerAutoloaderInit67b44fe7c35a8c302b78e218a0018012
|
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
-
spl_autoload_register(array('
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
-
spl_autoload_unregister(array('
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
-
call_user_func(\Composer\Autoload\
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
@@ -51,19 +51,19 @@ class ComposerAutoloaderInit67b44fe7c35a8c302b78e218a0018012
|
|
51 |
$loader->register(true);
|
52 |
|
53 |
if ($useStaticLoader) {
|
54 |
-
$includeFiles = Composer\Autoload\
|
55 |
} else {
|
56 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
57 |
}
|
58 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
59 |
-
|
60 |
}
|
61 |
|
62 |
return $loader;
|
63 |
}
|
64 |
}
|
65 |
|
66 |
-
function
|
67 |
{
|
68 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
69 |
require $file;
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInitd9d5a07d2a80f7ccbdaae9d6cdd2640f
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
+
spl_autoload_register(array('ComposerAutoloaderInitd9d5a07d2a80f7ccbdaae9d6cdd2640f', 'loadClassLoader'), true, true);
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
+
spl_autoload_unregister(array('ComposerAutoloaderInitd9d5a07d2a80f7ccbdaae9d6cdd2640f', 'loadClassLoader'));
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
+
call_user_func(\Composer\Autoload\ComposerStaticInitd9d5a07d2a80f7ccbdaae9d6cdd2640f::getInitializer($loader));
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
51 |
$loader->register(true);
|
52 |
|
53 |
if ($useStaticLoader) {
|
54 |
+
$includeFiles = Composer\Autoload\ComposerStaticInitd9d5a07d2a80f7ccbdaae9d6cdd2640f::$files;
|
55 |
} else {
|
56 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
57 |
}
|
58 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
59 |
+
composerRequired9d5a07d2a80f7ccbdaae9d6cdd2640f($fileIdentifier, $file);
|
60 |
}
|
61 |
|
62 |
return $loader;
|
63 |
}
|
64 |
}
|
65 |
|
66 |
+
function composerRequired9d5a07d2a80f7ccbdaae9d6cdd2640f($fileIdentifier, $file)
|
67 |
{
|
68 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
69 |
require $file;
|
vendor/composer/autoload_static.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
@@ -172,9 +172,9 @@ class ComposerStaticInit67b44fe7c35a8c302b78e218a0018012
|
|
172 |
public static function getInitializer(ClassLoader $loader)
|
173 |
{
|
174 |
return \Closure::bind(function () use ($loader) {
|
175 |
-
$loader->prefixLengthsPsr4 =
|
176 |
-
$loader->prefixDirsPsr4 =
|
177 |
-
$loader->classMap =
|
178 |
|
179 |
}, null, ClassLoader::class);
|
180 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInitd9d5a07d2a80f7ccbdaae9d6cdd2640f
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
172 |
public static function getInitializer(ClassLoader $loader)
|
173 |
{
|
174 |
return \Closure::bind(function () use ($loader) {
|
175 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInitd9d5a07d2a80f7ccbdaae9d6cdd2640f::$prefixLengthsPsr4;
|
176 |
+
$loader->prefixDirsPsr4 = ComposerStaticInitd9d5a07d2a80f7ccbdaae9d6cdd2640f::$prefixDirsPsr4;
|
177 |
+
$loader->classMap = ComposerStaticInitd9d5a07d2a80f7ccbdaae9d6cdd2640f::$classMap;
|
178 |
|
179 |
}, null, ClassLoader::class);
|
180 |
}
|
woocommerce-paypal-payments.php
CHANGED
@@ -3,13 +3,13 @@
|
|
3 |
* Plugin Name: WooCommerce PayPal Payments
|
4 |
* Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
|
5 |
* Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
|
6 |
-
* Version: 1.7.
|
7 |
* Author: WooCommerce
|
8 |
* Author URI: https://woocommerce.com/
|
9 |
* License: GPL-2.0
|
10 |
* Requires PHP: 7.1
|
11 |
* WC requires at least: 3.9
|
12 |
-
* WC tested up to: 6.
|
13 |
* Text Domain: woocommerce-paypal-payments
|
14 |
*
|
15 |
* @package WooCommerce\PayPalCommerce
|
3 |
* Plugin Name: WooCommerce PayPal Payments
|
4 |
* Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
|
5 |
* Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
|
6 |
+
* Version: 1.7.1
|
7 |
* Author: WooCommerce
|
8 |
* Author URI: https://woocommerce.com/
|
9 |
* License: GPL-2.0
|
10 |
* Requires PHP: 7.1
|
11 |
* WC requires at least: 3.9
|
12 |
+
* WC tested up to: 6.3
|
13 |
* Text Domain: woocommerce-paypal-payments
|
14 |
*
|
15 |
* @package WooCommerce\PayPalCommerce
|