From 140b75f1112acee9af325257386eeba721417d1b Mon Sep 17 00:00:00 2001 From: Phillip Shiu Date: Tue, 1 Nov 2022 17:06:29 +0300 Subject: [PATCH 1/2] feat: add initial support for stripe payment intents (#3847) * temp: add project-zebra to branches that should run ci (#3824) * fix: initial implementation of stripe fixes (#3817) Co-authored-by: John Nagro * feat: Add waffle flag to enable Stripe payments (#3816) REV-3004 * feat: initial implementation of Stripe processor (#3826) Co-authored-by: wdrussell2015 <43426024+wdrussell2015@users.noreply.github.com> Co-authored-by: John Nagro * fix: billing address creation * fix: retreive calls cannot take idempotency keys * temp: add logging * temp: add more logging * temp: add logging * fix: parsing address from payment intent * chore: cleanup logs * fix: Get billing address line2 default empty (#3833) * fix: Stripe billing address line2 default to empty if null (#3835) REV-3069 * feat: add SDN check (#3834) * feat: add SDN check * feat: use confirm call to complete transaction with stripe in ecommerce checkout endpoint * fix: make capture-context more resilient to idempotency errors (#3836) * fix: make capture-context more resilient to idempotency errors * fix: add new card types for stripe * feat: /management fulfill actions for Stripe FulfillFrozenBaskets is a helper class for a management page in Ecommerce (hosted at URL /management) that fulfills baskets that are paid but stuck in queue for fulfillment, to be used if, for example, ecommerce-worker is down. Add Stripe support for FulfillFrozenBaskets. Change FulfillFrozenBaskets so it does not continue fulfillment if the billing details are not retrievable. For Stripe, this handles when: * The PaymentMethod was not expanded in the PaymentIntent stored in the PaymentProcessorResponse (generating a TypeError) * The PaymentMethod was not a card (generating a KeyError). Also switched Cybersource to not fulfill if it cannot find the card brand. * fix: update PaymentIntent before confirmation * fix: stripe refunds should be of payment_intents, not charges * fix: change PaymentIntents to update_or_create Apparently, idempotency keys can expire after 24 hours. https://stripe.com/docs/api/idempotent_requests "Keys are eligible to be removed from the system automatically after they're at least 24 hours old, and a new request is generated if a key is reused after the original has been pruned." * refactor: reduce number of statements in management/utils.py for quality * fix: enable Stripe custom actions beta in settings * fix: finish passing api_version and enable_telemetry to stripe client * fix: add 'unknown' stripe card brand * fix: stripe api calls should be to payment_method and payment_intent_id * test: patch for stripePaymentIntent.modify * fix: StripeCheckoutView as a View instead of a FormView-like class StripeCheckoutView was previously like a FormView. However, our implementation of Stripe is much simpler and we opted to remove the overhead of Forms in lieu of trying to ensure all existing interfaces related to StripeSubmitForm. * fix: handle when Stripe charge is already refunded * test: correct refund_mock to use new payment_intent API * test: update Stripe mock responses for new API using actual calls * fix: log when payment_intent_id is missing from basket * refactor: move logging before retrieving any baskets * fix: clear out edx.org-specific Stripe publishable_key and secret_key * fix: throw a 500 on capture_context exceptions The Payment MFE will hang silently if capture_context fails. Throwing the exception will show an error message in Payment MFE, cluing the user in to the fact that there might be a problem. * fix: convert StripeCheckoutView to DRF for JWT auth Looks like JWT auth only works with DRF. * fix: return 200s or 400s instead of 302s in StripeCheckoutView We tried using 302s to redirect the Payment MFE to the receipt page. This didn't work because the library that we use for requests, Axios, doesn't appear to support not following redirects. Return a 200 or 400 instead, and separately instruct the frontend on what to do when receiving these. * fix: deprecate ECOMMERCE_PAYMENT_PROCESSOR_CONFIG.stripe.error_url error_path is already autoset by _oscar.py and grabbed by property processors.stripe.Stripe.error_url. * Revert "fix: throw a 500 on capture_context exceptions" This reverts commit 100827227bfe0bf99a96763e08c8dedb9907167e. It looks like there is a chance that we might depend on this behavior (no errors on exceptions in _add_capture_context) given how this error occurs with non-negligible frequency in production. Will attempt to warn user on frontend side. * add self.record_processor_response to more stripe code paths (#3852) * feat: REV-3076 | record payment processor for various stripe logical flows * chore: update tests for sanity checks * fix: address comments * fix: use ISO 3166-1 alpha-2 country code for SDN check (#3854) * fix: add waffle flag ENABLE_STRIPE_PAYMENT_PROCESSOR to get_client_side_payment_processor_class() The client-side payment processor decides which payment processor Ecommerce will use when generating the capture context for a payment. Force the client-side payment processor to be 'stripe' when the waffle flag is on. * fix: make postcode & state optional for stripe Cybersource has an optional line2, postcode, and state: https://github.com/openedx/ecommerce/blob/05404ebac527da1f6a0fac7df262ca79f3acec56/ecommerce/extensions/payment/views/cybersource.py#L544-L547 Do the same for Stripe. Co-authored-by: Chris Pappas Co-authored-by: John Nagro Co-authored-by: Juliana Kang Co-authored-by: wdrussell2015 <43426024+wdrussell2015@users.noreply.github.com> Co-authored-by: Chris Pappas --- .github/workflows/ci.yml | 4 +- ecommerce/core/models.py | 12 +- ecommerce/core/tests/test_models.py | 18 +- ecommerce/extensions/api/v2/constants.py | 4 +- ecommerce/extensions/basket/constants.py | 10 + .../extensions/basket/tests/test_views.py | 16 +- ecommerce/extensions/basket/utils.py | 43 +- ecommerce/extensions/basket/views.py | 15 +- ecommerce/extensions/payment/constants.py | 24 +- .../migrations/0032_alter_source_card_type.py | 18 + .../extensions/payment/processors/__init__.py | 3 + .../payment/processors/cybersource.py | 3 +- .../extensions/payment/processors/stripe.py | 197 ++++++--- .../payment/tests/processors/test_stripe.py | 183 ++++----- .../test_stripe_test_payment_flow.json | 384 ++++++++++++++++++ .../payment/tests/views/test_stripe.py | 372 +++++++++++------ ecommerce/extensions/payment/urls.py | 1 + .../extensions/payment/views/apple_pay.py | 2 +- ecommerce/extensions/payment/views/stripe.py | 191 ++++++++- ecommerce/management/utils.py | 33 +- ecommerce/settings/_oscar.py | 10 +- ecommerce/settings/base.py | 12 +- ecommerce/settings/devstack.py | 14 +- ecommerce/settings/local.py | 11 +- ecommerce/settings/test.py | 24 +- requirements/base.in | 2 +- requirements/base.txt | 49 ++- requirements/common_constraints.txt | 2 + requirements/dev.txt | 55 ++- requirements/docs.txt | 8 +- requirements/e2e.txt | 20 +- requirements/production.txt | 49 ++- requirements/test.txt | 53 ++- 33 files changed, 1383 insertions(+), 459 deletions(-) create mode 100644 ecommerce/extensions/payment/migrations/0032_alter_source_card_type.py create mode 100644 ecommerce/extensions/payment/tests/views/fixtures/test_stripe_test_payment_flow.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbe9592de38..113bafc2ca5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [master] + branches: [master, project-zebra] pull_request: - branches: [master] + branches: [master, project-zebra] jobs: build: diff --git a/ecommerce/core/models.py b/ecommerce/core/models.py index 4b1cdff6761..8ef35bdd510 100644 --- a/ecommerce/core/models.py +++ b/ecommerce/core/models.py @@ -21,6 +21,7 @@ from ecommerce.core.constants import ALL_ACCESS_CONTEXT, ALLOW_MISSING_LMS_USER_ID from ecommerce.core.exceptions import MissingLmsUserIdException from ecommerce.core.utils import log_message_and_raise_validation_error +from ecommerce.extensions.basket.constants import ENABLE_STRIPE_PAYMENT_PROCESSOR from ecommerce.extensions.payment.exceptions import ProcessorNotFoundError from ecommerce.extensions.payment.helpers import get_processor_class, get_processor_class_by_name @@ -274,7 +275,7 @@ def get_payment_processors(self): if processor.NAME in self.payment_processors_set and processor.is_enabled() ] - def get_client_side_payment_processor_class(self): + def get_client_side_payment_processor_class(self, request): """ Returns the payment processor class to be used for client-side payments. If no processor is set, returns None. @@ -282,9 +283,16 @@ def get_client_side_payment_processor_class(self): Returns: BasePaymentProcessor """ + desired_processor = self.client_side_payment_processor + + # Force client_side_payment_processor to be Stripe when waffle flag is set. + # This allows slowly increasing the percentage of users redirected to Stripe. + if waffle.flag_is_active(request, ENABLE_STRIPE_PAYMENT_PROCESSOR): + desired_processor = 'stripe' + if self.client_side_payment_processor: for processor in self._all_payment_processors(): - if processor.NAME == self.client_side_payment_processor: + if processor.NAME == desired_processor: return processor return None diff --git a/ecommerce/core/tests/test_models.py b/ecommerce/core/tests/test_models.py index ef07b74e9a9..4dfe176199f 100644 --- a/ecommerce/core/tests/test_models.py +++ b/ecommerce/core/tests/test_models.py @@ -13,6 +13,7 @@ from requests.exceptions import ConnectionError as ReqConnectionError from social_django.models import UserSocialAuth from testfixtures import LogCapture +from waffle.testutils import override_flag from ecommerce.core.models import ( BusinessClient, @@ -22,6 +23,7 @@ User ) from ecommerce.core.tests import toggle_switch +from ecommerce.extensions.basket.constants import ENABLE_STRIPE_PAYMENT_PROCESSOR from ecommerce.extensions.catalogue.tests.mixins import DiscoveryTestMixin from ecommerce.extensions.payment.tests.processors import AnotherDummyProcessor, DummyProcessor from ecommerce.tests.factories import SiteConfigurationFactory @@ -334,10 +336,22 @@ def test_get_client_side_payment_processor(self): site_config = _make_site_config(processor_name) site_config.client_side_payment_processor = None - self.assertIsNone(site_config.get_client_side_payment_processor_class()) + self.assertIsNone(site_config.get_client_side_payment_processor_class(request=None)) site_config.client_side_payment_processor = processor_name - self.assertEqual(site_config.get_client_side_payment_processor_class().NAME, processor_name) + self.assertEqual(site_config.get_client_side_payment_processor_class(request=None).NAME, processor_name) + + @override_flag(ENABLE_STRIPE_PAYMENT_PROCESSOR, active=True) + def test_get_client_side_payment_processor_waffle_enabled(self): + """ Verify that Stripe is always returned when waffle flag is on. """ + processor_name = 'cybersource,stripe' + site_config = _make_site_config(processor_name) + + site_config.client_side_payment_processor = None + self.assertIsNone(site_config.get_client_side_payment_processor_class(request=None)) + + site_config.client_side_payment_processor = 'cybersource' + self.assertEqual(site_config.get_client_side_payment_processor_class(request=None).NAME, 'stripe') def test_get_from_email(self): """ diff --git a/ecommerce/extensions/api/v2/constants.py b/ecommerce/extensions/api/v2/constants.py index 3b9a10eafe6..f67baf6a80b 100644 --- a/ecommerce/extensions/api/v2/constants.py +++ b/ecommerce/extensions/api/v2/constants.py @@ -9,7 +9,7 @@ # .. toggle_name: enable_hoist_order_history # .. toggle_type: waffle_flag # .. toggle_default: False -# .. toggle_description: Allows order fetching from Commerce Coordinator API for display in Order History MFE. +# .. toggle_description: Allows order fetching from Commerce Coordinator API for display in Order History MFE # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2022-04-05 # .. toggle_tickets: REV-2576 @@ -19,7 +19,7 @@ # .. toggle_name: enable_receipts_via_ecommerce_mfe # .. toggle_type: waffle_flag # .. toggle_default: False -# .. toggle_description: Determines whether to send user to new receipt page (vs old) . +# .. toggle_description: Determines whether to send user to new receipt page (vs old) # .. toggle_use_cases: open_edx # .. toggle_creation_date: 2022-06-02 # .. toggle_tickets: REV-2687 diff --git a/ecommerce/extensions/basket/constants.py b/ecommerce/extensions/basket/constants.py index 24a068fd44b..bfd7ae1bd94 100644 --- a/ecommerce/extensions/basket/constants.py +++ b/ecommerce/extensions/basket/constants.py @@ -2,3 +2,13 @@ EMAIL_OPT_IN_ATTRIBUTE = "email_opt_in" PURCHASER_BEHALF_ATTRIBUTE = "purchased_for_organization" PAYMENT_INTENT_ID_ATTRIBUTE = "payment_intent_id" + +# .. toggle_name: enable_stripe_payment_processor +# .. toggle_type: waffle_flag +# .. toggle_default: False +# .. toggle_description: Allows payments to be processed through Stripe instead of CyberSource +# .. toggle_use_cases: open_edx +# .. toggle_creation_date: 2022-09-19 +# .. toggle_tickets: REV-3004 +# .. toggle_status: supported +ENABLE_STRIPE_PAYMENT_PROCESSOR = 'enable_stripe_payment_processor' diff --git a/ecommerce/extensions/basket/tests/test_views.py b/ecommerce/extensions/basket/tests/test_views.py index 473af08447b..cbf6c237982 100644 --- a/ecommerce/extensions/basket/tests/test_views.py +++ b/ecommerce/extensions/basket/tests/test_views.py @@ -33,7 +33,7 @@ from ecommerce.enterprise.utils import construct_enterprise_course_consent_url from ecommerce.entitlements.utils import create_or_update_course_entitlement from ecommerce.extensions.analytics.utils import translate_basket_line_for_segment -from ecommerce.extensions.basket.constants import EMAIL_OPT_IN_ATTRIBUTE +from ecommerce.extensions.basket.constants import EMAIL_OPT_IN_ATTRIBUTE, ENABLE_STRIPE_PAYMENT_PROCESSOR from ecommerce.extensions.basket.tests.mixins import BasketMixin from ecommerce.extensions.basket.tests.test_utils import TEST_BUNDLE_ID from ecommerce.extensions.basket.utils import _set_basket_bundle_status, apply_voucher_on_basket_and_check_discount @@ -403,6 +403,7 @@ def assert_empty_basket_response( def assert_expected_response( self, basket, + enable_stripe_payment_processor=False, url=None, response=None, status_code=200, @@ -456,6 +457,7 @@ def assert_expected_response( expected_response = { 'basket_id': basket.id, 'currency': currency, + 'enable_stripe_payment_processor': enable_stripe_payment_processor, 'offers': offers, 'coupons': coupons, 'messages': messages if messages else [], @@ -698,6 +700,18 @@ def test_discounted_seat_type(self, discount_value): voucher=voucher, ) + @ddt.data(True, False) + def test_enable_stripe_payment_processor_flag(self, enable_stripe_payment_processor): + with override_flag(ENABLE_STRIPE_PAYMENT_PROCESSOR, active=enable_stripe_payment_processor): + seat = self.create_seat(self.course) + basket = self.create_basket_and_add_product(seat) + response = self.client.get(self.path) + self.assert_expected_response( + basket, + response=response, + enable_stripe_payment_processor=enable_stripe_payment_processor, + ) + @responses.activate def test_enterprise_free_basket_redirect(self): """ diff --git a/ecommerce/extensions/basket/utils.py b/ecommerce/extensions/basket/utils.py index 7dedbcd825d..67a6a408cda 100644 --- a/ecommerce/extensions/basket/utils.py +++ b/ecommerce/extensions/basket/utils.py @@ -18,7 +18,7 @@ from ecommerce.core.url_utils import absolute_url from ecommerce.courses.utils import mode_for_product from ecommerce.extensions.analytics.utils import track_segment_event -from ecommerce.extensions.basket.constants import PURCHASER_BEHALF_ATTRIBUTE +from ecommerce.extensions.basket.constants import PAYMENT_INTENT_ID_ATTRIBUTE, PURCHASER_BEHALF_ATTRIBUTE from ecommerce.extensions.order.exceptions import AlreadyPlacedOrderException from ecommerce.extensions.order.utils import UserAlreadyPlacedOrder from ecommerce.extensions.payment.constants import DISABLE_MICROFRONTEND_FOR_BASKET_PAGE_FLAG_NAME @@ -30,6 +30,8 @@ Basket = get_model('basket', 'Basket') BasketAttribute = get_model('basket', 'BasketAttribute') BasketAttributeType = get_model('basket', 'BasketAttributeType') +BillingAddress = get_model('order', 'BillingAddress') +Country = get_model('address', 'Country') BUNDLE = 'bundle_identifier' ORGANIZATION_ATTRIBUTE_TYPE = 'organization' ENTERPRISE_CATALOG_ATTRIBUTE_TYPE = 'enterprise_catalog_uuid' @@ -384,6 +386,25 @@ def basket_add_organization_attribute(basket, request_data): ) +@newrelic.agent.function_trace() +def basket_add_payment_intent_id_attribute(basket, payment_intent_id): + """ + Adds the Stripe payment_intent_id attribute on basket. + + Arguments: + basket(Basket): order basket + payment_intent_id (string): Payment Intent Identifier + + """ + + payment_intent_id_attribute, __ = BasketAttributeType.objects.get_or_create(name=PAYMENT_INTENT_ID_ATTRIBUTE) + BasketAttribute.objects.update_or_create( + basket=basket, + attribute_type=payment_intent_id_attribute, + defaults={'value_text': payment_intent_id.strip()} + ) + + @newrelic.agent.function_trace() def basket_add_enterprise_catalog_attribute(basket, request_data): """ @@ -569,3 +590,23 @@ def is_duplicate_seat_attempt(basket, product): found_product_quantity = basket.product_quantity(product) return bool(product_type == 'Seat' and found_product_quantity) + + +def get_billing_address_from_payment_intent_data(payment_intent): + """ + Take stripes response_data dict, instantiates a BillingAddress object + and return it. + """ + billing_details = payment_intent['payment_method']['billing_details'] + customer_address = billing_details['address'] + address = BillingAddress( + first_name=billing_details['name'], # Stripe only has a single name field + last_name='', + line1=customer_address['line1'], + line2='' if not customer_address['line2'] else customer_address['line2'], # line2 is optional + line4=customer_address['city'], # Oscar uses line4 for city + postcode='' if not customer_address['postal_code'] else customer_address['postal_code'], # postcode is optional + state='' if not customer_address['state'] else customer_address['state'], # state is optional + country=Country.objects.get(iso_3166_1_a2__iexact=customer_address['country']) + ) + return address diff --git a/ecommerce/extensions/basket/views.py b/ecommerce/extensions/basket/views.py index 1e568d7f868..33726fc8c73 100644 --- a/ecommerce/extensions/basket/views.py +++ b/ecommerce/extensions/basket/views.py @@ -47,7 +47,7 @@ translate_basket_line_for_segment ) from ecommerce.extensions.basket import message_utils -from ecommerce.extensions.basket.constants import EMAIL_OPT_IN_ATTRIBUTE +from ecommerce.extensions.basket.constants import EMAIL_OPT_IN_ATTRIBUTE, ENABLE_STRIPE_PAYMENT_PROCESSOR from ecommerce.extensions.basket.exceptions import BadRequestException, RedirectException, VoucherException from ecommerce.extensions.basket.utils import ( add_invalid_code_message_to_url, @@ -583,7 +583,7 @@ def _get_payment_processors_data(self, payment_processors): basket view context needs to be updated with. """ site_configuration = self.request.site.siteconfiguration - payment_processor_class = site_configuration.get_client_side_payment_processor_class() + payment_processor_class = site_configuration.get_client_side_payment_processor_class(self.request) if payment_processor_class: payment_processor = payment_processor_class(self.request.site) @@ -615,7 +615,8 @@ class CaptureContextApiLogicMixin: # pragma: no cover Business logic for the capture context API. """ def _add_capture_context(self, response): - payment_processor_class = self.request.site.siteconfiguration.get_client_side_payment_processor_class() + site_configuration = self.request.site.siteconfiguration + payment_processor_class = site_configuration.get_client_side_payment_processor_class(self.request) if not payment_processor_class: return payment_processor = payment_processor_class(self.request.site) @@ -623,7 +624,7 @@ def _add_capture_context(self, response): return try: - response['capture_context'] = payment_processor.get_capture_context(self.request.session) + response['capture_context'] = payment_processor.get_capture_context(self.request) except: # pylint: disable=bare-except logger.exception("Error generating capture_context") return @@ -681,6 +682,7 @@ def _serialize_context(self, context, lines_data): self._add_total_summary(response, context) self._add_offers(response) self._add_coupons(response, context) + self._add_enable_stripe_payment_processor(response) return response def _add_products(self, response, lines_data): @@ -738,6 +740,11 @@ def _add_coupons(self, response, context): def _add_messages(self, response): response['messages'] = message_utils.serialize(self.request) + def _add_enable_stripe_payment_processor(self, response): + response['enable_stripe_payment_processor'] = waffle.flag_is_active( + self.request, ENABLE_STRIPE_PAYMENT_PROCESSOR + ) + def _get_response_status(self, response): return message_utils.get_response_status(response['messages']) diff --git a/ecommerce/extensions/payment/constants.py b/ecommerce/extensions/payment/constants.py index a393e85ab84..ecc25c488ab 100644 --- a/ecommerce/extensions/payment/constants.py +++ b/ecommerce/extensions/payment/constants.py @@ -8,25 +8,41 @@ 'display_name': _('American Express'), 'cybersource_code': '003', 'apple_pay_network': 'amex', - 'stripe_brand': 'American Express', + 'stripe_brand': 'amex', + }, + 'diners': { + 'display_name': _('Diners'), + 'stripe_brand': 'diners', }, 'discover': { 'display_name': _('Discover'), 'cybersource_code': '004', 'apple_pay_network': 'discover', - 'stripe_brand': 'Discover', + 'stripe_brand': 'discover', + }, + 'jcb': { + 'display_name': _('JCB'), + 'stripe_brand': 'jcb', }, 'mastercard': { 'display_name': _('MasterCard'), 'cybersource_code': '002', 'apple_pay_network': 'mastercard', - 'stripe_brand': 'MasterCard', + 'stripe_brand': 'mastercard', + }, + 'unionpay': { + 'display_name': _('UnionPay'), + 'stripe_brand': 'unionpay', + }, + 'unknown': { + 'display_name': _('Unknown'), + 'stripe_brand': 'unknown', }, 'visa': { 'display_name': _('Visa'), 'cybersource_code': '001', 'apple_pay_network': 'visa', - 'stripe_brand': 'Visa', + 'stripe_brand': 'visa', }, } diff --git a/ecommerce/extensions/payment/migrations/0032_alter_source_card_type.py b/ecommerce/extensions/payment/migrations/0032_alter_source_card_type.py new file mode 100644 index 00000000000..4572746919e --- /dev/null +++ b/ecommerce/extensions/payment/migrations/0032_alter_source_card_type.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.15 on 2022-10-11 16:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('payment', '0031_sdnfallbackdata'), + ] + + operations = [ + migrations.AlterField( + model_name='source', + name='card_type', + field=models.CharField(blank=True, choices=[('american_express', 'American Express'), ('diners', 'Diners'), ('discover', 'Discover'), ('jcb', 'JCB'), ('mastercard', 'MasterCard'), ('unionpay', 'UnionPay'), ('unknown', 'Unknown'), ('visa', 'Visa')], max_length=255, null=True), + ), + ] diff --git a/ecommerce/extensions/payment/processors/__init__.py b/ecommerce/extensions/payment/processors/__init__.py index 6a1df9d20d9..31caf91b540 100644 --- a/ecommerce/extensions/payment/processors/__init__.py +++ b/ecommerce/extensions/payment/processors/__init__.py @@ -1,6 +1,7 @@ import abc +import logging from collections import namedtuple import waffle @@ -13,6 +14,8 @@ HandledProcessorResponse = namedtuple('HandledProcessorResponse', ['transaction_id', 'total', 'currency', 'card_number', 'card_type']) +logger = logging.getLogger(__name__) + class BasePaymentProcessor(metaclass=abc.ABCMeta): # pragma: no cover """Base payment processor class.""" diff --git a/ecommerce/extensions/payment/processors/cybersource.py b/ecommerce/extensions/payment/processors/cybersource.py index 3b9556c51e3..529e47a5d22 100644 --- a/ecommerce/extensions/payment/processors/cybersource.py +++ b/ecommerce/extensions/payment/processors/cybersource.py @@ -177,8 +177,9 @@ def __init__(self, site): def client_side_payment_url(self): return None - def get_capture_context(self, session): # pragma: no cover + def get_capture_context(self, request): # pragma: no cover # To delete None values in Input Request Json body + session = request.session requestObj = GeneratePublicKeyRequest( encryption_type='RsaOaep256', diff --git a/ecommerce/extensions/payment/processors/stripe.py b/ecommerce/extensions/payment/processors/stripe.py index cc7fe769286..ccd3bde2c22 100644 --- a/ecommerce/extensions/payment/processors/stripe.py +++ b/ecommerce/extensions/payment/processors/stripe.py @@ -4,9 +4,16 @@ import logging import stripe -from oscar.apps.payment.exceptions import GatewayError, TransactionDeclined +from oscar.apps.payment.exceptions import GatewayError from oscar.core.loading import get_model +from ecommerce.core.url_utils import get_ecommerce_url +from ecommerce.extensions.basket.constants import PAYMENT_INTENT_ID_ATTRIBUTE +from ecommerce.extensions.basket.models import Basket +from ecommerce.extensions.basket.utils import ( + basket_add_payment_intent_id_attribute, + get_billing_address_from_payment_intent_data +) from ecommerce.extensions.payment.constants import STRIPE_CARD_TYPE_MAP from ecommerce.extensions.payment.processors import ( ApplePayMixin, @@ -16,6 +23,8 @@ logger = logging.getLogger(__name__) +BasketAttribute = get_model('basket', 'BasketAttribute') +BasketAttributeType = get_model('basket', 'BasketAttributeType') BillingAddress = get_model('order', 'BillingAddress') Country = get_model('address', 'Country') PaymentEvent = get_model('order', 'PaymentEvent') @@ -38,57 +47,136 @@ def __init__(self, site): """ super(Stripe, self).__init__(site) configuration = self.configuration + + # Stripe API version to use. Will use latest allowed in Stripe Dashboard if None. + self.api_version = configuration['api_version'] + # Send anonymous latency metrics to Stripe. + self.enable_telemetry = configuration['enable_telemetry'] + # Stripe client logging level. None will default to INFO. + self.log_level = configuration['log_level'] + # How many times to automatically retry requests. None means no retries. + self.max_network_retries = configuration['max_network_retries'] + # Send requests somewhere else instead of Stripe. May be useful for testing. + self.proxy = configuration['proxy'] + # The key visible on the frontend to identify our Stripe account. Public. self.publishable_key = configuration['publishable_key'] + # The secret API key used by the backend to communicate with Stripe. Private/secret. self.secret_key = configuration['secret_key'] - self.country = configuration['country'] stripe.api_key = self.secret_key + stripe.api_version = self.api_version + stripe.enable_telemetry = self.enable_telemetry + stripe.log = self.log_level + stripe.max_network_retries = self.max_network_retries + stripe.proxy = self.proxy - def get_transaction_parameters(self, basket, request=None, use_client_side_checkout=True, **kwargs): - raise NotImplementedError('The Stripe payment processor does not support transaction parameters.') + @property + def cancel_url(self): + return get_ecommerce_url(self.configuration['cancel_checkout_path']) + + @property + def error_url(self): + return get_ecommerce_url(self.configuration['error_path']) def _get_basket_amount(self, basket): + """Convert to stripe amount, which is in cents.""" return str((basket.total_incl_tax * 100).to_integral_value()) - def handle_processor_response(self, response, basket=None): - token = response + def _build_payment_intent_parameters(self, basket): order_number = basket.order_number + amount = self._get_basket_amount(basket) currency = basket.currency + return { + 'amount': amount, + 'currency': currency, + 'description': order_number, + 'metadata': {'order_number': order_number}, + } + + def generate_basket_pi_idempotency_key(self, basket): + """ + Generate an idempotency key for creating a PaymentIntent for a Basket. + Using a version number in they key to aid in future development. + """ + return f'basket_pi_create_v1_{basket.order_number}' - # NOTE: In the future we may want to get/create a Customer. See https://stripe.com/docs/api#customers. + def get_capture_context(self, request): + # TODO: consider whether the basket should be passed in from MFE, not retrieved from Oscar + basket = Basket.get_basket(request.user, request.site) try: - charge = stripe.Charge.create( - amount=self._get_basket_amount(basket), - currency=currency, - source=token, - description=order_number, - metadata={'order_number': order_number} + stripe_response = stripe.PaymentIntent.create( + **self._build_payment_intent_parameters(basket), + # This means this payment intent can only be confirmed with secret key (as in, from ecommerce) + secret_key_confirmation='required', + # don't create a new intent for the same basket + idempotency_key=self.generate_basket_pi_idempotency_key(basket), + ) + # id is the payment_intent_id from Stripe + transaction_id = stripe_response['id'] + basket_add_payment_intent_id_attribute(basket, transaction_id) + # for when basket was already created, but with different amount + except stripe.error.IdempotencyError: + # if this PI has been created before, we should be able to retrieve + # it from Stripe using the payment_intent_id BasketAttribute. + # Note that we update the PI's price in handle_processor_response + # before hitting the confirm endpoint, so we don't need to do that here + payment_intent_id_attribute = BasketAttributeType.objects.get(name=PAYMENT_INTENT_ID_ATTRIBUTE) + payment_intent_attr = BasketAttribute.objects.get( + basket=basket, + attribute_type=payment_intent_id_attribute ) - transaction_id = charge.id - - # NOTE: Charge objects subclass the dict class so there is no need to do any data transformation - # before storing the response in the database. - self.record_processor_response(charge, transaction_id=transaction_id, basket=basket) - logger.info('Successfully created Stripe charge [%s] for basket [%d].', transaction_id, basket.id) - except stripe.error.CardError as ex: - base_message = "Stripe payment for basket [%d] declined with HTTP status [%d]" - exception_format_string = "{}: %s".format(base_message) - body = ex.json_body - logger.exception( - exception_format_string, - basket.id, - ex.http_status, - body + stripe_response = stripe.PaymentIntent.retrieve(id=payment_intent_attr.value_text.strip()) + + new_capture_context = { + 'key_id': stripe_response['client_secret'], + 'order_id': basket.order_number, + } + return new_capture_context + + def get_transaction_parameters(self, basket, request=None, use_client_side_checkout=True, **kwargs): + return {'payment_page_url': self.client_side_payment_url} + + def handle_processor_response(self, response, basket=None): + # pretty sure we should simply return/error if basket is None, as not + # sure what it would mean if there + payment_intent_id = response['payment_intent_id'] + # NOTE: In the future we may want to get/create a Customer. See https://stripe.com/docs/api#customers. + + # rewrite order amount so it's updated for coupon & quantity and unchanged by the user + stripe.PaymentIntent.modify( + payment_intent_id, + **self._build_payment_intent_parameters(basket), + ) + try: + confirm_api_response = stripe.PaymentIntent.confirm( + payment_intent_id, + # stop on complicated payments MFE can't handle yet + error_on_requires_action=True, + expand=['payment_method'], ) - self.record_processor_response(body, basket=basket) - raise TransactionDeclined(base_message, basket.id, ex.http_status) from ex + except stripe.error.CardError as err: + self.record_processor_response(err.json_body, transaction_id=payment_intent_id, basket=basket) + logger.exception('Card Error for basket [%d]: %s}', basket.id, err) + raise + + # proceed only if payment went through + assert confirm_api_response['status'] == "succeeded" + self.record_processor_response(confirm_api_response, transaction_id=payment_intent_id, basket=basket) + + logger.info( + 'Successfully confirmed Stripe payment intent [%s] for basket [%d].', + payment_intent_id, + basket.id + ) total = basket.total_incl_tax - card_number = charge.source.last4 - card_type = STRIPE_CARD_TYPE_MAP.get(charge.source.brand) + currency = basket.currency + card_object = confirm_api_response['charges']['data'][0]['payment_method_details']['card'] + card_number = card_object['last4'] + card_type = STRIPE_CARD_TYPE_MAP.get(card_object['brand']) return HandledProcessorResponse( - transaction_id=transaction_id, + transaction_id=payment_intent_id, total=total, currency=currency, card_number=card_number, @@ -97,7 +185,20 @@ def handle_processor_response(self, response, basket=None): def issue_credit(self, order_number, basket, reference_number, amount, currency): try: - refund = stripe.Refund.create(charge=reference_number) + refund = stripe.Refund.create(payment_intent=reference_number) + except stripe.error.InvalidRequestError as err: + if err.code == 'charge_already_refunded': + refund = stripe.Refund.list(payment_intent=reference_number, limit=1)['data'][0] + self.record_processor_response(refund, transaction_id=refund.id, basket=basket) + msg = 'Skipping issuing credit (via Stripe) for order [{}] because charge was already refunded.'.format( + order_number) + logger.warning(msg) + else: + self.record_processor_response(err.json_body, transaction_id=reference_number, basket=basket) + msg = 'An error occurred while attempting to issue a credit (via Stripe) for order [{}].'.format( + order_number) + logger.exception(msg) + raise except: msg = 'An error occurred while attempting to issue a credit (via Stripe) for order [{}].'.format( order_number) @@ -105,28 +206,24 @@ def issue_credit(self, order_number, basket, reference_number, amount, currency) raise GatewayError(msg) # pylint: disable=raise-missing-from transaction_id = refund.id - - # NOTE: Refund objects subclass dict so there is no need to do any data transformation - # before storing the response in the database. self.record_processor_response(refund, transaction_id=transaction_id, basket=basket) return transaction_id - def get_address_from_token(self, token): - """ Retrieves the billing address associated with token. + def get_address_from_token(self, payment_intent_id): + """ + Retrieves the billing address associated with a PaymentIntent. Returns: BillingAddress """ - data = stripe.Token.retrieve(token)['card'] - address = BillingAddress( - first_name=data['name'], # Stripe only has a single name field - last_name='', - line1=data['address_line1'], - line2=data.get('address_line2') or '', - line4=data['address_city'], # Oscar uses line4 for city - postcode=data.get('address_zip') or '', - state=data.get('address_state') or '', - country=Country.objects.get(iso_3166_1_a2__iexact=data['address_country']) + retrieve_kwargs = { + 'expand': ['payment_method'], + } + + payment_intent = stripe.PaymentIntent.retrieve( + payment_intent_id, + **retrieve_kwargs, ) - return address + + return get_billing_address_from_payment_intent_data(payment_intent) diff --git a/ecommerce/extensions/payment/tests/processors/test_stripe.py b/ecommerce/extensions/payment/tests/processors/test_stripe.py index 9b5e7510573..4c28cec542d 100644 --- a/ecommerce/extensions/payment/tests/processors/test_stripe.py +++ b/ecommerce/extensions/payment/tests/processors/test_stripe.py @@ -4,7 +4,7 @@ import mock import stripe -from oscar.apps.payment.exceptions import GatewayError, TransactionDeclined +from oscar.apps.payment.exceptions import GatewayError from oscar.core.loading import get_model from ecommerce.extensions.payment.processors.stripe import Stripe @@ -23,45 +23,87 @@ class StripeTests(PaymentProcessorTestCaseMixin, TestCase): processor_name = 'stripe' def test_get_transaction_parameters(self): - self.assertRaises(NotImplementedError, self.processor.get_transaction_parameters, self.basket) + transaction_params = self.processor.get_transaction_parameters(self.basket) + assert 'payment_page_url' in transaction_params.keys() + # TODO: update or remove these tests def test_handle_processor_response(self): - token = 'abc123' - charge = stripe.Charge.construct_from({ - 'id': '2404', - 'source': { - 'brand': 'American Express', - 'last4': '1986', - }, - }, 'fake-key') - - with mock.patch('stripe.Charge.create') as charge_mock: - charge_mock.return_value = charge - - actual = self.processor.handle_processor_response(token, self.basket) - - charge_mock.assert_called_once_with( - amount=str((self.basket.total_incl_tax * 100).to_integral_value()), - currency=self.basket.currency, - source=token, - description=self.basket.order_number, - metadata={'order_number': self.basket.order_number} - ) - - assert actual.transaction_id == charge.id - assert actual.total == self.basket.total_incl_tax - assert actual.currency == self.basket.currency - assert actual.card_number == charge.source.last4 - assert actual.card_type == 'american_express' - - self.assert_processor_response_recorded(self.processor_name, charge.id, charge, basket=self.basket) - - def test_handle_processor_response_error(self): - with mock.patch('stripe.Charge.create') as charge_mock: - charge_mock.side_effect = stripe.error.CardError( - 'fake-msg', 'fake-param', 'fake-code', http_body='fake-body', http_status=500 - ) - self.assertRaises(TransactionDeclined, self.processor.handle_processor_response, 'fake-token', self.basket) + assert True + # payment_intent_1 = stripe.PaymentIntent.construct_from({ + # 'id': 'pi_testtesttest', + # 'source': { + # 'brand': 'visa', + # 'last4': '4242', + # }, + # }, 'fake-key') + + # payment_intent_2 = stripe.PaymentIntent.construct_from({ + # 'id': 'pi_testtesttest', + # 'source': { + # 'brand': 'visa', + # 'last4': '4242', + # }, + # 'status': 'succeeded', + # "charges": { + # "object": "list", + # "data": [ + # { + # "id": "ch_testtesttest", + # "object": "charge", + # "status": "succeeded", + # "payment_method_details": { + # "card": { + # "brand": "visa", + # "country": "US", + # "exp_month": 5, + # "exp_year": 2020, + # "fingerprint": "Xt5EWLLDS7FJjR1c", + # "funding": "credit", + # "last4": "4242", + # "network": "visa", + # }, + # "type": "card" + # }, + # } + # ] + # } + # }, 'fake-key') + + # with mock.patch('stripe.PaymentIntent.modify') as payment_intent_modify_mock: + # with mock.patch('stripe.PaymentIntent.confirm') as payment_intent_confirm_mock: + # payment_intent_modify_mock.return_value = payment_intent_1 + # payment_intent_confirm_mock.return_value = payment_intent_2 + # actual = self.processor.handle_processor_response(payment_intent_1, self.basket) + + # assert actual.transaction_id == payment_intent_1.id + # assert actual.total == self.basket.total_incl_tax + # assert actual.currency == self.basket.currency + + # self.assert_processor_response_recorded( + # self.processor_name, + # payment_intent_2.id, + # payment_intent_2, + # basket=self.basket + # ) + + # def test_handle_processor_response_error(self): + # payment_intent_1 = stripe.PaymentIntent.construct_from({ + # 'id': 'pi_testtesttest', + # 'source': { + # 'brand': 'visa', + # 'last4': '4242', + # }, + # }, 'fake-key') + # with mock.patch('stripe.PaymentIntent.modify') as charge_mock: + # charge_mock.side_effect = stripe.error.CardError( + # 'fake-msg', 'fake-param', 'fake-code', http_body='fake-body', http_status=500 + # ) + # self.assertRaises( + # TransactionDeclined, + # self.processor.handle_processor_response, + # payment_intent_1, + # self.basket + # ) def test_issue_credit(self): charge_reference_number = '9436' @@ -74,7 +116,7 @@ def test_issue_credit(self): refund_mock.return_value = refund self.processor.issue_credit(order.number, order.basket, charge_reference_number, order.total_incl_tax, order.currency) - refund_mock.assert_called_once_with(charge=charge_reference_number) + refund_mock.assert_called_once_with(payment_intent=charge_reference_number) self.assert_processor_response_recorded(self.processor_name, refund.id, refund, basket=self.basket) @@ -87,66 +129,3 @@ def test_issue_credit_error(self): GatewayError, self.processor.issue_credit, order.number, order.basket, '123', order.total_incl_tax, order.currency ) - - def assert_addresses_equal(self, actual, expected): - for field in ('first_name', 'last_name', 'line1', 'line2', 'line3', 'line4', 'postcode', 'state', 'country'): - assert getattr(actual, field) == getattr(expected, field), 'The value of {} differs'.format(field) - - def test_get_address_from_token(self): - country, __ = Country.objects.get_or_create(iso_3166_1_a2='US') - expected = BillingAddress( - first_name='Richard White', - last_name='', - line1='1201 E. 8th Street', - line2='Suite 216', - line4='Dallas', - postcode='75203', - state='TX', - country=country - ) - token = stripe.Token.construct_from({ - 'id': 'tok_test', - 'card': { - 'address_city': 'Dallas', - 'address_country': 'US', - 'address_line1': '1201 E. 8th Street', - 'address_line2': 'Suite 216', - 'address_state': 'TX', - 'address_zip': '75203', - 'name': 'Richard White', - }, - }, 'fake-key') - - with mock.patch('stripe.Token.retrieve') as token_mock: - token_mock.return_value = token - self.assert_addresses_equal(self.processor.get_address_from_token(token.id), expected) - - def test_get_address_from_token_with_optional_fields(self): - country, __ = Country.objects.get_or_create(iso_3166_1_a2='US') - expected = BillingAddress( - first_name='Ned Green', - last_name='', - line1='3111 Bonnie View Road', - line2='', - line4='Dallas', - postcode='', - state='', - country=country - ) - token = stripe.Token.construct_from({ - 'id': 'tok_test', - 'card': { - 'address_city': 'Dallas', - 'address_country': 'US', - 'address_line1': '3111 Bonnie View Road', - 'address_line2': None, - 'address_state': None, - # NOTE: This field is intentionally excluded to simulate the API field missing. - # 'address_zip': None, - 'name': 'Ned Green', - }, - }, 'fake-key') - - with mock.patch('stripe.Token.retrieve') as token_mock: - token_mock.return_value = token - self.assert_addresses_equal(self.processor.get_address_from_token(token.id), expected) diff --git a/ecommerce/extensions/payment/tests/views/fixtures/test_stripe_test_payment_flow.json b/ecommerce/extensions/payment/tests/views/fixtures/test_stripe_test_payment_flow.json new file mode 100644 index 00000000000..a220dabf98d --- /dev/null +++ b/ecommerce/extensions/payment/tests/views/fixtures/test_stripe_test_payment_flow.json @@ -0,0 +1,384 @@ +{ + "happy_path": { + "confirm_resp": { + "id": "pi_3LsftNIadiFyUl1x2TWxaADZ", + "object": "payment_intent", + "amount": 14900, + "amount_capturable": 0, + "amount_details": { + "tip": {} + }, + "amount_received": 14900, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "automatic", + "charges": { + "object": "list", + "data": [ + { + "id": "ch_3LsftNIadiFyUl1x2Qh9P6Te", + "object": "charge", + "amount": 14900, + "amount_captured": 14900, + "amount_refunded": 0, + "application": null, + "application_fee": null, + "application_fee_amount": null, + "balance_transaction": "txn_3LsftNIadiFyUl1x2vxcOEsM", + "billing_details": { + "address": { + "city": "Sample", + "country": "US", + "line1": "123 Test St", + "line2": null, + "postal_code": "12345", + "state": "MA" + }, + "email": "pshiu-dev-test-3@example.com", + "name": "Test User", + "phone": null + }, + "calculated_statement_descriptor": "WWW.EDX.ORG", + "captured": true, + "created": 1665723259, + "currency": "usd", + "customer": null, + "description": "EDX-100011", + "destination": null, + "dispute": null, + "disputed": false, + "failure_balance_transaction": null, + "failure_code": null, + "failure_message": null, + "fraud_details": {}, + "invoice": null, + "livemode": false, + "metadata": { + "order_number": "EDX-100011" + }, + "on_behalf_of": null, + "order": null, + "outcome": { + "network_status": "approved_by_network", + "reason": null, + "risk_level": "normal", + "risk_score": 6, + "seller_message": "Payment complete.", + "type": "authorized" + }, + "paid": true, + "payment_intent": "pi_3LsftNIadiFyUl1x2TWxaADZ", + "payment_method": "pm_1LsfuTIadiFyUl1xcHa5WALi", + "payment_method_details": { + "card": { + "brand": "visa", + "checks": { + "address_line1_check": "pass", + "address_postal_code_check": "pass", + "cvc_check": "pass" + }, + "country": "US", + "exp_month": 1, + "exp_year": 2023, + "fingerprint": "N2ltqpPKT2DuO8HF", + "funding": "credit", + "installments": null, + "last4": "1111", + "mandate": null, + "network": "visa", + "three_d_secure": null, + "wallet": null + }, + "type": "card" + }, + "receipt_email": null, + "receipt_number": null, + "receipt_url": "https://pay.stripe.com/receipts/payment/CAcaFwoVYWNjdF8xTGkyS29JYWRpRnlVbDF4KPzWo5oGMgZEeRWu5K86LBbPJHPT2KSM6XjNMXK1BnCeCX2gQYlTjBilX6VYkgohptS97JXM0Ey2L7-N", + "refunded": false, + "refunds": {}, + "review": null, + "shipping": null, + "source": null, + "source_transfer": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "succeeded", + "transfer_data": null, + "transfer_group": null + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/charges?payment_intent=pi_3LsftNIadiFyUl1x2TWxaADZ" + }, + "client_secret": "pi_3LsftNIadiFyUl1x2TWxaADZ_secret_VxRx7Y1skyp0jKtq7Gdu80Xnh", + "confirmation_method": "automatic", + "created": 1665723185, + "currency": "usd", + "customer": null, + "description": "EDX-100011", + "invoice": null, + "last_payment_error": null, + "livemode": false, + "metadata": { + "order_number": "EDX-100011" + }, + "next_action": null, + "on_behalf_of": null, + "payment_method": "pm_1LsfuTIadiFyUl1xcHa5WALi", + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "secret_key_confirmation": "required", + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "succeeded", + "transfer_data": null, + "transfer_group": null + }, + "create_resp": { + "id": "pi_3LsftNIadiFyUl1x2TWxaADZ", + "object": "payment_intent", + "amount": 14900, + "amount_capturable": 0, + "amount_details": { + "tip": {} + }, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "automatic", + "charges": {}, + "client_secret": "pi_3LsftNIadiFyUl1x2TWxaADZ_secret_VxRx7Y1skyp0jKtq7Gdu80Xnh", + "confirmation_method": "automatic", + "created": 1665723185, + "currency": "usd", + "customer": null, + "description": "EDX-100011", + "invoice": null, + "last_payment_error": null, + "livemode": false, + "metadata": { + "order_number": "EDX-100011" + }, + "next_action": null, + "on_behalf_of": null, + "payment_method": null, + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "secret_key_confirmation": "required", + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "requires_payment_method", + "transfer_data": null, + "transfer_group": null + }, + "modify_resp": { + "id": "pi_3LsftNIadiFyUl1x2TWxaADZ", + "object": "payment_intent", + "amount": 14900, + "amount_capturable": 0, + "amount_details": { + "tip": {} + }, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "automatic", + "charges": {}, + "client_secret": "pi_3LsftNIadiFyUl1x2TWxaADZ_secret_VxRx7Y1skyp0jKtq7Gdu80Xnh", + "confirmation_method": "automatic", + "created": 1665723185, + "currency": "usd", + "customer": null, + "description": "EDX-100011", + "invoice": null, + "last_payment_error": null, + "livemode": false, + "metadata": { + "order_number": "EDX-100011" + }, + "next_action": null, + "on_behalf_of": null, + "payment_method": "pm_1LsfuTIadiFyUl1xcHa5WALi", + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "secret_key_confirmation": "required", + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "requires_confirmation", + "transfer_data": null, + "transfer_group": null + }, + "refund_resp": { + "id": "re_3LsftNIadiFyUl1x2KvTM7FO", + "object": "refund", + "amount": 14900, + "balance_transaction": "txn_3LsftNIadiFyUl1x2trZAzQP", + "charge": "ch_3LsftNIadiFyUl1x2Qh9P6Te", + "created": 1665723358, + "currency": "usd", + "metadata": {}, + "payment_intent": "pi_3LsftNIadiFyUl1x2TWxaADZ", + "reason": null, + "receipt_number": null, + "source_transfer_reversal": null, + "status": "succeeded", + "transfer_reversal": null + }, + "retrieve_addr_resp": { + "id": "pi_3LsftNIadiFyUl1x2TWxaADZ", + "object": "payment_intent", + "amount": 14900, + "amount_capturable": 0, + "amount_details": { + "tip": {} + }, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "automatic_payment_methods": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "automatic", + "charges": {}, + "client_secret": "pi_3LsftNIadiFyUl1x2TWxaADZ_secret_VxRx7Y1skyp0jKtq7Gdu80Xnh", + "confirmation_method": "automatic", + "created": 1665723185, + "currency": "usd", + "customer": null, + "description": "EDX-100011", + "invoice": null, + "last_payment_error": null, + "livemode": false, + "metadata": { + "order_number": "EDX-100011" + }, + "next_action": null, + "on_behalf_of": null, + "payment_method": { + "id": "pm_1LsfuTIadiFyUl1xcHa5WALi", + "object": "payment_method", + "billing_details": { + "address": { + "city": "Sample", + "country": "US", + "line1": "123 Test St", + "line2": null, + "postal_code": "12345", + "state": "MA" + }, + "email": "pshiu-dev-test-3@example.com", + "name": "Test User", + "phone": null + }, + "card": { + "brand": "visa", + "checks": { + "address_line1_check": "unchecked", + "address_postal_code_check": "unchecked", + "cvc_check": "unchecked" + }, + "country": "US", + "exp_month": 1, + "exp_year": 2023, + "fingerprint": "N2ltqpPKT2DuO8HF", + "funding": "credit", + "generated_from": null, + "last4": "1111", + "networks": { + "available": [ + "visa" + ], + "preferred": null + }, + "three_d_secure_usage": { + "supported": true + }, + "wallet": null + }, + "created": 1665723253, + "customer": null, + "livemode": false, + "metadata": {}, + "type": "card" + }, + "payment_method_options": { + "card": { + "installments": null, + "mandate_options": null, + "network": null, + "request_three_d_secure": "automatic" + } + }, + "payment_method_types": [ + "card" + ], + "processing": null, + "receipt_email": null, + "review": null, + "secret_key_confirmation": "required", + "setup_future_usage": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "statement_descriptor_suffix": null, + "status": "requires_confirmation", + "transfer_data": null, + "transfer_group": null + } + } +} diff --git a/ecommerce/extensions/payment/tests/views/test_stripe.py b/ecommerce/extensions/payment/tests/views/test_stripe.py index 7de03e2a7ec..901a70374aa 100644 --- a/ecommerce/extensions/payment/tests/views/test_stripe.py +++ b/ecommerce/extensions/payment/tests/views/test_stripe.py @@ -1,42 +1,48 @@ - - import stripe +from ddt import ddt, file_data from django.conf import settings from django.urls import reverse from mock import mock from oscar.core.loading import get_class, get_model -from oscar.test.factories import BillingAddressFactory +from rest_framework import status -from ecommerce.core.constants import ENROLLMENT_CODE_PRODUCT_CLASS_NAME, ENROLLMENT_CODE_SWITCH -from ecommerce.core.models import BusinessClient -from ecommerce.core.tests import toggle_switch +from ecommerce.core.constants import SEAT_PRODUCT_CLASS_NAME from ecommerce.courses.tests.factories import CourseFactory -from ecommerce.extensions.basket.constants import PURCHASER_BEHALF_ATTRIBUTE -from ecommerce.extensions.basket.utils import basket_add_organization_attribute from ecommerce.extensions.checkout.utils import get_receipt_page_url from ecommerce.extensions.order.constants import PaymentEventTypeName from ecommerce.extensions.payment.constants import STRIPE_CARD_TYPE_MAP from ecommerce.extensions.payment.processors.stripe import Stripe from ecommerce.extensions.payment.tests.mixins import PaymentEventsMixin from ecommerce.extensions.test.factories import create_basket -from ecommerce.invoice.models import Invoice from ecommerce.tests.testcases import TestCase +BasketAttribute = get_model('basket', 'BasketAttribute') +BasketAttributeType = get_model('basket', 'BasketAttributeType') Country = get_model('address', 'Country') Order = get_model('order', 'Order') PaymentEvent = get_model('order', 'PaymentEvent') Selector = get_class('partner.strategy', 'Selector') Source = get_model('payment', 'Source') Product = get_model('catalogue', 'Product') +PaymentProcessorResponse = get_model('payment', 'PaymentProcessorResponse') -class StripeSubmitViewTests(PaymentEventsMixin, TestCase): +@ddt +class StripeCheckoutViewTests(PaymentEventsMixin, TestCase): path = reverse('stripe:submit') def setUp(self): - super(StripeSubmitViewTests, self).setUp() + super(StripeCheckoutViewTests, self).setUp() self.user = self.create_user() self.client.login(username=self.user.username, password=self.password) + self.site.siteconfiguration.client_side_payment_processor = 'stripe' + self.site.siteconfiguration.save() + Country.objects.create(iso_3166_1_a2='US', name='US') + self.mock_enrollment_api_resp = mock.Mock() + self.mock_enrollment_api_resp.status_code = status.HTTP_200_OK + + self.stripe_checkout_url = reverse('stripe:checkout') + self.capture_context_url = reverse('bff:payment:v0:capture_context') def assert_successful_order_response(self, response, order_number): assert response.status_code == 201 @@ -67,16 +73,14 @@ def assert_order_created(self, basket, billing_address, card_type, label): ) assert order.billing_address == billing_address - def generate_form_data(self, basket_id): - return { - 'stripe_token': 'st_abc123', - 'basket': basket_id, - } - - def create_basket(self): - basket = create_basket(owner=self.user, site=self.site) + def create_basket(self, product_class=None): + basket = create_basket(owner=self.user, site=self.site, product_class=product_class) basket.strategy = Selector().strategy() basket.thaw() + basket.flush() + course = CourseFactory() + seat = course.create_or_update_seat('credit', False, 100, 'credit_provider_id', None, 2) + basket.add_product(seat, 1) return basket def test_login_required(self): @@ -85,114 +89,228 @@ def test_login_required(self): expected_url = '{base}?next={path}'.format(base=reverse(settings.LOGIN_URL), path=self.path) self.assertRedirects(response, expected_url, fetch_redirect_response=False) - def test_payment_error(self): - basket = self.create_basket() - data = self.generate_form_data(basket.id) - - with mock.patch.object(Stripe, 'get_address_from_token', mock.Mock(return_value=BillingAddressFactory())): - with mock.patch.object(Stripe, 'handle_processor_response', mock.Mock(side_effect=Exception)): - response = self.client.post(self.path, data) - - assert response.status_code == 400 - assert response.content.decode('utf-8') == '{}' - - def test_billing_address_error(self): - basket = self.create_basket() - data = self.generate_form_data(basket.id) - card_type = 'American Express' - label = '1986' - charge = stripe.Charge.construct_from({ - 'id': '2404', - 'source': { - 'brand': card_type, - 'last4': label, - }, - }, 'fake-key') - - with mock.patch.object(Stripe, 'get_address_from_token') as address_mock: - address_mock.side_effect = Exception - - with mock.patch.object(stripe.Charge, 'create') as charge_mock: - charge_mock.return_value = charge - response = self.client.post(self.path, data) - - address_mock.assert_called_once_with(data['stripe_token']) - - self.assert_successful_order_response(response, basket.order_number) - self.assert_order_created(basket, None, card_type, label) - - def test_successful_payment(self): - basket = self.create_basket() - data = self.generate_form_data(basket.id) - card_type = 'American Express' - label = '1986' - charge = stripe.Charge.construct_from({ - 'id': '2404', - 'source': { - 'brand': card_type, - 'last4': label, - }, - }, 'fake-key') - - billing_address = BillingAddressFactory() - with mock.patch.object(Stripe, 'get_address_from_token') as address_mock: - address_mock.return_value = billing_address - - with mock.patch.object(stripe.Charge, 'create') as charge_mock: - charge_mock.return_value = charge - response = self.client.post(self.path, data) - - address_mock.assert_called_once_with(data['stripe_token']) - - self.assert_successful_order_response(response, basket.order_number) - self.assert_order_created(basket, billing_address, card_type, label) - - def test_successful_payment_for_bulk_purchase(self): + @file_data('fixtures/test_stripe_test_payment_flow.json') + def test_payment_flow( + self, + confirm_resp, + create_resp, + modify_resp, + refund_resp, # pylint: disable=unused-argument + retrieve_addr_resp): """ - Verify that when a Order has been successfully placed for bulk - purchase then that order is linked to the provided business client. + Verify that the stripe payment flow, hitting capture-context and + stripe-checkout urls, results in a basket associated with the correct + stripe payment_intent_id. + + Args: + confirm_resp: Response for confirm call on payment purchase + create_resp: Response for create call when capturing context + modify_resp: Response for modify call before confirming response + retrieve_addr_resp: Response for retrieve call that should be made when getting billing address + confirm_resp: Response for confirm call that should be made when handling processor response """ - toggle_switch(ENROLLMENT_CODE_SWITCH, True) - - course = CourseFactory(partner=self.partner) - course.create_or_update_seat('verified', True, 50, create_enrollment_code=True) - basket = create_basket(owner=self.user, site=self.site) - enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME) - basket.add_product(enrollment_code, quantity=1) - basket.strategy = Selector().strategy() + basket = self.create_basket(product_class=SEAT_PRODUCT_CLASS_NAME) + idempotency_key = f'basket_pi_create_v1_{basket.order_number}' + + # need to call capture-context endpoint before we call do GET to the stripe checkout view + # so that the PaymentProcessorResponse is already created + with mock.patch('stripe.PaymentIntent.create') as mock_create: + mock_create.return_value = create_resp + self.client.get(self.capture_context_url) + mock_create.assert_called_once() + assert mock_create.call_args.kwargs['idempotency_key'] == idempotency_key + + with mock.patch('stripe.PaymentIntent.retrieve') as mock_retrieve: + mock_retrieve.return_value = retrieve_addr_resp + + with mock.patch( + 'ecommerce.extensions.fulfillment.modules.EnrollmentFulfillmentModule._post_to_enrollment_api' + ) as mock_api_resp: + mock_api_resp.return_value = self.mock_enrollment_api_resp + + with mock.patch('stripe.PaymentIntent.confirm') as mock_confirm: + mock_confirm.return_value = confirm_resp + with mock.patch('stripe.PaymentIntent.modify') as mock_modify: + mock_modify.return_value = modify_resp + self.client.post( + self.stripe_checkout_url, + data={'payment_intent_id': 'pi_3LsftNIadiFyUl1x2TWxaADZ'}, + ) + assert mock_retrieve.call_count == 1 + assert mock_modify.call_count == 1 + assert mock_confirm.call_count == 1 + + # Verify BillingAddress was set correctly + basket.refresh_from_db() + order = basket.order_set.first() + assert str(order.billing_address) == "Test User, 123 Test St, Sample, MA, 12345" + + # Verify there is 1 and only 1 Basket Attribute with the payment_intent_id + # associated with our basket. + assert BasketAttribute.objects.filter( + value_text='pi_3LsftNIadiFyUl1x2TWxaADZ', + basket=basket, + ).count() == 1 + + pprs = PaymentProcessorResponse.objects.filter( + transaction_id="pi_3LsftNIadiFyUl1x2TWxaADZ" + ) + # created when andle_processor_response is successful + assert pprs.count() == 1 - data = self.generate_form_data(basket.id) - data.update({'organization': 'Dummy Business Client'}) - data.update({PURCHASER_BEHALF_ATTRIBUTE: 'False'}) - - # Manually add organization attribute on the basket for testing - basket_add_organization_attribute(basket, data) - - card_type = 'American Express' - label = '1986' - charge = stripe.Charge.construct_from({ - 'id': '2404', - 'source': { - 'brand': card_type, - 'last4': label, - }, - }, 'fake-key') - - billing_address = BillingAddressFactory() - with mock.patch.object(Stripe, 'get_address_from_token') as address_mock: - address_mock.return_value = billing_address - - with mock.patch.object(stripe.Charge, 'create') as charge_mock: - charge_mock.return_value = charge - response = self.client.post(self.path, data) - - address_mock.assert_called_once_with(data['stripe_token']) - - self.assert_successful_order_response(response, basket.order_number) - self.assert_order_created(basket, billing_address, card_type, label) - - # Now verify that a new business client has been created and current - # order is now linked with that client through Invoice model. - order = Order.objects.filter(basket=basket).first() - business_client = BusinessClient.objects.get(name=data['organization']) - assert Invoice.objects.get(order=order).business_client == business_client + def test_capture_context_basket_price_change(self): + """ + Verify that existing payment intent is retrieved, + and that we do not error with an IdempotencyError in this case: capture + context is called to generate stripe elements, but then user backs out from + payment page, and tries to check out with a different things in the basket. + """ + basket = self.create_basket(product_class=SEAT_PRODUCT_CLASS_NAME) + idempotency_key = f'basket_pi_create_v1_{basket.order_number}' + + with mock.patch('stripe.PaymentIntent.create') as mock_create: + mock_create.return_value = { + 'id': 'pi_3LsftNIadiFyUl1x2TWxaADZ', + 'client_secret': 'pi_3LsftNIadiFyUl1x2TWxaADZ_secret_VxRx7Y1skyp0jKtq7Gdu80Xnh', + } + self.client.get(self.capture_context_url) + mock_create.assert_called_once() + assert mock_create.call_args.kwargs['idempotency_key'] == idempotency_key + + # Verify there is 1 and only 1 Basket Attribute with the payment_intent_id + # associated with our basket. + assert BasketAttribute.objects.filter( + value_text='pi_3LsftNIadiFyUl1x2TWxaADZ', + basket=basket, + ).count() == 1 + + # Change the basket price + basket.flush() + course = CourseFactory() + seat = course.create_or_update_seat('credit', False, 99, 'credit_provider_id', None, 2) + basket.add_product(seat, 1) + basket.save() + + with mock.patch('stripe.PaymentIntent.create') as mock_create: + mock_create.side_effect = stripe.error.IdempotencyError + + with mock.patch('stripe.PaymentIntent.retrieve') as mock_retrieve: + mock_retrieve.return_value = { + 'id': 'pi_3LsftNIadiFyUl1x2TWxaADZ', + 'client_secret': 'pi_3LsftNIadiFyUl1x2TWxaADZ_secret_VxRx7Y1skyp0jKtq7Gdu80Xnh', + } + self.client.get(self.capture_context_url) + mock_retrieve.assert_called_once() + assert mock_retrieve.call_args.kwargs['id'] == 'pi_3LsftNIadiFyUl1x2TWxaADZ' + + # def test_payment_error(self): + # basket = self.create_basket() + # data = self.generate_form_data(basket.id) + + # with mock.patch.object(Stripe, 'get_address_from_token', mock.Mock(return_value=BillingAddressFactory())): + # with mock.patch.object(Stripe, 'handle_processor_response', mock.Mock(side_effect=Exception)): + # response = self.client.post(self.path, data) + + # assert response.status_code == 400 + # assert response.content.decode('utf-8') == '{}' + + # def test_billing_address_error(self): + # basket = self.create_basket() + # data = self.generate_form_data(basket.id) + # card_type = 'visa' + # label = '4242' + # payment_intent = stripe.PaymentIntent.construct_from({ + # 'id': 'pi_testtesttest', + # 'source': { + # 'brand': card_type, + # 'last4': label, + # }, + # }, 'fake-key') + + # with mock.patch.object(Stripe, 'get_address_from_token') as address_mock: + # address_mock.side_effect = Exception + + # with mock.patch.object(stripe.PaymentIntent, 'create') as pi_mock: + # pi_mock.return_value = payment_intent + # response = self.client.post(self.path, data) + + # address_mock.assert_called_once_with(data['payment_intent_id']) + + # self.assert_successful_order_response(response, basket.order_number) + # self.assert_order_created(basket, None, card_type, label) + + # def test_successful_payment(self): + # basket = self.create_basket() + # data = self.generate_form_data(basket.id) + # card_type = 'visa' + # label = '4242' + # payment_intent = stripe.PaymentIntent.construct_from({ + # 'id': 'pi_testtesttest', + # 'source': { + # 'brand': card_type, + # 'last4': label, + # }, + # }, 'fake-key') + + # billing_address = BillingAddressFactory() + # with mock.patch.object(Stripe, 'get_address_from_token') as address_mock: + # address_mock.return_value = billing_address + + # with mock.patch.object(stripe.PaymentIntent, 'create') as pi_mock: + # pi_mock.return_value = payment_intent + # response = self.client.post(self.path, data) + + # address_mock.assert_called_once_with(data['payment_intent_id']) + + # self.assert_successful_order_response(response, basket.order_number) + # self.assert_order_created(basket, billing_address, card_type, label) + + # def test_successful_payment_for_bulk_purchase(self): + # """ + # Verify that when a Order has been successfully placed for bulk + # purchase then that order is linked to the provided business client. + # """ + # toggle_switch(ENROLLMENT_CODE_SWITCH, True) + + # course = CourseFactory(partner=self.partner) + # course.create_or_update_seat('verified', True, 50, create_enrollment_code=True) + # basket = create_basket(owner=self.user, site=self.site) + # enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME) + # basket.add_product(enrollment_code, quantity=1) + # basket.strategy = Selector().strategy() + + # data = self.generate_form_data(basket.id) + # data.update({'organization': 'Dummy Business Client'}) + # data.update({PURCHASER_BEHALF_ATTRIBUTE: 'False'}) + + # # Manually add organization attribute on the basket for testing + # basket_add_organization_attribute(basket, data) + + # card_type = 'visa' + # label = '4242' + # payment_intent = stripe.PaymentIntent.construct_from({ + # 'id': 'pi_testtesttest', + # 'source': { + # 'brand': card_type, + # 'last4': label, + # }, + # }, 'fake-key') + + # billing_address = BillingAddressFactory() + # with mock.patch.object(Stripe, 'get_address_from_token') as address_mock: + # address_mock.return_value = billing_address + + # with mock.patch.object(stripe.PaymentIntent, 'create') as pi_mock: + # pi_mock.return_value = payment_intent + # response = self.client.post(self.path, data) + + # address_mock.assert_called_once_with(data['payment_intent_id']) + + # self.assert_successful_order_response(response, basket.order_number) + # self.assert_order_created(basket, billing_address, card_type, label) + + # # Now verify that a new business client has been created and current + # # order is now linked with that client through Invoice model. + # order = Order.objects.filter(basket=basket).first() + # business_client = BusinessClient.objects.get(name=data['organization']) + # assert Invoice.objects.get(order=order).business_client == business_client diff --git a/ecommerce/extensions/payment/urls.py b/ecommerce/extensions/payment/urls.py index 2b5a1c3841f..6ae80cadaaa 100644 --- a/ecommerce/extensions/payment/urls.py +++ b/ecommerce/extensions/payment/urls.py @@ -25,6 +25,7 @@ STRIPE_URLS = [ url(r'^submit/$', stripe.StripeSubmitView.as_view(), name='submit'), + url(r'^checkout', stripe.StripeCheckoutView.as_view(), name='checkout'), ] urlpatterns = [ diff --git a/ecommerce/extensions/payment/views/apple_pay.py b/ecommerce/extensions/payment/views/apple_pay.py index f345d1cfec1..b59c055acef 100644 --- a/ecommerce/extensions/payment/views/apple_pay.py +++ b/ecommerce/extensions/payment/views/apple_pay.py @@ -11,7 +11,7 @@ class ApplePayMerchantDomainAssociationView(View): def get(self, request, *args, **kwargs): # pylint: disable=unused-argument site_configuration = self.request.site.siteconfiguration - payment_processor_class = site_configuration.get_client_side_payment_processor_class() + payment_processor_class = site_configuration.get_client_side_payment_processor_class(self.request) payment_processor = payment_processor_class(self.request.site) content = payment_processor.apple_pay_merchant_id_domain_association status_code = 200 diff --git a/ecommerce/extensions/payment/views/stripe.py b/ecommerce/extensions/payment/views/stripe.py index 024ec449b6c..d0863a527bf 100644 --- a/ecommerce/extensions/payment/views/stripe.py +++ b/ecommerce/extensions/payment/views/stripe.py @@ -2,12 +2,20 @@ import logging +from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist +from django.db import transaction from django.http import JsonResponse +from django.shortcuts import redirect +from oscar.apps.partner import strategy from oscar.core.loading import get_class, get_model +from rest_framework.permissions import IsAuthenticated +from rest_framework.views import APIView +from stripe.error import CardError -from ecommerce.extensions.basket.utils import basket_add_organization_attribute +from ecommerce.extensions.basket.utils import basket_add_organization_attribute, basket_add_payment_intent_id_attribute from ecommerce.extensions.checkout.mixins import EdxOrderPlacementMixin from ecommerce.extensions.checkout.utils import get_receipt_page_url +from ecommerce.extensions.payment.core.sdn import checkSDN from ecommerce.extensions.payment.forms import StripeSubmitForm from ecommerce.extensions.payment.processors.stripe import Stripe from ecommerce.extensions.payment.views import BasePaymentSubmitView @@ -15,10 +23,12 @@ logger = logging.getLogger(__name__) Applicator = get_class('offer.applicator', 'Applicator') +BasketAttribute = get_model('basket', 'BasketAttribute') BillingAddress = get_model('order', 'BillingAddress') Country = get_model('address', 'Country') NoShippingRequired = get_class('shipping.methods', 'NoShippingRequired') OrderTotalCalculator = get_class('checkout.calculators', 'OrderTotalCalculator') +PaymentProcessorResponse = get_model('payment', 'PaymentProcessorResponse') class StripeSubmitView(EdxOrderPlacementMixin, BasePaymentSubmitView): @@ -36,29 +46,20 @@ def payment_processor(self): def form_valid(self, form): form_data = form.cleaned_data basket = form_data['basket'] - token = form_data['stripe_token'] + payment_intent_id = form_data['payment_intent_id'] order_number = basket.order_number basket_add_organization_attribute(basket, self.request.POST) + basket_add_payment_intent_id_attribute(basket, self.request.POST) try: - billing_address = self.payment_processor.get_address_from_token(token) - except Exception: # pylint: disable=broad-except - logger.exception( - 'An error occurred while parsing the billing address for basket [%d]. No billing address will be ' - 'stored for the resulting order [%s].', - basket.id, - order_number) - billing_address = None - - try: - self.handle_payment(token, basket) + self.handle_payment(payment_intent_id, basket) except Exception: # pylint: disable=broad-except logger.exception('An error occurred while processing the Stripe payment for basket [%d].', basket.id) return JsonResponse({}, status=400) try: - order = self.create_order(self.request, basket, billing_address=billing_address) + order = self.create_order(self.request, basket) except Exception: # pylint: disable=broad-except logger.exception('An error occurred while processing the Stripe payment for basket [%d].', basket.id) return JsonResponse({}, status=400) @@ -72,3 +73,165 @@ def form_valid(self, form): disable_back_button=True ) return JsonResponse({'url': receipt_url}, status=201) + + +class StripeCheckoutView(EdxOrderPlacementMixin, APIView): + http_method_names = ['post'] + + # DRF APIView wrapper which allows clients to use JWT authentication when + # making Stripe checkout submit requests. + permission_classes = [IsAuthenticated] + + @property + def payment_processor(self): + return Stripe(self.request.site) + + def check_sdn(self, request, data): + """ + Check that the supplied request and form data passes SDN checks. + + Returns: + hit_count (int) if the SDN check fails, or None if it succeeds. + """ + hit_count = checkSDN( + request, + data['name'], + data['city'], + data['country']) + + if hit_count > 0: + logger.info( + 'SDNCheck function called for basket [%d]. It received %d hit(s).', + request.basket.id, + hit_count, + ) + return hit_count + + logger.info( + 'SDNCheck function called for basket [%d]. It did not receive a hit.', + request.basket.id, + ) + return None + + def _get_basket(self, payment_intent_id): + """ + Retrieve a basket using a payment intent ID. + + Arguments: + payment_intent_id: payment_intent_id received from Stripe. + + Returns: + It will return related basket or log exception and return None if + duplicate payment_intent_id* received or any other exception occurred. + """ + try: + basket_attribute = BasketAttribute.objects.get(value_text=payment_intent_id) + basket = basket_attribute.basket + basket.strategy = strategy.Default() + + Applicator().apply(basket, basket.owner, self.request) + + basket_add_organization_attribute(basket, self.request.GET) + except MultipleObjectsReturned: + logger.warning(u"Duplicate payment_intent_id [%s] received from Stripe.", payment_intent_id) + return None + except ObjectDoesNotExist: + logger.warning(u"Could not find payment_intent_id [%s] among baskets.", payment_intent_id) + return None + except Exception: # pylint: disable=broad-except + logger.exception(u"Unexpected error during basket retrieval while executing Stripe payment.") + return None + return basket + + def post(self, request): + """Handle an incoming user returned to us by Stripe after approving payment.""" + stripe_response = request.POST.dict() + payment_intent_id = stripe_response.get('payment_intent_id') + + logger.info( + '%s called for payment intent id [%s].', + self.__class__.__name__, + request.POST.get('payment_intent_id') + ) + + basket = self._get_basket(payment_intent_id) + + if not basket: + return redirect(self.payment_processor.error_url) + + # SDN Check here! + billing_address_obj = self.payment_processor.get_address_from_token( + payment_intent_id + ) + sdn_check_data = { + # Stripe has 1 name field so we use first_name on billing_address_obj + 'name': billing_address_obj.first_name, + 'city': billing_address_obj.city, + 'country': billing_address_obj.country_id, + } + sdn_check_failure = self.check_sdn(self.request, sdn_check_data) + if sdn_check_failure is not None: + return self.sdn_error_page_response(sdn_check_failure) + + try: + with transaction.atomic(): + try: + self.handle_payment(stripe_response, basket) + except CardError as err: + return self.stripe_error_response(err) + except: # pylint: disable=bare-except + logger.exception('Attempts to handle payment for basket [%d] failed.', basket.id) + return self.error_page_response() + + try: + billing_address = self.create_billing_address( + user=self.request.user, + billing_address=billing_address_obj + ) + except Exception as err: # pylint: disable=broad-except + logger.exception('Error creating billing address for basket [%d]: %s', basket.id, err) + billing_address = None + + try: + order = self.create_order(request, basket, billing_address) + self.handle_post_order(order) + except Exception: # pylint: disable=broad-except + logger.exception( + 'Error processing order for transaction [%s], with order [%s] and basket [%d]. Processed by [%s].', + payment_intent_id, + basket.order_number, + basket.id, + self.payment_processor.NAME, + ) + return self.error_page_response() + + return self.receipt_page_response(basket) + + def error_page_response(self): + """Tell the frontend to redirect to a generic error page.""" + return JsonResponse({}, status=400) + + def sdn_error_page_response(self, hit_count): + """Tell the frontend to redirect to the SDN error page.""" + return JsonResponse({ + 'sdn_check_failure': {'hit_count': hit_count} + }, status=400) + + def receipt_page_response(self, basket): + """Tell the frontend to redirect to the receipt page.""" + receipt_page_url = get_receipt_page_url( + self.request, + order_number=basket.order_number, + site_configuration=basket.site.siteconfiguration, + disable_back_button=True + ) + return JsonResponse({ + 'receipt_page_url': receipt_page_url, + }, status=201) + + def stripe_error_response(self, error): + """Tell the frontend that a Stripe error has occurred.""" + return JsonResponse({ + 'error_code': error.code, + 'user_message': error.user_message, + }, status=400) diff --git a/ecommerce/management/utils.py b/ecommerce/management/utils.py index 0bd0e43b07a..7b58a69f76a 100644 --- a/ecommerce/management/utils.py +++ b/ecommerce/management/utils.py @@ -7,7 +7,7 @@ from oscar.core.loading import get_class, get_model from ecommerce.extensions.checkout.mixins import EdxOrderPlacementMixin -from ecommerce.extensions.payment.constants import CYBERSOURCE_CARD_TYPE_MAP +from ecommerce.extensions.payment.constants import CYBERSOURCE_CARD_TYPE_MAP, STRIPE_CARD_TYPE_MAP from ecommerce.extensions.payment.helpers import get_processor_class_by_name from ecommerce.extensions.payment.processors import HandledProcessorResponse @@ -106,9 +106,10 @@ def get_payment_notification(basket): """ # Filter the successful payment processor response which in case # of Cybersource includes "u'decision': u'ACCEPT'" and in case of - # Paypal includes "u'state': u'approved'". + # Paypal includes "u'state': u'approved'" and in the case of Stripe + # includes "u'status': u'succeeded'". successful_transaction = basket.paymentprocessorresponse_set.filter( - Q(response__contains='ACCEPT') | Q(response__contains='approved') + Q(response__contains='ACCEPT') | Q(response__contains='approved') | Q(response__contains='succeeded') ) # In case of no successful transactions log and return none. @@ -122,6 +123,21 @@ def get_payment_notification(basket): logger.warning('Basket %d has more than one successful transaction id, using the first one', basket.id) return successful_transaction[0] + @staticmethod + def get_card_info_from_payment_notification(payment_notification): + if payment_notification.transaction_id.startswith('PAY'): + card_number = 'Paypal Account' + card_type = None + elif payment_notification.transaction_id.startswith('pi_'): + card_number = payment_notification.response['payment_method']['card']['last4'] + stripe_card_type = payment_notification.response['payment_method']['card']['brand'] + card_type = STRIPE_CARD_TYPE_MAP[stripe_card_type] + else: + card_number = payment_notification.response['req_card_number'] + cybersource_card_type = payment_notification.response['req_card_type'] + card_type = CYBERSOURCE_CARD_TYPE_MAP[cybersource_card_type] + return (card_number, card_type) + def fulfill_basket(self, basket_id, site): logger.info('Trying to complete order for frozen basket %d', basket_id) @@ -154,12 +170,11 @@ def fulfill_basket(self, basket_id, site): if not payment_notification: return False - if payment_notification.transaction_id.startswith('PAY'): - card_number = 'Paypal Account' - card_type = None - else: - card_number = payment_notification.response['req_card_number'] - card_type = CYBERSOURCE_CARD_TYPE_MAP.get(payment_notification.response['req_card_type']) + try: + card_number, card_type = self.get_card_info_from_payment_notification(payment_notification) + except (KeyError, TypeError): + logger.exception('Unable to parse payment details for basket %d', basket.id) + return False self.payment_processor = _get_payment_processor(site, payment_notification.processor_name) # Create handled response diff --git a/ecommerce/settings/_oscar.py b/ecommerce/settings/_oscar.py index 8ae0e1b0200..6feefba37d1 100644 --- a/ecommerce/settings/_oscar.py +++ b/ecommerce/settings/_oscar.py @@ -168,10 +168,16 @@ 'error_path': PAYMENT_PROCESSOR_ERROR_PATH, }, 'stripe': { + 'api_version': '2022-08-01; server_side_confirmation_beta=v1', + 'enable_telemetry': None, + 'log_level': None, + 'max_network_retries': 0, + 'proxy': None, 'publishable_key': None, 'secret_key': None, - 'country': None, - 'apple_pay_merchant_id_domain_association': '7B227073704964223A2239373943394538343346343131343044463144313834343232393232313734313034353044314339464446394437384337313531303944334643463542433731222C2276657273696F6E223A312C22637265617465644F6E223A313437313435343137313137362C227369676E6174757265223A2233303830303630393261383634383836663730643031303730326130383033303830303230313031333130663330306430363039363038363438303136353033303430323031303530303330383030363039326138363438383666373064303130373031303030306130383033303832303365363330383230333862613030333032303130323032303836383630663639396439636361373066333030613036303832613836343863653364303430333032333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303165313730643331333633303336333033333331333833313336333433303561313730643332333133303336333033323331333833313336333433303561333036323331323833303236303630333535303430333063316636353633363332643733366437303264363237323666366236353732326437333639363736653566353534333334326435333431346534343432346635383331313433303132303630333535303430623063306236393466353332303533373937333734363536643733333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303539333031333036303732613836343863653364303230313036303832613836343863653364303330313037303334323030303438323330666461626333396366373565323032633530643939623435313265363337653261393031646436636233653062316364346235323637393866386366346562646538316132356138633231653463333364646365386532613936633266366166613139333033343563346538376134343236636539353162313239356133383230323131333038323032306433303435303630383262303630313035303530373031303130343339333033373330333530363038326230363031303530353037333030313836323936383734373437303361326632663666363337333730326536313730373036633635326536333666366432663666363337333730333033343264363137303730366336353631363936333631333333303332333031643036303335353164306530343136303431343032323433303062396165656564343633313937613461363561323939653432373138323163343533303063303630333535316431333031303166663034303233303030333031663036303335353164323330343138333031363830313432336632343963343466393365346566323765366334663632383663336661326262666432653462333038323031316430363033353531643230303438323031313433303832303131303330383230313063303630393261383634383836663736333634303530313330383166653330383163333036303832623036303130353035303730323032333038316236306338316233353236353663363936313665363336353230366636653230373436383639373332303633363537323734363936363639363336313734363532303632373932303631366537393230373036313732373437393230363137333733373536643635373332303631363336333635373037343631366536333635323036663636323037343638363532303734363836353665323036313730373036633639363336313632366336353230373337343631366536343631373236343230373436353732366437333230363136653634323036333666366536343639373436393666366537333230366636363230373537333635326332303633363537323734363936363639363336313734363532303730366636633639363337393230363136653634323036333635373237343639363636393633363137343639366636653230373037323631363337343639363336353230373337343631373436353664363536653734373332653330333630363038326230363031303530353037303230313136326136383734373437303361326632663737373737373265363137303730366336353265363336663664326636333635373237343639363636393633363137343635363137353734363836663732363937343739326633303334303630333535316431663034326433303262333032396130323761303235383632333638373437343730336132663266363337323663326536313730373036633635326536333666366432663631373037303663363536313639363336313333326536333732366333303065303630333535316430663031303166663034303430333032303738303330306630363039326138363438383666373633363430363164303430323035303033303061303630383261383634386365336430343033303230333439303033303436303232313030646131633633616538626535663634663865313165383635363933376239623639633437326265393365616333323333613136373933366534613864356538333032323130306264356166626638363966336330636132373462326664646534663731373135396362336264373139396232636130666634303964653635396138326232346433303832303265653330383230323735613030333032303130323032303834393664326662663361393864613937333030613036303832613836343863653364303430333032333036373331316233303139303630333535303430333063313234313730373036633635323035323666366637343230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313334333033353330333633323333333433363333333035613137306433323339333033353330333633323333333433363333333035613330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034663031373131383431396437363438356435316135653235383130373736653838306132656664653762616534646530386466633462393365313333353664353636356233356165323264303937373630643232346537626261303866643736313763653838636237366262363637306265633865383239383466663534343561333831663733303831663433303436303630383262303630313035303530373031303130343361333033383330333630363038326230363031303530353037333030313836326136383734373437303361326632663666363337333730326536313730373036633635326536333666366432663666363337333730333033343264363137303730366336353732366636663734363336313637333333303164303630333535316430653034313630343134323366323439633434663933653465663237653663346636323836633366613262626664326534623330306630363033353531643133303130316666303430353330303330313031666633303166303630333535316432333034313833303136383031346262623064656131353833333838396161343861393964656265626465626166646163623234616233303337303630333535316431663034333033303265333032636130326161303238383632363638373437343730336132663266363337323663326536313730373036633635326536333666366432663631373037303663363537323666366637343633363136373333326536333732366333303065303630333535316430663031303166663034303430333032303130363330313030363061326138363438383666373633363430363032306530343032303530303330306130363038326138363438636533643034303330323033363730303330363430323330336163663732383335313136393962313836666233356333353663613632626666343137656464393066373534646132386562656631396338313565343262373839663839386637396235393966393864353431306438663964653963326665303233303332326464353434323162306133303537373663356466333338336239303637666431373763326332313664393634666336373236393832313236663534663837613764316239396362396230393839323136313036393930663039393231643030303033313832303136303330383230313563303230313031333038313836333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353330323038363836306636393964396363613730663330306430363039363038363438303136353033303430323031303530306130363933303138303630393261383634383836663730643031303930333331306230363039326138363438383666373064303130373031333031633036303932613836343838366637306430313039303533313066313730643331333633303338333133373331333733313336333133313561333032663036303932613836343838366637306430313039303433313232303432303733343832623432653665366332323264616536643963303961346336663332316534656136653666326661626631356430376562333338643264613435646233303061303630383261383634386365336430343033303230343438333034363032323130306564333264376438616131623536623036626164623162396639396264643063653662363931316530623032393232633934333362663564326130656135353830323231303066393433353637663030323361643061343561373236663238376636303062656334666566373335383832383935633733313531383337336163383934383137303030303030303030303030227D', + 'error_path': PAYMENT_PROCESSOR_ERROR_PATH, + 'cancel_checkout_path': PAYMENT_PROCESSOR_CANCEL_PATH, + 'receipt_url': PAYMENT_PROCESSOR_RECEIPT_PATH, }, }, } diff --git a/ecommerce/settings/base.py b/ecommerce/settings/base.py index 7347b2aa3d1..6432d0969a8 100644 --- a/ecommerce/settings/base.py +++ b/ecommerce/settings/base.py @@ -810,7 +810,17 @@ 'error_url': '/checkout/error/', 'mode': 'sandbox', 'receipt_url': '/checkout/receipt/' - } + }, + 'stripe': { + 'api_version': '2022-08-01; server_side_confirmation_beta=v1', + 'enable_telemetry': None, + 'log_level': None, + 'max_network_retries': 0, + 'proxy': None, + 'publishable_key': 'SET-ME-PLEASE', + 'receipt_url': '/checkout/receipt/', + 'secret_key': 'SET-ME-PLEASE', + }, } } MEDIA_STORAGE_BACKEND = { diff --git a/ecommerce/settings/devstack.py b/ecommerce/settings/devstack.py index 5d58eae4dcd..7cdd4f263c5 100644 --- a/ecommerce/settings/devstack.py +++ b/ecommerce/settings/devstack.py @@ -95,10 +95,16 @@ 'error_path': PAYMENT_PROCESSOR_ERROR_PATH, }, 'stripe': { - 'publishable_key': 'pk_test_JU90ubQThS4C5K4E3gG2K61N', - 'secret_key': 'sk_test_cHL2I2pDzsp5ApNTKX3E97oq', - 'country': 'US', - 'apple_pay_merchant_id_domain_association': '7B227073704964223A2239373943394538343346343131343044463144313834343232393232313734313034353044314339464446394437384337313531303944334643463542433731222C2276657273696F6E223A312C22637265617465644F6E223A313437313435343137313137362C227369676E6174757265223A2233303830303630393261383634383836663730643031303730326130383033303830303230313031333130663330306430363039363038363438303136353033303430323031303530303330383030363039326138363438383666373064303130373031303030306130383033303832303365363330383230333862613030333032303130323032303836383630663639396439636361373066333030613036303832613836343863653364303430333032333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303165313730643331333633303336333033333331333833313336333433303561313730643332333133303336333033323331333833313336333433303561333036323331323833303236303630333535303430333063316636353633363332643733366437303264363237323666366236353732326437333639363736653566353534333334326435333431346534343432346635383331313433303132303630333535303430623063306236393466353332303533373937333734363536643733333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303539333031333036303732613836343863653364303230313036303832613836343863653364303330313037303334323030303438323330666461626333396366373565323032633530643939623435313265363337653261393031646436636233653062316364346235323637393866386366346562646538316132356138633231653463333364646365386532613936633266366166613139333033343563346538376134343236636539353162313239356133383230323131333038323032306433303435303630383262303630313035303530373031303130343339333033373330333530363038326230363031303530353037333030313836323936383734373437303361326632663666363337333730326536313730373036633635326536333666366432663666363337333730333033343264363137303730366336353631363936333631333333303332333031643036303335353164306530343136303431343032323433303062396165656564343633313937613461363561323939653432373138323163343533303063303630333535316431333031303166663034303233303030333031663036303335353164323330343138333031363830313432336632343963343466393365346566323765366334663632383663336661326262666432653462333038323031316430363033353531643230303438323031313433303832303131303330383230313063303630393261383634383836663736333634303530313330383166653330383163333036303832623036303130353035303730323032333038316236306338316233353236353663363936313665363336353230366636653230373436383639373332303633363537323734363936363639363336313734363532303632373932303631366537393230373036313732373437393230363137333733373536643635373332303631363336333635373037343631366536333635323036663636323037343638363532303734363836353665323036313730373036633639363336313632366336353230373337343631366536343631373236343230373436353732366437333230363136653634323036333666366536343639373436393666366537333230366636363230373537333635326332303633363537323734363936363639363336313734363532303730366636633639363337393230363136653634323036333635373237343639363636393633363137343639366636653230373037323631363337343639363336353230373337343631373436353664363536653734373332653330333630363038326230363031303530353037303230313136326136383734373437303361326632663737373737373265363137303730366336353265363336663664326636333635373237343639363636393633363137343635363137353734363836663732363937343739326633303334303630333535316431663034326433303262333032396130323761303235383632333638373437343730336132663266363337323663326536313730373036633635326536333666366432663631373037303663363536313639363336313333326536333732366333303065303630333535316430663031303166663034303430333032303738303330306630363039326138363438383666373633363430363164303430323035303033303061303630383261383634386365336430343033303230333439303033303436303232313030646131633633616538626535663634663865313165383635363933376239623639633437326265393365616333323333613136373933366534613864356538333032323130306264356166626638363966336330636132373462326664646534663731373135396362336264373139396232636130666634303964653635396138326232346433303832303265653330383230323735613030333032303130323032303834393664326662663361393864613937333030613036303832613836343863653364303430333032333036373331316233303139303630333535303430333063313234313730373036633635323035323666366637343230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313334333033353330333633323333333433363333333035613137306433323339333033353330333633323333333433363333333035613330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034663031373131383431396437363438356435316135653235383130373736653838306132656664653762616534646530386466633462393365313333353664353636356233356165323264303937373630643232346537626261303866643736313763653838636237366262363637306265633865383239383466663534343561333831663733303831663433303436303630383262303630313035303530373031303130343361333033383330333630363038326230363031303530353037333030313836326136383734373437303361326632663666363337333730326536313730373036633635326536333666366432663666363337333730333033343264363137303730366336353732366636663734363336313637333333303164303630333535316430653034313630343134323366323439633434663933653465663237653663346636323836633366613262626664326534623330306630363033353531643133303130316666303430353330303330313031666633303166303630333535316432333034313833303136383031346262623064656131353833333838396161343861393964656265626465626166646163623234616233303337303630333535316431663034333033303265333032636130326161303238383632363638373437343730336132663266363337323663326536313730373036633635326536333666366432663631373037303663363537323666366637343633363136373333326536333732366333303065303630333535316430663031303166663034303430333032303130363330313030363061326138363438383666373633363430363032306530343032303530303330306130363038326138363438636533643034303330323033363730303330363430323330336163663732383335313136393962313836666233356333353663613632626666343137656464393066373534646132386562656631396338313565343262373839663839386637396235393966393864353431306438663964653963326665303233303332326464353434323162306133303537373663356466333338336239303637666431373763326332313664393634666336373236393832313236663534663837613764316239396362396230393839323136313036393930663039393231643030303033313832303136303330383230313563303230313031333038313836333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353330323038363836306636393964396363613730663330306430363039363038363438303136353033303430323031303530306130363933303138303630393261383634383836663730643031303930333331306230363039326138363438383666373064303130373031333031633036303932613836343838366637306430313039303533313066313730643331333633303338333133373331333733313336333133313561333032663036303932613836343838366637306430313039303433313232303432303733343832623432653665366332323264616536643963303961346336663332316534656136653666326661626631356430376562333338643264613435646233303061303630383261383634386365336430343033303230343438333034363032323130306564333264376438616131623536623036626164623162396639396264643063653662363931316530623032393232633934333362663564326130656135353830323231303066393433353637663030323361643061343561373236663238376636303062656334666566373335383832383935633733313531383337336163383934383137303030303030303030303030227D', + 'api_version': '2022-08-01; server_side_confirmation_beta=v1', + 'enable_telemetry': None, + 'log_level': 'debug', + 'max_network_retries': 0, + 'proxy': None, + 'publishable_key': 'SET-ME-PLEASE', + 'secret_key': 'SET-ME-PLEASE', + 'error_path': PAYMENT_PROCESSOR_ERROR_PATH, + 'cancel_checkout_path': PAYMENT_PROCESSOR_CANCEL_PATH, + 'receipt_url': PAYMENT_PROCESSOR_RECEIPT_PATH, }, }, } diff --git a/ecommerce/settings/local.py b/ecommerce/settings/local.py index f825ab29cf7..8ea6e58e502 100644 --- a/ecommerce/settings/local.py +++ b/ecommerce/settings/local.py @@ -133,10 +133,13 @@ 'error_path': PAYMENT_PROCESSOR_ERROR_PATH, }, 'stripe': { - 'publishable_key': 'fake-publishable-key', - 'secret_key': 'fake-secret-key', - 'country': 'US', - 'apple_pay_merchant_id_domain_association': '7B227073704964223A2239373943394538343346343131343044463144313834343232393232313734313034353044314339464446394437384337313531303944334643463542433731222C2276657273696F6E223A312C22637265617465644F6E223A313437313435343137313137362C227369676E6174757265223A2233303830303630393261383634383836663730643031303730326130383033303830303230313031333130663330306430363039363038363438303136353033303430323031303530303330383030363039326138363438383666373064303130373031303030306130383033303832303365363330383230333862613030333032303130323032303836383630663639396439636361373066333030613036303832613836343863653364303430333032333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303165313730643331333633303336333033333331333833313336333433303561313730643332333133303336333033323331333833313336333433303561333036323331323833303236303630333535303430333063316636353633363332643733366437303264363237323666366236353732326437333639363736653566353534333334326435333431346534343432346635383331313433303132303630333535303430623063306236393466353332303533373937333734363536643733333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303539333031333036303732613836343863653364303230313036303832613836343863653364303330313037303334323030303438323330666461626333396366373565323032633530643939623435313265363337653261393031646436636233653062316364346235323637393866386366346562646538316132356138633231653463333364646365386532613936633266366166613139333033343563346538376134343236636539353162313239356133383230323131333038323032306433303435303630383262303630313035303530373031303130343339333033373330333530363038326230363031303530353037333030313836323936383734373437303361326632663666363337333730326536313730373036633635326536333666366432663666363337333730333033343264363137303730366336353631363936333631333333303332333031643036303335353164306530343136303431343032323433303062396165656564343633313937613461363561323939653432373138323163343533303063303630333535316431333031303166663034303233303030333031663036303335353164323330343138333031363830313432336632343963343466393365346566323765366334663632383663336661326262666432653462333038323031316430363033353531643230303438323031313433303832303131303330383230313063303630393261383634383836663736333634303530313330383166653330383163333036303832623036303130353035303730323032333038316236306338316233353236353663363936313665363336353230366636653230373436383639373332303633363537323734363936363639363336313734363532303632373932303631366537393230373036313732373437393230363137333733373536643635373332303631363336333635373037343631366536333635323036663636323037343638363532303734363836353665323036313730373036633639363336313632366336353230373337343631366536343631373236343230373436353732366437333230363136653634323036333666366536343639373436393666366537333230366636363230373537333635326332303633363537323734363936363639363336313734363532303730366636633639363337393230363136653634323036333635373237343639363636393633363137343639366636653230373037323631363337343639363336353230373337343631373436353664363536653734373332653330333630363038326230363031303530353037303230313136326136383734373437303361326632663737373737373265363137303730366336353265363336663664326636333635373237343639363636393633363137343635363137353734363836663732363937343739326633303334303630333535316431663034326433303262333032396130323761303235383632333638373437343730336132663266363337323663326536313730373036633635326536333666366432663631373037303663363536313639363336313333326536333732366333303065303630333535316430663031303166663034303430333032303738303330306630363039326138363438383666373633363430363164303430323035303033303061303630383261383634386365336430343033303230333439303033303436303232313030646131633633616538626535663634663865313165383635363933376239623639633437326265393365616333323333613136373933366534613864356538333032323130306264356166626638363966336330636132373462326664646534663731373135396362336264373139396232636130666634303964653635396138326232346433303832303265653330383230323735613030333032303130323032303834393664326662663361393864613937333030613036303832613836343863653364303430333032333036373331316233303139303630333535303430333063313234313730373036633635323035323666366637343230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313334333033353330333633323333333433363333333035613137306433323339333033353330333633323333333433363333333035613330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034663031373131383431396437363438356435316135653235383130373736653838306132656664653762616534646530386466633462393365313333353664353636356233356165323264303937373630643232346537626261303866643736313763653838636237366262363637306265633865383239383466663534343561333831663733303831663433303436303630383262303630313035303530373031303130343361333033383330333630363038326230363031303530353037333030313836326136383734373437303361326632663666363337333730326536313730373036633635326536333666366432663666363337333730333033343264363137303730366336353732366636663734363336313637333333303164303630333535316430653034313630343134323366323439633434663933653465663237653663346636323836633366613262626664326534623330306630363033353531643133303130316666303430353330303330313031666633303166303630333535316432333034313833303136383031346262623064656131353833333838396161343861393964656265626465626166646163623234616233303337303630333535316431663034333033303265333032636130326161303238383632363638373437343730336132663266363337323663326536313730373036633635326536333666366432663631373037303663363537323666366637343633363136373333326536333732366333303065303630333535316430663031303166663034303430333032303130363330313030363061326138363438383666373633363430363032306530343032303530303330306130363038326138363438636533643034303330323033363730303330363430323330336163663732383335313136393962313836666233356333353663613632626666343137656464393066373534646132386562656631396338313565343262373839663839386637396235393966393864353431306438663964653963326665303233303332326464353434323162306133303537373663356466333338336239303637666431373763326332313664393634666336373236393832313236663534663837613764316239396362396230393839323136313036393930663039393231643030303033313832303136303330383230313563303230313031333038313836333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353330323038363836306636393964396363613730663330306430363039363038363438303136353033303430323031303530306130363933303138303630393261383634383836663730643031303930333331306230363039326138363438383666373064303130373031333031633036303932613836343838366637306430313039303533313066313730643331333633303338333133373331333733313336333133313561333032663036303932613836343838366637306430313039303433313232303432303733343832623432653665366332323264616536643963303961346336663332316534656136653666326661626631356430376562333338643264613435646233303061303630383261383634386365336430343033303230343438333034363032323130306564333264376438616131623536623036626164623162396639396264643063653662363931316530623032393232633934333362663564326130656135353830323231303066393433353637663030323361643061343561373236663238376636303062656334666566373335383832383935633733313531383337336163383934383137303030303030303030303030227D', + 'api_version': '2022-08-01; server_side_confirmation_beta=v1', + 'enable_telemetry': None, + 'log_level': 'debug', + 'max_network_retries': 0, + 'proxy': None, + 'publishable_key': 'SET-ME-PLEASE', + 'secret_key': 'SET-ME-PLEASE', }, }, } diff --git a/ecommerce/settings/test.py b/ecommerce/settings/test.py index d2cad8189bc..84b059041dc 100644 --- a/ecommerce/settings/test.py +++ b/ecommerce/settings/test.py @@ -90,10 +90,16 @@ }, 'invoice': {}, 'stripe': { + 'api_version': '2022-08-01; server_side_confirmation_beta=v1', + 'enable_telemetry': None, + 'log_level': 'debug', + 'max_network_retries': 0, + 'proxy': None, 'publishable_key': 'fake-publishable-key', 'secret_key': 'fake-secret-key', - 'country': 'US', - 'apple_pay_merchant_id_domain_association': None, + 'error_path': PAYMENT_PROCESSOR_ERROR_PATH, + 'cancel_checkout_path': PAYMENT_PROCESSOR_CANCEL_PATH, + 'receipt_url': PAYMENT_PROCESSOR_RECEIPT_PATH, }, }, 'other': { @@ -123,10 +129,16 @@ }, 'invoice': {}, 'stripe': { - 'publishable_key': 'other-fake-publishable-key', - 'secret_key': 'other-fake-secret-key', - 'country': 'US', - 'apple_pay_merchant_id_domain_association': '7B227073704964223A2239373943394538343346343131343044463144313834343232393232313734313034353044314339464446394437384337313531303944334643463542433731222C2276657273696F6E223A312C22637265617465644F6E223A313437313435343137313137362C227369676E6174757265223A2233303830303630393261383634383836663730643031303730326130383033303830303230313031333130663330306430363039363038363438303136353033303430323031303530303330383030363039326138363438383666373064303130373031303030306130383033303832303365363330383230333862613030333032303130323032303836383630663639396439636361373066333030613036303832613836343863653364303430333032333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303165313730643331333633303336333033333331333833313336333433303561313730643332333133303336333033323331333833313336333433303561333036323331323833303236303630333535303430333063316636353633363332643733366437303264363237323666366236353732326437333639363736653566353534333334326435333431346534343432346635383331313433303132303630333535303430623063306236393466353332303533373937333734363536643733333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353333303539333031333036303732613836343863653364303230313036303832613836343863653364303330313037303334323030303438323330666461626333396366373565323032633530643939623435313265363337653261393031646436636233653062316364346235323637393866386366346562646538316132356138633231653463333364646365386532613936633266366166613139333033343563346538376134343236636539353162313239356133383230323131333038323032306433303435303630383262303630313035303530373031303130343339333033373330333530363038326230363031303530353037333030313836323936383734373437303361326632663666363337333730326536313730373036633635326536333666366432663666363337333730333033343264363137303730366336353631363936333631333333303332333031643036303335353164306530343136303431343032323433303062396165656564343633313937613461363561323939653432373138323163343533303063303630333535316431333031303166663034303233303030333031663036303335353164323330343138333031363830313432336632343963343466393365346566323765366334663632383663336661326262666432653462333038323031316430363033353531643230303438323031313433303832303131303330383230313063303630393261383634383836663736333634303530313330383166653330383163333036303832623036303130353035303730323032333038316236306338316233353236353663363936313665363336353230366636653230373436383639373332303633363537323734363936363639363336313734363532303632373932303631366537393230373036313732373437393230363137333733373536643635373332303631363336333635373037343631366536333635323036663636323037343638363532303734363836353665323036313730373036633639363336313632366336353230373337343631366536343631373236343230373436353732366437333230363136653634323036333666366536343639373436393666366537333230366636363230373537333635326332303633363537323734363936363639363336313734363532303730366636633639363337393230363136653634323036333635373237343639363636393633363137343639366636653230373037323631363337343639363336353230373337343631373436353664363536653734373332653330333630363038326230363031303530353037303230313136326136383734373437303361326632663737373737373265363137303730366336353265363336663664326636333635373237343639363636393633363137343635363137353734363836663732363937343739326633303334303630333535316431663034326433303262333032396130323761303235383632333638373437343730336132663266363337323663326536313730373036633635326536333666366432663631373037303663363536313639363336313333326536333732366333303065303630333535316430663031303166663034303430333032303738303330306630363039326138363438383666373633363430363164303430323035303033303061303630383261383634386365336430343033303230333439303033303436303232313030646131633633616538626535663634663865313165383635363933376239623639633437326265393365616333323333613136373933366534613864356538333032323130306264356166626638363966336330636132373462326664646534663731373135396362336264373139396232636130666634303964653635396138326232346433303832303265653330383230323735613030333032303130323032303834393664326662663361393864613937333030613036303832613836343863653364303430333032333036373331316233303139303630333535303430333063313234313730373036633635323035323666366637343230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313334333033353330333633323333333433363333333035613137306433323339333033353330333633323333333433363333333035613330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034663031373131383431396437363438356435316135653235383130373736653838306132656664653762616534646530386466633462393365313333353664353636356233356165323264303937373630643232346537626261303866643736313763653838636237366262363637306265633865383239383466663534343561333831663733303831663433303436303630383262303630313035303530373031303130343361333033383330333630363038326230363031303530353037333030313836326136383734373437303361326632663666363337333730326536313730373036633635326536333666366432663666363337333730333033343264363137303730366336353732366636663734363336313637333333303164303630333535316430653034313630343134323366323439633434663933653465663237653663346636323836633366613262626664326534623330306630363033353531643133303130316666303430353330303330313031666633303166303630333535316432333034313833303136383031346262623064656131353833333838396161343861393964656265626465626166646163623234616233303337303630333535316431663034333033303265333032636130326161303238383632363638373437343730336132663266363337323663326536313730373036633635326536333666366432663631373037303663363537323666366637343633363136373333326536333732366333303065303630333535316430663031303166663034303430333032303130363330313030363061326138363438383666373633363430363032306530343032303530303330306130363038326138363438636533643034303330323033363730303330363430323330336163663732383335313136393962313836666233356333353663613632626666343137656464393066373534646132386562656631396338313565343262373839663839386637396235393966393864353431306438663964653963326665303233303332326464353434323162306133303537373663356466333338336239303637666431373763326332313664393634666336373236393832313236663534663837613764316239396362396230393839323136313036393930663039393231643030303033313832303136303330383230313563303230313031333038313836333037613331326533303263303630333535303430333063323534313730373036633635323034313730373036633639363336313734363936663665323034393665373436353637373236313734363936663665323034333431323032643230343733333331323633303234303630333535303430623063316434313730373036633635323034333635373237343639363636393633363137343639366636653230343137353734363836663732363937343739333131333330313130363033353530343061306330613431373037303663363532303439366536333265333130623330303930363033353530343036313330323535353330323038363836306636393964396363613730663330306430363039363038363438303136353033303430323031303530306130363933303138303630393261383634383836663730643031303930333331306230363039326138363438383666373064303130373031333031633036303932613836343838366637306430313039303533313066313730643331333633303338333133373331333733313336333133313561333032663036303932613836343838366637306430313039303433313232303432303733343832623432653665366332323264616536643963303961346336663332316534656136653666326661626631356430376562333338643264613435646233303061303630383261383634386365336430343033303230343438333034363032323130306564333264376438616131623536623036626164623162396639396264643063653662363931316530623032393232633934333362663564326130656135353830323231303066393433353637663030323361643061343561373236663238376636303062656334666566373335383832383935633733313531383337336163383934383137303030303030303030303030227D', + 'api_version': '2022-08-01; server_side_confirmation_beta=v1', + 'enable_telemetry': None, + 'log_level': 'debug', + 'max_network_retries': 0, + 'proxy': None, + 'publishable_key': 'fake-publishable-key', + 'secret_key': 'fake-secret-key', + 'error_path': PAYMENT_PROCESSOR_ERROR_PATH, + 'cancel_checkout_path': PAYMENT_PROCESSOR_CANCEL_PATH, + 'receipt_url': PAYMENT_PROCESSOR_RECEIPT_PATH, }, } } diff --git a/requirements/base.in b/requirements/base.in index f5ff4f62c61..7bc96cfd8eb 100755 --- a/requirements/base.in +++ b/requirements/base.in @@ -52,7 +52,7 @@ rules simplejson social-auth-app-django sorl-thumbnail -stripe==1.70.0 +stripe unicodecsv xss-utils zeep diff --git a/requirements/base.txt b/requirements/base.txt index 946ad00b0ab..addb106a814 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -22,7 +22,7 @@ babel==2.10.3 # via django-oscar backoff==1.10.0 # via analytics-python -bcrypt==3.2.2 +bcrypt==4.0.0 # via # cybersource-rest-client-python # paramiko @@ -30,9 +30,9 @@ billiard==3.6.4.0 # via celery bleach==5.0.1 # via -r requirements/base.in -boto3==1.24.49 +boto3==1.24.73 # via -r requirements/base.in -botocore==1.27.49 +botocore==1.27.73 # via # boto3 # s3transfer @@ -42,23 +42,22 @@ celery==4.4.7 # via # -c requirements/constraints.txt # edx-ecommerce-worker -certifi==2022.6.15 +certifi==2022.9.14 # via # cybersource-rest-client-python # requests cffi==1.15.1 # via - # bcrypt # cryptography # cybersource-rest-client-python # pynacl chardet==5.0.0 # via cybersource-rest-client-python -charset-normalizer==2.1.0 +charset-normalizer==2.1.1 # via requests click==8.1.3 # via edx-django-utils -configparser==5.2.0 +configparser==5.3.0 # via cybersource-rest-client-python coreapi==2.3.3 # via @@ -68,11 +67,11 @@ coreschema==0.0.4 # via # coreapi # drf-yasg -coverage==6.4.3 +coverage==6.4.4 # via cybersource-rest-client-python crypto==1.4.1 # via cybersource-rest-client-python -cryptography==37.0.4 +cryptography==38.0.1 # via # cybersource-rest-client-python # paramiko @@ -81,13 +80,13 @@ cryptography==37.0.4 # social-auth-core cssselect==1.1.0 # via premailer -cssutils==2.5.1 +cssutils==2.6.0 # via premailer cybersource-rest-client-python==0.0.21 # via # -c requirements/constraints.txt # -r requirements/base.in -datetime==4.5 +datetime==4.7 # via cybersource-rest-client-python defusedxml==0.7.1 # via @@ -141,7 +140,7 @@ django-crum==0.7.9 # via # edx-django-utils # edx-rbac -django-extensions==3.2.0 +django-extensions==3.2.1 # via -r requirements/base.in django-extra-views==0.13.0 # via django-oscar @@ -171,7 +170,7 @@ django-threadlocals==0.10 # via -r requirements/base.in django-treebeard==4.4 # via django-oscar -django-waffle==2.6.0 +django-waffle==3.0.0 # via # -r requirements/base.in # edx-django-utils @@ -211,7 +210,7 @@ edx-django-release-util==1.2.0 # via -r requirements/base.in edx-django-sites-extensions==4.0.0 # via -r requirements/base.in -edx-django-utils==5.0.0 +edx-django-utils==5.0.1 # via # -r requirements/base.in # django-config-models @@ -244,7 +243,7 @@ extras==1.0.0 # testtools factory-boy==2.12.0 # via django-oscar -faker==13.15.1 +faker==14.2.0 # via factory-boy fixtures==4.0.1 # via @@ -279,7 +278,7 @@ jmespath==1.0.1 # botocore jsonfield==3.1.0 # via -r requirements/base.in -jsonschema==4.9.1 +jsonschema==4.16.0 # via cybersource-rest-client-python kombu==4.6.11 # via celery @@ -311,13 +310,13 @@ naked==0.1.31 # cybersource-rest-client-python ndg-httpsclient==0.5.1 # via -r requirements/base.in -newrelic==7.16.0.178 +newrelic==8.1.0.180 # via # -r requirements/base.in # edx-django-utils nose==1.3.7 # via cybersource-rest-client-python -oauthlib==3.2.0 +oauthlib==3.2.1 # via # getsmarter-api-clients # requests-oauthlib @@ -332,13 +331,13 @@ path-py==7.2 # via -r requirements/base.in paypalrestsdk==1.13.1 # via -r requirements/base.in -pbr==5.9.0 +pbr==5.10.0 # via # cybersource-rest-client-python # fixtures # stevedore # testtools -phonenumbers==8.12.53 +phonenumbers==8.12.55 # via django-oscar pillow==9.2.0 # via django-oscar @@ -348,7 +347,7 @@ platformdirs==2.5.2 # via zeep premailer==2.9.2 # via -r requirements/base.in -psutil==5.9.1 +psutil==5.9.2 # via edx-django-utils purl==1.6 # via django-oscar @@ -370,7 +369,7 @@ pycryptodomex==3.15.0 # via # cybersource-rest-client-python # pyjwkest -pygments==2.12.0 +pygments==2.13.0 # via -r requirements/base.in pyjwkest==1.4.2 # via edx-drf-extensions @@ -520,7 +519,7 @@ social-auth-core==4.0.2 # -c requirements/constraints.txt # edx-auth-backends # social-auth-app-django -sorl-thumbnail==12.8.0 +sorl-thumbnail==12.9.0 # via -r requirements/base.in sqlparse==0.4.2 # via django @@ -528,7 +527,7 @@ stevedore==4.0.0 # via # edx-django-utils # edx-opaque-keys -stripe==1.70.0 +stripe==4.1.0 # via -r requirements/base.in testtools==2.5.0 # via @@ -546,7 +545,7 @@ uritemplate==4.1.1 # via # coreapi # drf-yasg -urllib3==1.26.11 +urllib3==1.26.12 # via # -c requirements/constraints.txt # botocore diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt index cca3ccd308c..b1dfdf0176d 100644 --- a/requirements/common_constraints.txt +++ b/requirements/common_constraints.txt @@ -19,6 +19,8 @@ Django<4.0 # elastic search changelog: https://www.elastic.co/guide/en/enterprise-search/master/release-notes-7.14.0.html elasticsearch<7.14.0 +# setuptools==60.0 had breaking changes and busted several service's pipeline. +# Details can be found here: https://github.com/pypa/setuptools/issues/2940 setuptools<60 # django-simple-history>3.0.0 adds indexing and causes a lot of migrations to be affected diff --git a/requirements/dev.txt b/requirements/dev.txt index 0a1a5cec474..a376b76274c 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -46,7 +46,7 @@ backoff==1.10.0 # via # -r requirements/test.txt # analytics-python -bcrypt==3.2.2 +bcrypt==4.0.0 # via # -r requirements/test.txt # cybersource-rest-client-python @@ -63,9 +63,9 @@ bleach==5.0.1 # via -r requirements/test.txt bok-choy==1.1.1 # via -r requirements/test.txt -boto3==1.24.49 +boto3==1.24.73 # via -r requirements/test.txt -botocore==1.27.49 +botocore==1.27.73 # via # -r requirements/test.txt # boto3 @@ -78,7 +78,7 @@ celery==4.4.7 # via # -r requirements/test.txt # edx-ecommerce-worker -certifi==2022.6.15 +certifi==2022.9.14 # via # -r requirements/docs.txt # -r requirements/test.txt @@ -87,7 +87,6 @@ certifi==2022.6.15 cffi==1.15.1 # via # -r requirements/test.txt - # bcrypt # cryptography # cybersource-rest-client-python # pynacl @@ -96,7 +95,7 @@ chardet==5.0.0 # -r requirements/test.txt # cybersource-rest-client-python # diff-cover -charset-normalizer==2.1.0 +charset-normalizer==2.1.1 # via # -r requirements/docs.txt # -r requirements/test.txt @@ -105,7 +104,7 @@ click==8.1.3 # via # -r requirements/test.txt # edx-django-utils -configparser==5.2.0 +configparser==5.3.0 # via # -r requirements/test.txt # cybersource-rest-client-python @@ -118,7 +117,7 @@ coreschema==0.0.4 # -r requirements/test.txt # coreapi # drf-yasg -coverage[toml]==6.4.3 +coverage[toml]==6.4.4 # via # -r requirements/test.txt # cybersource-rest-client-python @@ -127,7 +126,7 @@ crypto==1.4.1 # via # -r requirements/test.txt # cybersource-rest-client-python -cryptography==37.0.4 +cryptography==38.0.1 # via # -r requirements/test.txt # cybersource-rest-client-python @@ -139,13 +138,13 @@ cssselect==1.1.0 # via # -r requirements/test.txt # premailer -cssutils==2.5.1 +cssutils==2.6.0 # via # -r requirements/test.txt # premailer cybersource-rest-client-python==0.0.21 # via -r requirements/test.txt -datetime==4.5 +datetime==4.7 # via # -r requirements/test.txt # cybersource-rest-client-python @@ -212,9 +211,9 @@ django-crum==0.7.9 # -r requirements/test.txt # edx-django-utils # edx-rbac -django-debug-toolbar==3.5.0 +django-debug-toolbar==3.6.0 # via -r requirements/dev.in -django-extensions==3.2.0 +django-extensions==3.2.1 # via -r requirements/test.txt django-extra-views==0.13.0 # via @@ -252,7 +251,7 @@ django-treebeard==4.4 # via # -r requirements/test.txt # django-oscar -django-waffle==2.6.0 +django-waffle==3.0.0 # via # -r requirements/test.txt # edx-django-utils @@ -300,7 +299,7 @@ edx-django-release-util==1.2.0 # via -r requirements/test.txt edx-django-sites-extensions==4.0.0 # via -r requirements/test.txt -edx-django-utils==5.0.0 +edx-django-utils==5.0.1 # via # -r requirements/test.txt # django-config-models @@ -341,7 +340,7 @@ factory-boy==2.12.0 # via # -r requirements/test.txt # django-oscar -faker==13.15.1 +faker==14.2.0 # via # -r requirements/test.txt # factory-boy @@ -354,7 +353,7 @@ fixtures==4.0.1 # -r requirements/test.txt # cybersource-rest-client-python # testtools -freezegun==1.2.1 +freezegun==1.2.2 # via -r requirements/test.txt funcsigs==1.0.2 # via @@ -428,7 +427,7 @@ jmespath==1.0.1 # botocore jsonfield==3.1.0 # via -r requirements/test.txt -jsonschema==4.9.1 +jsonschema==4.16.0 # via # -r requirements/test.txt # cybersource-rest-client-python @@ -488,7 +487,7 @@ naked==0.1.31 # cybersource-rest-client-python ndg-httpsclient==0.5.1 # via -r requirements/test.txt -newrelic==7.16.0.178 +newrelic==8.1.0.180 # via # -r requirements/test.txt # edx-django-utils @@ -496,7 +495,7 @@ nose==1.3.7 # via # -r requirements/test.txt # cybersource-rest-client-python -oauthlib==3.2.0 +oauthlib==3.2.1 # via # -r requirements/test.txt # getsmarter-api-clients @@ -523,14 +522,14 @@ path-py==7.2 # via -r requirements/test.txt paypalrestsdk==1.13.1 # via -r requirements/test.txt -pbr==5.9.0 +pbr==5.10.0 # via # -r requirements/test.txt # cybersource-rest-client-python # fixtures # stevedore # testtools -phonenumbers==8.12.53 +phonenumbers==8.12.55 # via # -r requirements/test.txt # django-oscar @@ -559,7 +558,7 @@ polib==1.1.1 # edx-i18n-tools premailer==2.9.2 # via -r requirements/test.txt -psutil==5.9.1 +psutil==5.9.2 # via # -r requirements/test.txt # edx-django-utils @@ -599,7 +598,7 @@ pycryptodomex==3.15.0 # -r requirements/test.txt # cybersource-rest-client-python # pyjwkest -pygments==2.12.0 +pygments==2.13.0 # via # -r requirements/docs.txt # -r requirements/test.txt @@ -694,7 +693,7 @@ python-dateutil==2.8.2 # edx-drf-extensions # faker # freezegun -python-dotenv==0.20.0 +python-dotenv==0.21.0 # via -r requirements/test.txt python-memcached==1.59 # via -r requirements/test.txt @@ -876,7 +875,7 @@ social-auth-core==4.0.2 # -r requirements/test.txt # edx-auth-backends # social-auth-app-django -sorl-thumbnail==12.8.0 +sorl-thumbnail==12.9.0 # via -r requirements/test.txt soupsieve==2.3.2.post1 # via @@ -920,7 +919,7 @@ stevedore==4.0.0 # -r requirements/test.txt # edx-django-utils # edx-opaque-keys -stripe==1.70.0 +stripe==4.1.0 # via -r requirements/test.txt tenacity==6.3.1 # via @@ -975,7 +974,7 @@ uritemplate==4.1.1 # -r requirements/test.txt # coreapi # drf-yasg -urllib3==1.26.11 +urllib3==1.26.12 # via # -r requirements/docs.txt # -r requirements/test.txt diff --git a/requirements/docs.txt b/requirements/docs.txt index 4c425eff232..4d8ba7517ac 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -8,9 +8,9 @@ alabaster==0.7.12 # via sphinx babel==2.10.3 # via sphinx -certifi==2022.6.15 +certifi==2022.9.14 # via requests -charset-normalizer==2.1.0 +charset-normalizer==2.1.1 # via requests docutils==0.19 # via sphinx @@ -30,7 +30,7 @@ markupsafe==2.1.1 # via jinja2 packaging==21.3 # via sphinx -pygments==2.12.0 +pygments==2.13.0 # via sphinx pyparsing==3.0.9 # via packaging @@ -60,7 +60,7 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -urllib3==1.26.11 +urllib3==1.26.12 # via # -c requirements/constraints.txt # requests diff --git a/requirements/e2e.txt b/requirements/e2e.txt index 9174f3d2c46..4468e710125 100644 --- a/requirements/e2e.txt +++ b/requirements/e2e.txt @@ -12,7 +12,7 @@ attrs==22.1.0 # via # -c requirements/base.txt # pytest -certifi==2022.6.15 +certifi==2022.9.14 # via # -c requirements/base.txt # requests @@ -21,7 +21,7 @@ cffi==1.15.1 # -c requirements/base.txt # cryptography # pynacl -charset-normalizer==2.1.0 +charset-normalizer==2.1.1 # via # -c requirements/base.txt # requests @@ -29,7 +29,7 @@ click==8.1.3 # via # -c requirements/base.txt # edx-django-utils -cryptography==37.0.4 +cryptography==38.0.1 # via # -c requirements/base.txt # pyjwt @@ -43,11 +43,11 @@ django-crum==0.7.9 # via # -c requirements/base.txt # edx-django-utils -django-waffle==2.6.0 +django-waffle==3.0.0 # via # -c requirements/base.txt # edx-django-utils -edx-django-utils==5.0.0 +edx-django-utils==5.0.1 # via # -c requirements/base.txt # edx-rest-api-client @@ -64,7 +64,7 @@ importlib-metadata==4.12.0 # via pytest-randomly iniconfig==1.1.1 # via pytest -newrelic==7.16.0.178 +newrelic==8.1.0.180 # via # -c requirements/base.txt # edx-django-utils @@ -72,7 +72,7 @@ packaging==21.3 # via # -c requirements/base.txt # pytest -pbr==5.9.0 +pbr==5.10.0 # via # -c requirements/base.txt # stevedore @@ -80,7 +80,7 @@ pluggy==0.13.1 # via # -c requirements/constraints.txt # pytest -psutil==5.9.1 +psutil==5.9.2 # via # -c requirements/base.txt # edx-django-utils @@ -126,7 +126,7 @@ pytest-timeout==2.1.0 # via -r requirements/e2e.in pytest-variables==1.9.0 # via pytest-selenium -python-dotenv==0.20.0 +python-dotenv==0.21.0 # via -r requirements/e2e.in pytz==2016.10 # via @@ -165,7 +165,7 @@ tenacity==6.3.1 # via pytest-selenium toml==0.10.2 # via pytest -urllib3==1.26.11 +urllib3==1.26.12 # via # -c requirements/base.txt # -c requirements/constraints.txt diff --git a/requirements/production.txt b/requirements/production.txt index dfa78adca09..3b42a4be9d5 100644 --- a/requirements/production.txt +++ b/requirements/production.txt @@ -22,7 +22,7 @@ babel==2.10.3 # via django-oscar backoff==1.10.0 # via analytics-python -bcrypt==3.2.2 +bcrypt==4.0.0 # via # cybersource-rest-client-python # paramiko @@ -30,11 +30,11 @@ billiard==3.6.4.0 # via celery bleach==5.0.1 # via -r requirements/base.in -boto3==1.24.49 +boto3==1.24.73 # via # -r requirements/base.in # django-ses -botocore==1.27.49 +botocore==1.27.73 # via # boto3 # s3transfer @@ -44,23 +44,22 @@ celery==4.4.7 # via # -c requirements/constraints.txt # edx-ecommerce-worker -certifi==2022.6.15 +certifi==2022.9.14 # via # cybersource-rest-client-python # requests cffi==1.15.1 # via - # bcrypt # cryptography # cybersource-rest-client-python # pynacl chardet==5.0.0 # via cybersource-rest-client-python -charset-normalizer==2.1.0 +charset-normalizer==2.1.1 # via requests click==8.1.3 # via edx-django-utils -configparser==5.2.0 +configparser==5.3.0 # via cybersource-rest-client-python coreapi==2.3.3 # via @@ -70,11 +69,11 @@ coreschema==0.0.4 # via # coreapi # drf-yasg -coverage==6.4.3 +coverage==6.4.4 # via cybersource-rest-client-python crypto==1.4.1 # via cybersource-rest-client-python -cryptography==37.0.4 +cryptography==38.0.1 # via # cybersource-rest-client-python # paramiko @@ -83,13 +82,13 @@ cryptography==37.0.4 # social-auth-core cssselect==1.1.0 # via premailer -cssutils==2.5.1 +cssutils==2.6.0 # via premailer cybersource-rest-client-python==0.0.21 # via # -c requirements/constraints.txt # -r requirements/base.in -datetime==4.5 +datetime==4.7 # via cybersource-rest-client-python defusedxml==0.7.1 # via @@ -144,7 +143,7 @@ django-crum==0.7.9 # via # edx-django-utils # edx-rbac -django-extensions==3.2.0 +django-extensions==3.2.1 # via -r requirements/base.in django-extra-views==0.13.0 # via django-oscar @@ -162,7 +161,7 @@ django-oscar==2.2 # -r requirements/base.in django-phonenumber-field==5.0.0 # via django-oscar -django-ses==3.1.0 +django-ses==3.1.2 # via -r requirements/production.in django-simple-history==3.0.0 # via @@ -176,7 +175,7 @@ django-threadlocals==0.10 # via -r requirements/base.in django-treebeard==4.4 # via django-oscar -django-waffle==2.6.0 +django-waffle==3.0.0 # via # -r requirements/base.in # edx-django-utils @@ -216,7 +215,7 @@ edx-django-release-util==1.2.0 # via -r requirements/base.in edx-django-sites-extensions==4.0.0 # via -r requirements/base.in -edx-django-utils==5.0.0 +edx-django-utils==5.0.1 # via # -r requirements/base.in # django-config-models @@ -249,7 +248,7 @@ extras==1.0.0 # testtools factory-boy==2.12.0 # via django-oscar -faker==13.15.1 +faker==14.2.0 # via factory-boy fixtures==4.0.1 # via @@ -286,7 +285,7 @@ jmespath==1.0.1 # botocore jsonfield==3.1.0 # via -r requirements/base.in -jsonschema==4.9.1 +jsonschema==4.16.0 # via cybersource-rest-client-python kombu==4.6.11 # via celery @@ -327,7 +326,7 @@ nodeenv==1.1.1 # via -r requirements/production.in nose==1.3.7 # via cybersource-rest-client-python -oauthlib==3.2.0 +oauthlib==3.2.1 # via # getsmarter-api-clients # requests-oauthlib @@ -342,13 +341,13 @@ path-py==7.2 # via -r requirements/base.in paypalrestsdk==1.13.1 # via -r requirements/base.in -pbr==5.9.0 +pbr==5.10.0 # via # cybersource-rest-client-python # fixtures # stevedore # testtools -phonenumbers==8.12.53 +phonenumbers==8.12.55 # via django-oscar pillow==9.2.0 # via django-oscar @@ -358,7 +357,7 @@ platformdirs==2.5.2 # via zeep premailer==2.9.2 # via -r requirements/base.in -psutil==5.9.1 +psutil==5.9.2 # via edx-django-utils purl==1.6 # via django-oscar @@ -380,7 +379,7 @@ pycryptodomex==3.15.0 # via # cybersource-rest-client-python # pyjwkest -pygments==2.12.0 +pygments==2.13.0 # via -r requirements/base.in pyjwkest==1.4.2 # via edx-drf-extensions @@ -537,7 +536,7 @@ social-auth-core==4.0.2 # -c requirements/constraints.txt # edx-auth-backends # social-auth-app-django -sorl-thumbnail==12.8.0 +sorl-thumbnail==12.9.0 # via -r requirements/base.in sqlparse==0.4.2 # via django @@ -545,7 +544,7 @@ stevedore==4.0.0 # via # edx-django-utils # edx-opaque-keys -stripe==1.70.0 +stripe==4.1.0 # via -r requirements/base.in testtools==2.5.0 # via @@ -563,7 +562,7 @@ uritemplate==4.1.1 # via # coreapi # drf-yasg -urllib3==1.26.11 +urllib3==1.26.12 # via # -c requirements/constraints.txt # botocore diff --git a/requirements/test.txt b/requirements/test.txt index 0ebd7d810cd..9c2f5a6a8e0 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -40,7 +40,7 @@ backoff==1.10.0 # via # -r requirements/base.txt # analytics-python -bcrypt==3.2.2 +bcrypt==4.0.0 # via # -r requirements/base.txt # cybersource-rest-client-python @@ -55,9 +55,9 @@ bleach==5.0.1 # via -r requirements/base.txt bok-choy==1.1.1 # via -r requirements/test.in -boto3==1.24.49 +boto3==1.24.73 # via -r requirements/base.txt -botocore==1.27.49 +botocore==1.27.73 # via # -r requirements/base.txt # boto3 @@ -71,7 +71,7 @@ celery==4.4.7 # -c requirements/constraints.txt # -r requirements/base.txt # edx-ecommerce-worker -certifi==2022.6.15 +certifi==2022.9.14 # via # -r requirements/base.txt # -r requirements/e2e.txt @@ -81,7 +81,6 @@ cffi==1.15.1 # via # -r requirements/base.txt # -r requirements/e2e.txt - # bcrypt # cryptography # cybersource-rest-client-python # pynacl @@ -90,7 +89,7 @@ chardet==5.0.0 # -r requirements/base.txt # cybersource-rest-client-python # diff-cover -charset-normalizer==2.1.0 +charset-normalizer==2.1.1 # via # -r requirements/base.txt # -r requirements/e2e.txt @@ -100,7 +99,7 @@ click==8.1.3 # -r requirements/base.txt # -r requirements/e2e.txt # edx-django-utils -configparser==5.2.0 +configparser==5.3.0 # via # -r requirements/base.txt # cybersource-rest-client-python @@ -113,7 +112,7 @@ coreschema==0.0.4 # -r requirements/base.txt # coreapi # drf-yasg -coverage[toml]==6.4.3 +coverage[toml]==6.4.4 # via # -r requirements/base.txt # -r requirements/test.in @@ -123,7 +122,7 @@ crypto==1.4.1 # via # -r requirements/base.txt # cybersource-rest-client-python -cryptography==37.0.4 +cryptography==38.0.1 # via # -r requirements/base.txt # -r requirements/e2e.txt @@ -136,7 +135,7 @@ cssselect==1.1.0 # via # -r requirements/base.txt # premailer -cssutils==2.5.1 +cssutils==2.6.0 # via # -r requirements/base.txt # premailer @@ -144,7 +143,7 @@ cybersource-rest-client-python==0.0.21 # via # -c requirements/constraints.txt # -r requirements/base.txt -datetime==4.5 +datetime==4.7 # via # -r requirements/base.txt # cybersource-rest-client-python @@ -212,7 +211,7 @@ django-crum==0.7.9 # -r requirements/e2e.txt # edx-django-utils # edx-rbac -django-extensions==3.2.0 +django-extensions==3.2.1 # via -r requirements/base.txt django-extra-views==0.13.0 # via @@ -254,7 +253,7 @@ django-treebeard==4.4 # via # -r requirements/base.txt # django-oscar -django-waffle==2.6.0 +django-waffle==3.0.0 # via # -r requirements/base.txt # -r requirements/e2e.txt @@ -303,7 +302,7 @@ edx-django-release-util==1.2.0 # via -r requirements/base.txt edx-django-sites-extensions==4.0.0 # via -r requirements/base.txt -edx-django-utils==5.0.0 +edx-django-utils==5.0.1 # via # -r requirements/base.txt # -r requirements/e2e.txt @@ -346,7 +345,7 @@ factory-boy==2.12.0 # -r requirements/base.txt # -r requirements/test.in # django-oscar -faker==13.15.1 +faker==14.2.0 # via # -r requirements/base.txt # factory-boy @@ -359,7 +358,7 @@ fixtures==4.0.1 # -r requirements/base.txt # cybersource-rest-client-python # testtools -freezegun==1.2.1 +freezegun==1.2.2 # via -r requirements/test.in funcsigs==1.0.2 # via @@ -422,7 +421,7 @@ jmespath==1.0.1 # botocore jsonfield==3.1.0 # via -r requirements/base.txt -jsonschema==4.9.1 +jsonschema==4.16.0 # via # -r requirements/base.txt # cybersource-rest-client-python @@ -478,7 +477,7 @@ naked==0.1.31 # cybersource-rest-client-python ndg-httpsclient==0.5.1 # via -r requirements/base.txt -newrelic==7.16.0.178 +newrelic==8.1.0.180 # via # -r requirements/base.txt # -r requirements/e2e.txt @@ -487,7 +486,7 @@ nose==1.3.7 # via # -r requirements/base.txt # cybersource-rest-client-python -oauthlib==3.2.0 +oauthlib==3.2.1 # via # -r requirements/base.txt # getsmarter-api-clients @@ -512,7 +511,7 @@ path-py==7.2 # via -r requirements/base.txt paypalrestsdk==1.13.1 # via -r requirements/base.txt -pbr==5.9.0 +pbr==5.10.0 # via # -r requirements/base.txt # -r requirements/e2e.txt @@ -520,7 +519,7 @@ pbr==5.9.0 # fixtures # stevedore # testtools -phonenumbers==8.12.53 +phonenumbers==8.12.55 # via # -r requirements/base.txt # django-oscar @@ -549,7 +548,7 @@ polib==1.1.1 # via edx-i18n-tools premailer==2.9.2 # via -r requirements/base.txt -psutil==5.9.1 +psutil==5.9.2 # via # -r requirements/base.txt # -r requirements/e2e.txt @@ -590,7 +589,7 @@ pycryptodomex==3.15.0 # -r requirements/base.txt # cybersource-rest-client-python # pyjwkest -pygments==2.12.0 +pygments==2.13.0 # via # -r requirements/base.txt # diff-cover @@ -689,7 +688,7 @@ python-dateutil==2.8.2 # edx-drf-extensions # faker # freezegun -python-dotenv==0.20.0 +python-dotenv==0.21.0 # via -r requirements/e2e.txt python-memcached==1.59 # via -r requirements/test.in @@ -864,7 +863,7 @@ social-auth-core==4.0.2 # -r requirements/base.txt # edx-auth-backends # social-auth-app-django -sorl-thumbnail==12.8.0 +sorl-thumbnail==12.9.0 # via -r requirements/base.txt soupsieve==2.3.2.post1 # via beautifulsoup4 @@ -879,7 +878,7 @@ stevedore==4.0.0 # -r requirements/e2e.txt # edx-django-utils # edx-opaque-keys -stripe==1.70.0 +stripe==4.1.0 # via -r requirements/base.txt tenacity==6.3.1 # via @@ -929,7 +928,7 @@ uritemplate==4.1.1 # -r requirements/base.txt # coreapi # drf-yasg -urllib3==1.26.11 +urllib3==1.26.12 # via # -c requirements/constraints.txt # -r requirements/base.txt From c2c3e164255dd636ce25ec39e1d12fd7683ec516 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Nov 2022 14:07:36 +0000 Subject: [PATCH 2/2] build(deps): bump minimist and karma Bumps [minimist](https://github.com/minimistjs/minimist) to 1.2.6 and updates ancestor dependency [karma](https://github.com/karma-runner/karma). These dependencies need to be updated together. Updates `minimist` from 0.0.10 to 1.2.6 - [Release notes](https://github.com/minimistjs/minimist/releases) - [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md) - [Commits](https://github.com/minimistjs/minimist/compare/v0.0.10...v1.2.6) Updates `karma` from 1.5.0 to 6.4.1 - [Release notes](https://github.com/karma-runner/karma/releases) - [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md) - [Commits](https://github.com/karma-runner/karma/compare/v1.5.0...v6.4.1) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect - dependency-name: karma dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- package-lock.json | 2918 +++++++++++++++++---------------------------- package.json | 2 +- 2 files changed, 1066 insertions(+), 1854 deletions(-) diff --git a/package-lock.json b/package-lock.json index 495302632fa..1197abd6da3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "gulp-eslint": "3.0.1", "jasmine-core": "2.6.1", "jasmine-jquery": "2.1.1", - "karma": "1.5.0", + "karma": "6.4.1", "karma-chrome-launcher": "2.2.0", "karma-coverage": "1.1.1", "karma-coverage-allsources": "0.0.4", @@ -34,12 +34,45 @@ "sinon": "2.3.8" } }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, + "node_modules/@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", + "dev": true + }, "node_modules/abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", @@ -47,13 +80,13 @@ "dev": true }, "node_modules/accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha512-AOPopplFOUlmUugwiZUCDpOwmqvSgdCyE8iJVLWI4NcB7qfMKQN34dn5xYtlUU03XGG5egRWW4NW5gIxpa5hEA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { - "mime-types": "~2.1.11", - "negotiator": "0.6.1" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { "node": ">= 0.6" @@ -101,12 +134,6 @@ "node": ">=0.3.0" } }, - "node_modules/after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==", - "dev": true - }, "node_modules/ajv": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", @@ -400,15 +427,6 @@ "node": ">=0.10.0" } }, - "node_modules/array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha512-rlVfZW/1Ph2SNySXwR9QYkChp8EkOEiTMO5Vwx60usw04i4nWemkm9RXmQqgkQFaLHsqLuADvjp6IfgL9l2M8Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-sort": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", @@ -459,12 +477,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/arraybuffer.slice": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", - "integrity": "sha512-6ZjfQaBSy6CuIH0+B0NrxMfDE5VIOCP/5gOqSpEIsaAZx9/giszzrXg6PZ7G51U/n88UmlAgYLNQ9wAnII7PJA==", - "dev": true - }, "node_modules/assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -556,12 +568,6 @@ "node": ">= 0.10" } }, - "node_modules/backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", - "dev": true - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -598,22 +604,13 @@ "node": ">=0.10.0" } }, - "node_modules/base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha512-437oANT9tP582zZMwSvZGy2nmSeAb8DW2me3y+Uv1Wp2Rulr8Mqlyrv3E7MLxmsiaPSMMDmiDVzgE+e8zlMx9g==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha512-rz8L+d/xByiB/vLVftPkyY215fqNrmasrcJsYkVcm4TgJNz+YXKrFaFAWibSaHkiKoSgMDCb+lipOIRQNGYesw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "dev": true, "engines": { - "node": ">= 0.4.0" + "node": "^4.5.0 || >= 5.9" } }, "node_modules/beeper": { @@ -625,18 +622,6 @@ "node": ">=0.10.0" } }, - "node_modules/better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha512-bYeph2DFlpK1XmGs6fvlLRUN29QISM3GBuUwSFsMY2XRx4AvC0WNCS57j4c/xGrK2RS24C1w3YoBOsw9fT46tQ==", - "dev": true, - "dependencies": { - "callsite": "1.0.0" - }, - "engines": { - "node": "*" - } - }, "node_modules/binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -656,12 +641,6 @@ "file-uri-to-path": "1.0.0" } }, - "node_modules/blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha512-YRc9zvVz4wNaxcXmiSgb9LAg7YYwqQ2xd0Sj6osfA7k/PKmIGVlnOYs3wOFdkRC9/JpQu8sGt/zHgJV7xzerfg==", - "dev": true - }, "node_modules/block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -747,22 +726,6 @@ "node": ">=0.10.0" } }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "dependencies": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "node_modules/buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, "node_modules/buffer-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", @@ -772,12 +735,6 @@ "node": ">=0.4.0" } }, - "node_modules/buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "dev": true - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -850,15 +807,6 @@ "node": ">=0.10.0" } }, - "node_modules/callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", @@ -1153,6 +1101,24 @@ "node": ">=0.10.0" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -1162,48 +1128,18 @@ "color-support": "bin.js" } }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combine-lists": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", - "integrity": "sha512-4Mi0V7N48B9KzC8Zl/U7wiWuxMFEHf44N3/PSoAvWDu8IOPrddNo1y1tC/kXbP7IvVMhgCFMMNzgKb0pWoin9w==", - "dev": true, - "dependencies": { - "lodash": "^4.5.0" - } - }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==", - "dev": true - }, "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, - "node_modules/component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==", - "dev": true - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1265,9 +1201,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true, "engines": { "node": ">= 0.6" @@ -1292,20 +1228,25 @@ "is-plain-object": "^5.0.0" } }, - "node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.", - "dev": true, - "hasInstallScript": true - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", @@ -1346,6 +1287,15 @@ "type": "^1.0.1" } }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/dateformat": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", @@ -1554,6 +1504,12 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -1573,107 +1529,77 @@ } }, "node_modules/engine.io": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz", - "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", - "dev": true, - "dependencies": { - "accepts": "1.3.3", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "ws": "1.1.2" - } - }, - "node_modules/engine.io-client": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz", - "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", - "dev": true, - "dependencies": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parsejson": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "1.1.2", - "xmlhttprequest-ssl": "1.5.3", - "yeast": "0.1.2" - } - }, - "node_modules/engine.io-client/node_modules/component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==", - "dev": true - }, - "node_modules/engine.io-client/node_modules/debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", - "dev": true, - "dependencies": { - "ms": "0.7.2" - } - }, - "node_modules/engine.io-client/node_modules/ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - }, - "node_modules/engine.io-client/node_modules/ws": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", - "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", + "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", "dev": true, "dependencies": { - "options": ">=0.0.5", - "ultron": "1.0.x" + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3" + }, + "engines": { + "node": ">=10.0.0" } }, "node_modules/engine.io-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", - "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", + "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", "dev": true, - "dependencies": { - "after": "0.8.2", - "arraybuffer.slice": "0.0.6", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary": "0.1.7", - "wtf-8": "1.0.0" + "engines": { + "node": ">=10.0.0" } }, "node_modules/engine.io/node_modules/debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "ms": "0.7.2" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/engine.io/node_modules/ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/engine.io/node_modules/ws": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", - "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", "dev": true, - "dependencies": { - "options": ">=0.0.5", - "ultron": "1.0.x" + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/ent": { @@ -1839,6 +1765,15 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -2209,41 +2144,6 @@ "node": ">=0.10.0" } }, - "node_modules/expand-braces": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", - "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", - "dev": true, - "dependencies": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-braces/node_modules/array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-braces/node_modules/braces": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", - "integrity": "sha512-EIMHIv2UXHWFY2xubUGKz+hq9hNkENj4Pjvr7h58cmJgpkK2yMlKA8I484f7MSttkzVAy/lL7X9xDaILd6avzA==", - "dev": true, - "dependencies": { - "expand-range": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -2336,37 +2236,6 @@ "node": ">=0.10.0" } }, - "node_modules/expand-range": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", - "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", - "dev": true, - "dependencies": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-range/node_modules/is-number": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", - "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-range/node_modules/repeat-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", - "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, "node_modules/expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -2497,15 +2366,6 @@ "dev": true, "optional": true }, - "node_modules/filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fileset": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fileset/-/fileset-0.2.1.tgz", @@ -2669,6 +2529,12 @@ "node": ">=0.10.0" } }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, "node_modules/flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -2754,6 +2620,20 @@ "node": ">=0.10.0" } }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -2948,49 +2828,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "dependencies": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-base/node_modules/glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "dependencies": { - "is-glob": "^2.0.0" - } - }, - "node_modules/glob-base/node_modules/is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-base/node_modules/is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "dependencies": { - "is-extglob": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -3311,31 +3148,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-binary": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", - "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", - "dev": true, - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/has-binary/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "node_modules/has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true, "engines": { "node": ">=0.10.0" @@ -3527,12 +3343,6 @@ "node": ">=0.10.0" } }, - "node_modules/indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3792,27 +3602,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "dependencies": { - "is-primitive": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -3964,24 +3753,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", @@ -4158,15 +3929,15 @@ "dev": true }, "node_modules/isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", "dev": true, - "dependencies": { - "buffer-alloc": "^1.2.0" - }, "engines": { - "node": ">=0.6.0" + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" } }, "node_modules/isexe": { @@ -4308,13 +4079,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "node_modules/json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "deprecated": "Please use the native JSON object instead of JSON 3", - "dev": true - }, "node_modules/json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -4327,6 +4091,15 @@ "json5": "lib/cli.js" } }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -4352,44 +4125,41 @@ "dev": true }, "node_modules/karma": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/karma/-/karma-1.5.0.tgz", - "integrity": "sha1-nEwU8EAL7ywEyOjmv/WTcQJcwAk=", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", + "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", "dev": true, "dependencies": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^1.4.1", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^3.8.0", - "log4js": "^0.6.31", - "mime": "^1.3.4", - "minimatch": "^3.0.0", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", - "socket.io": "1.7.3", - "source-map": "^0.5.3", - "tmp": "0.0.31", - "useragent": "^2.1.12" + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.4.1", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" }, "bin": { "karma": "bin/karma" }, "engines": { - "node": "0.10 || 0.12 || 4 || 5 || 6 || 7" + "node": ">= 10" } }, "node_modules/karma-chrome-launcher": { @@ -4699,229 +4469,304 @@ "node": ">=0.1.90" } }, - "node_modules/karma/node_modules/anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "node_modules/karma/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/karma/node_modules/arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA==", + "node_modules/karma/node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { - "arr-flatten": "^1.0.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, - "node_modules/karma/node_modules/array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==", + "node_modules/karma/node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/karma/node_modules/braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "dependencies": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "fill-range": "^7.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/karma/node_modules/chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg==", - "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "^1.0.0" + "fsevents": "~2.3.2" } }, - "node_modules/karma/node_modules/expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "dependencies": { - "is-posix-bracket": "^0.1.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/karma/node_modules/expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "node_modules/karma/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/karma/node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/karma/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "fill-range": "^2.1.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/karma/node_modules/extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "node_modules/karma/node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "dependencies": { - "is-extglob": "^1.0.0" + "binary-extensions": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/karma/node_modules/fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "node_modules/karma/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/karma/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "picomatch": "^2.2.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8.10.0" } }, - "node_modules/karma/node_modules/glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "node_modules/karma/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "is-glob": "^2.0.0" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/karma/node_modules/is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/karma/node_modules/is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "node_modules/karma/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "is-extglob": "^1.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/karma/node_modules/is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "node_modules/karma/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/karma/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "node_modules/karma/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { - "isarray": "1.0.0" + "is-number": "^7.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8.0" } }, - "node_modules/karma/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/karma/node_modules/lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true + "node_modules/karma/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "node_modules/karma/node_modules/micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/karma/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, "node_modules/kind-of": { @@ -5193,40 +5038,42 @@ } }, "node_modules/log4js": { - "version": "0.6.38", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", - "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", + "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", "dev": true, "dependencies": { - "readable-stream": "~1.0.2", - "semver": "~4.3.3" + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.3" }, "engines": { - "node": ">=0.8" + "node": ">=8.0" } }, - "node_modules/log4js/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "node_modules/log4js/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "node_modules/log4js/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/log4js/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "node_modules/log4js/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/lolex": { @@ -5257,16 +5104,6 @@ "node": ">=0.10.0" } }, - "node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "node_modules/make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -5360,12 +5197,6 @@ "node": ">=0.10.0" } }, - "node_modules/math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -5467,15 +5298,15 @@ } }, "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, "bin": { "mime": "cli.js" }, "engines": { - "node": ">=4" + "node": ">=4.0.0" } }, "node_modules/mime-db": { @@ -5723,9 +5554,9 @@ "dev": true }, "node_modules/negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, "engines": { "node": ">= 0.6" @@ -5824,12 +5655,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, "node_modules/object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -6000,31 +5825,6 @@ "node": ">=0.10.0" } }, - "node_modules/object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "dependencies": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.omit/node_modules/for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "dependencies": { - "for-in": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -6097,31 +5897,6 @@ "node": ">=0.10.0" } }, - "node_modules/optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "dependencies": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "node_modules/optimist/node_modules/minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "node_modules/optimist/node_modules/wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -6178,15 +5953,6 @@ "node": ">=0.10.0" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -6234,42 +6000,6 @@ "node": ">=0.8" } }, - "node_modules/parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "dependencies": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-glob/node_modules/is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-glob/node_modules/is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "dependencies": { - "is-extglob": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -6300,33 +6030,6 @@ "node": ">=0.10.0" } }, - "node_modules/parsejson": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", - "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", - "dev": true, - "dependencies": { - "better-assert": "~1.0.0" - } - }, - "node_modules/parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "dependencies": { - "better-assert": "~1.0.0" - } - }, - "node_modules/parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "dependencies": { - "better-assert": "~1.0.0" - } - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -6431,6 +6134,18 @@ "node": ">=0.10.0" } }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -6494,15 +6209,6 @@ "node": ">=0.10.0" } }, - "node_modules/preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -6527,12 +6233,6 @@ "node": ">=0.4.0" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "node_modules/pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", @@ -6588,38 +6288,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "dependencies": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/randomatic/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/randomatic/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -6780,18 +6448,6 @@ "node": ">=0.10.0" } }, - "node_modules/regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "dependencies": { - "is-equal-shallow": "^0.1.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -7071,6 +6727,12 @@ "node": ">=0.12" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "node_modules/rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -7450,148 +7112,87 @@ } }, "node_modules/socket.io": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", - "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", + "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", "dev": true, "dependencies": { - "debug": "2.3.3", - "engine.io": "1.8.3", - "has-binary": "0.1.7", - "object-assign": "4.1.0", - "socket.io-adapter": "0.5.0", - "socket.io-client": "1.7.3", - "socket.io-parser": "2.3.1" + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.2.0", + "socket.io-adapter": "~2.4.0", + "socket.io-parser": "~4.2.0" + }, + "engines": { + "node": ">=10.0.0" } }, "node_modules/socket.io-adapter": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", - "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", - "dev": true, - "dependencies": { - "debug": "2.3.3", - "socket.io-parser": "2.3.1" - } - }, - "node_modules/socket.io-adapter/node_modules/debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", - "dev": true, - "dependencies": { - "ms": "0.7.2" - } - }, - "node_modules/socket.io-adapter/node_modules/ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - }, - "node_modules/socket.io-client": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz", - "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", - "dev": true, - "dependencies": { - "backo2": "1.0.2", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "2.3.3", - "engine.io-client": "1.8.3", - "has-binary": "0.1.7", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseuri": "0.0.5", - "socket.io-parser": "2.3.1", - "to-array": "0.1.4" - } - }, - "node_modules/socket.io-client/node_modules/component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==", - "dev": true - }, - "node_modules/socket.io-client/node_modules/debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", - "dev": true, - "dependencies": { - "ms": "0.7.2" - } - }, - "node_modules/socket.io-client/node_modules/ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", + "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", "dev": true }, "node_modules/socket.io-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", - "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", + "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", "dev": true, "dependencies": { - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "3.3.2" + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" } }, - "node_modules/socket.io-parser/node_modules/component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha512-YhIbp3PJiznERfjlIkK0ue4obZxt2S60+0W8z24ZymOHT8sHloOqWOqZRU2eN5OlY8U08VFsP02letcu26FilA==", - "dev": true - }, "node_modules/socket.io-parser/node_modules/debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha512-X0rGvJcskG1c3TgSCPqHJ0XJgwlcvOC7elJ5Y0hYuKBZoVqWpAMfLOeIh2UI/DCQ5ruodIjvsugZtjUYUw2pUw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "ms": "0.7.1" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/socket.io-parser/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, "node_modules/socket.io-parser/node_modules/ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/socket.io/node_modules/debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "ms": "0.7.2" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/socket.io/node_modules/ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/socket.io/node_modules/object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -7835,6 +7436,43 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, + "node_modules/streamroller": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", + "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/streamroller/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -8118,15 +7756,30 @@ } }, "node_modules/tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "dev": true, "dependencies": { - "os-tmpdir": "~1.0.1" + "rimraf": "^3.0.0" }, "engines": { - "node": ">=0.4.0" + "node": ">=8.17.0" + } + }, + "node_modules/tmp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/to-absolute-glob": { @@ -8142,12 +7795,6 @@ "node": ">=0.10.0" } }, - "node_modules/to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, "node_modules/to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -8325,6 +7972,25 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "node_modules/ua-parser-js": { + "version": "0.7.32", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", + "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "engines": { + "node": "*" + } + }, "node_modules/uglify-js": { "version": "3.15.5", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", @@ -8435,6 +8101,15 @@ "through2-filter": "^3.0.0" } }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -8551,16 +8226,6 @@ "node": ">=0.10.0" } }, - "node_modules/useragent": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", - "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", - "dev": true, - "dependencies": { - "lru-cache": "4.1.x", - "tmp": "0.0.x" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -8607,6 +8272,15 @@ "node": ">= 0.10" } }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/vinyl": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", @@ -8860,12 +8534,6 @@ "ultron": "1.0.x" } }, - "node_modules/wtf-8": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", - "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", - "dev": true - }, "node_modules/xml2js": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz", @@ -8885,15 +8553,6 @@ "node": ">=8.0" } }, - "node_modules/xmlhttprequest-ssl": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -8909,12 +8568,6 @@ "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", "dev": true }, - "node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, "node_modules/yargs": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", @@ -8945,21 +8598,45 @@ "camelcase": "^3.0.0", "object.assign": "^4.1.0" } + } + }, + "dependencies": { + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true + }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true }, - "node_modules/yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", "dev": true - } - }, - "dependencies": { + }, + "@types/cors": { + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "dev": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", + "dev": true + }, "abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", @@ -8967,13 +8644,13 @@ "dev": true }, "accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha512-AOPopplFOUlmUugwiZUCDpOwmqvSgdCyE8iJVLWI4NcB7qfMKQN34dn5xYtlUU03XGG5egRWW4NW5gIxpa5hEA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "requires": { - "mime-types": "~2.1.11", - "negotiator": "0.6.1" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "acorn": { @@ -9005,12 +8682,6 @@ "integrity": "sha512-QHVQ6ekddFaGr9r2hBUC4gPw2wLqMZioXojt9BydQPbSh8us7+Q5xcUCUq+hnh4zAdauV3wqoY0quApjKqrhbA==", "dev": true }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==", - "dev": true - }, "ajv": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", @@ -9236,12 +8907,6 @@ } } }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha512-rlVfZW/1Ph2SNySXwR9QYkChp8EkOEiTMO5Vwx60usw04i4nWemkm9RXmQqgkQFaLHsqLuADvjp6IfgL9l2M8Q==", - "dev": true - }, "array-sort": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", @@ -9277,12 +8942,6 @@ "es-shim-unscopables": "^1.0.0" } }, - "arraybuffer.slice": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", - "integrity": "sha512-6ZjfQaBSy6CuIH0+B0NrxMfDE5VIOCP/5gOqSpEIsaAZx9/giszzrXg6PZ7G51U/n88UmlAgYLNQ9wAnII7PJA==", - "dev": true - }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -9356,12 +9015,6 @@ "now-and-later": "^2.0.0" } }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", - "dev": true - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -9394,16 +9047,10 @@ } } }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha512-437oANT9tP582zZMwSvZGy2nmSeAb8DW2me3y+Uv1Wp2Rulr8Mqlyrv3E7MLxmsiaPSMMDmiDVzgE+e8zlMx9g==", - "dev": true - }, "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha512-rz8L+d/xByiB/vLVftPkyY215fqNrmasrcJsYkVcm4TgJNz+YXKrFaFAWibSaHkiKoSgMDCb+lipOIRQNGYesw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "dev": true }, "beeper": { @@ -9412,15 +9059,6 @@ "integrity": "sha512-3vqtKL1N45I5dV0RdssXZG7X6pCqQrWPNOlBPZPrd+QkE2HEhR57Z04m0KtpbsZH73j+a3F8UD1TQnn+ExTvIA==", "dev": true }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha512-bYeph2DFlpK1XmGs6fvlLRUN29QISM3GBuUwSFsMY2XRx4AvC0WNCS57j4c/xGrK2RS24C1w3YoBOsw9fT46tQ==", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -9437,12 +9075,6 @@ "file-uri-to-path": "1.0.0" } }, - "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha512-YRc9zvVz4wNaxcXmiSgb9LAg7YYwqQ2xd0Sj6osfA7k/PKmIGVlnOYs3wOFdkRC9/JpQu8sGt/zHgJV7xzerfg==", - "dev": true - }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -9511,34 +9143,12 @@ "to-regex": "^3.0.1" } }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, "buffer-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", "integrity": "sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==", "dev": true }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", - "dev": true - }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -9596,12 +9206,6 @@ "callsites": "^0.2.0" } }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==", - "dev": true - }, "callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", @@ -9839,51 +9443,39 @@ "object-visit": "^1.0.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combine-lists": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", - "integrity": "sha512-4Mi0V7N48B9KzC8Zl/U7wiWuxMFEHf44N3/PSoAvWDu8IOPrddNo1y1tC/kXbP7IvVMhgCFMMNzgKb0pWoin9w==", - "dev": true, - "requires": { - "lodash": "^4.5.0" - } - }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==", - "dev": true - }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==", - "dev": true - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -9938,9 +9530,9 @@ } }, "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true }, "copy-descriptor": { @@ -9959,18 +9551,22 @@ "is-plain-object": "^5.0.0" } }, - "core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "dev": true - }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", @@ -10005,6 +9601,12 @@ "type": "^1.0.1" } }, + "date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true + }, "dateformat": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", @@ -10172,6 +9774,12 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -10188,112 +9796,52 @@ } }, "engine.io": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz", - "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", - "dev": true, - "requires": { - "accepts": "1.3.3", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "ws": "1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - }, - "ws": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", - "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", - "dev": true, - "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" - } - } - } - }, - "engine.io-client": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz", - "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", + "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", "dev": true, "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parsejson": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "1.1.2", - "xmlhttprequest-ssl": "1.5.3", - "yeast": "0.1.2" + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.2.3" }, "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==", - "dev": true - }, "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "ms": "0.7.2" + "ms": "2.1.2" } }, "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "ws": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", - "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", "dev": true, - "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" - } + "requires": {} } } }, "engine.io-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", - "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "0.0.6", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary": "0.1.7", - "wtf-8": "1.0.0" - } + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", + "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "dev": true }, "ent": { "version": "2.2.0", @@ -10444,6 +9992,12 @@ "es6-symbol": "^3.1.1" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -10741,34 +10295,6 @@ "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", "dev": true }, - "expand-braces": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", - "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", - "dev": true, - "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" - }, - "dependencies": { - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==", - "dev": true - }, - "braces": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", - "integrity": "sha512-EIMHIv2UXHWFY2xubUGKz+hq9hNkENj4Pjvr7h58cmJgpkK2yMlKA8I484f7MSttkzVAy/lL7X9xDaILd6avzA==", - "dev": true, - "requires": { - "expand-range": "^0.1.0" - } - } - } - }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -10846,30 +10372,6 @@ } } }, - "expand-range": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", - "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", - "dev": true, - "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" - }, - "dependencies": { - "is-number": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", - "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", - "dev": true - }, - "repeat-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", - "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", - "dev": true - } - } - }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -10983,12 +10485,6 @@ "dev": true, "optional": true }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, "fileset": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fileset/-/fileset-0.2.1.tgz", @@ -11124,6 +10620,12 @@ "write": "^0.2.1" } }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -11182,6 +10684,17 @@ "null-check": "^1.0.0" } }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -11328,42 +10841,6 @@ "path-is-absolute": "^1.0.0" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -11624,29 +11101,6 @@ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true }, - "has-binary": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", - "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", @@ -11795,12 +11249,6 @@ "repeating": "^2.0.0" } }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -12000,21 +11448,6 @@ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -12123,18 +11556,6 @@ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, "is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", @@ -12263,13 +11684,10 @@ "dev": true }, "isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "dev": true, - "requires": { - "buffer-alloc": "^1.2.0" - } + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true }, "isexe": { "version": "2.0.0", @@ -12389,12 +11807,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -12404,6 +11816,15 @@ "minimist": "^1.2.0" } }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -12423,219 +11844,246 @@ "dev": true }, "karma": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/karma/-/karma-1.5.0.tgz", - "integrity": "sha1-nEwU8EAL7ywEyOjmv/WTcQJcwAk=", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", + "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", "dev": true, "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^1.4.1", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^3.8.0", - "log4js": "^0.6.31", - "mime": "^1.3.4", - "minimatch": "^3.0.0", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", - "socket.io": "1.7.3", - "source-map": "^0.5.3", - "tmp": "0.0.31", - "useragent": "^2.1.12" + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.4.1", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" }, "dependencies": { - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "color-convert": "^2.0.1" } }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA==", + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { - "arr-flatten": "^1.0.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==", + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "fill-range": "^7.0.1" } }, "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" } }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "is-posix-bracket": "^0.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "fill-range": "^2.1.0" + "to-regex-range": "^5.0.1" } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-glob": "^4.0.1" } }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "binary-extensions": "^2.0.0" } }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { - "is-glob": "^2.0.0" + "glob": "^7.1.3" } }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "kind-of": "^3.0.2" + "ansi-regex": "^5.0.1" } }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "isarray": "1.0.0" + "is-number": "^7.0.0" } }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true } } }, @@ -13120,37 +12568,31 @@ } }, "log4js": { - "version": "0.6.38", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", - "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", + "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", "dev": true, "requires": { - "readable-stream": "~1.0.2", - "semver": "~4.3.3" + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.3" }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "ms": "2.1.2" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -13177,16 +12619,6 @@ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "dev": true }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -13260,12 +12692,6 @@ } } }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -13348,9 +12774,9 @@ } }, "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true }, "mime-db": { @@ -13565,9 +12991,9 @@ "dev": true }, "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true }, "neo-async": { @@ -13642,12 +13068,6 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -13779,27 +13199,6 @@ "make-iterator": "^1.0.0" } }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - }, - "dependencies": { - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - } - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -13854,30 +13253,6 @@ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", "dev": true }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } - } - }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -13922,12 +13297,6 @@ "lcid": "^1.0.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -13963,35 +13332,6 @@ "path-root": "^0.1.1" } }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -14013,33 +13353,6 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, - "parsejson": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", - "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -14125,6 +13438,12 @@ "pinkie-promise": "^2.0.0" } }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -14170,12 +13489,6 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -14194,12 +13507,6 @@ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", "dev": true }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", @@ -14242,31 +13549,6 @@ "side-channel": "^1.0.4" } }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -14401,15 +13683,6 @@ "strip-indent": "^1.0.1" } }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -14617,6 +13890,12 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -14922,149 +14201,65 @@ } }, "socket.io": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", - "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", + "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", "dev": true, "requires": { - "debug": "2.3.3", - "engine.io": "1.8.3", - "has-binary": "0.1.7", - "object-assign": "4.1.0", - "socket.io-adapter": "0.5.0", - "socket.io-client": "1.7.3", - "socket.io-parser": "2.3.1" + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.2.0", + "socket.io-adapter": "~2.4.0", + "socket.io-parser": "~4.2.0" }, "dependencies": { "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "ms": "0.7.2" + "ms": "2.1.2" } }, "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - }, - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "socket.io-adapter": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", - "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", - "dev": true, - "requires": { - "debug": "2.3.3", - "socket.io-parser": "2.3.1" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-client": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz", - "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "2.3.3", - "engine.io-client": "1.8.3", - "has-binary": "0.1.7", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseuri": "0.0.5", - "socket.io-parser": "2.3.1", - "to-array": "0.1.4" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==", - "dev": true - }, - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha512-dCHp4G+F11zb+RtEu7BE2U8R32AYmM/4bljQfut8LipH3PdwsVBVGh083MXvtKkB7HSQUzSwiXz53c4mzJvYfw==", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", + "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", + "dev": true }, "socket.io-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", - "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", + "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", "dev": true, "requires": { - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "3.3.2" + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" }, "dependencies": { - "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha512-YhIbp3PJiznERfjlIkK0ue4obZxt2S60+0W8z24ZymOHT8sHloOqWOqZRU2eN5OlY8U08VFsP02letcu26FilA==", - "dev": true - }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha512-X0rGvJcskG1c3TgSCPqHJ0XJgwlcvOC7elJ5Y0hYuKBZoVqWpAMfLOeIh2UI/DCQ5ruodIjvsugZtjUYUw2pUw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.1.2" } }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -15273,6 +14468,34 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, + "streamroller": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", + "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", + "dev": true, + "requires": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -15505,12 +14728,23 @@ "dev": true }, "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "dev": true, "requires": { - "os-tmpdir": "~1.0.1" + "rimraf": "^3.0.0" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } } }, "to-absolute-glob": { @@ -15523,12 +14757,6 @@ "is-negated-glob": "^1.0.0" } }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -15671,6 +14899,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "ua-parser-js": { + "version": "0.7.32", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", + "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", + "dev": true + }, "uglify-js": { "version": "3.15.5", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", @@ -15762,6 +14996,12 @@ "through2-filter": "^3.0.0" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -15850,16 +15090,6 @@ "os-homedir": "^1.0.0" } }, - "useragent": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", - "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", - "dev": true, - "requires": { - "lru-cache": "4.1.x", - "tmp": "0.0.x" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -15897,6 +15127,12 @@ "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", "dev": true }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true + }, "vinyl": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", @@ -16106,12 +15342,6 @@ "ultron": "1.0.x" } }, - "wtf-8": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", - "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", - "dev": true - }, "xml2js": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz", @@ -16128,12 +15358,6 @@ "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "dev": true }, - "xmlhttprequest-ssl": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", - "dev": true - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -16146,12 +15370,6 @@ "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", "dev": true }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, "yargs": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", @@ -16182,12 +15400,6 @@ "camelcase": "^3.0.0", "object.assign": "^4.1.0" } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true } } } diff --git a/package.json b/package.json index 25a4d5fb656..06b230e9e7c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "gulp-eslint": "3.0.1", "jasmine-core": "2.6.1", "jasmine-jquery": "2.1.1", - "karma": "1.5.0", + "karma": "6.4.1", "karma-chrome-launcher": "2.2.0", "karma-coverage": "1.1.1", "karma-coverage-allsources": "0.0.4",