From dcecdfa191593be155e70ecd6b4538b1856ec8fe Mon Sep 17 00:00:00 2001 From: salman2013 Date: Thu, 19 Feb 2026 22:47:53 +0500 Subject: [PATCH 1/8] chore: bundling all js files with webpack --- xblocks_contrib/discussion/discussion.py | 250 +- xblocks_contrib/discussion/package-lock.json | 2636 +++++++++++++++++ xblocks_contrib/discussion/package.json | 14 + .../discussion/static/css/discussion.css | 9 - .../discussion/static/js/discussion_main.js | 40 + .../discussion/templates/discussion.html | 7 - .../discussion/webpack.common.config.js | 84 + .../discussion/webpack.dev.config.js | 19 + .../discussion/webpack.prod.config.js | 12 + 9 files changed, 3003 insertions(+), 68 deletions(-) create mode 100644 xblocks_contrib/discussion/package-lock.json create mode 100644 xblocks_contrib/discussion/package.json delete mode 100644 xblocks_contrib/discussion/static/css/discussion.css create mode 100644 xblocks_contrib/discussion/static/js/discussion_main.js delete mode 100644 xblocks_contrib/discussion/templates/discussion.html create mode 100644 xblocks_contrib/discussion/webpack.common.config.js create mode 100644 xblocks_contrib/discussion/webpack.dev.config.js create mode 100644 xblocks_contrib/discussion/webpack.prod.config.js diff --git a/xblocks_contrib/discussion/discussion.py b/xblocks_contrib/discussion/discussion.py index 88db1fe2..74364229 100644 --- a/xblocks_contrib/discussion/discussion.py +++ b/xblocks_contrib/discussion/discussion.py @@ -1,7 +1,18 @@ """ Discussion XBlock """ +""" +Discussion XBlock +""" + +import logging +import urllib +import markupsafe +from django.conf import settings +from django.template.loader import render_to_string +from django.urls import reverse +from django.utils.translation import get_language_bidi import logging import urllib @@ -12,6 +23,7 @@ from django.utils.translation import get_language_bidi from web_fragments.fragment import Fragment from xblock.completable import XBlockCompletionMode +from xblock.completable import XBlockCompletionMode from xblock.core import XBlock from xblock.fields import UNIQUE_ID, Scope, String from xblock.utils.resources import ResourceLoader @@ -24,6 +36,52 @@ Text = markupsafe.escape # pylint: disable=invalid-name +def _(text): + """ + A noop underscore function that marks strings for extraction. + """ + return text + + +def HTML(html): # pylint: disable=invalid-name + """ + Mark a string as already HTML, so that it won't be escaped before output. + + Use this function when formatting HTML into other strings. It must be + used in conjunction with ``Text()``, and both ``HTML()`` and ``Text()`` + must be closed before any calls to ``format()``:: + + <%page expression_filter="h"/> + <%! + from django.utils.translation import gettext as _ + + from openedx.core.djangolib.markup import HTML, Text + %> + ${Text(_("Write & send {start}email{end}")).format( + start=HTML("").format(user.email), + end=HTML(""), + )} + + """ + return markupsafe.Markup(html) + + +def is_discussion_enabled(course_id): # pylint: disable=unused-argument + """ + Return True if discussions are enabled; else False + """ + return settings.FEATURES.get('ENABLE_DISCUSSION_SERVICE') + + +from xblock.utils.studio_editable import StudioEditableXBlockMixin + +from xblocks_contrib.common.xml_utils import LegacyXmlMixin + +log = logging.getLogger(__name__) +loader = ResourceLoader(__name__) +Text = markupsafe.escape # pylint: disable=invalid-name + + def _(text): """ A noop underscore function that marks strings for extraction. @@ -64,6 +122,12 @@ def is_discussion_enabled(course_id): # pylint: disable=unused-argument @XBlock.needs("i18n") @XBlock.wants("user") # pylint: disable=abstract-method +class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, LegacyXmlMixin): + """ + Provides a discussion forum that is inline with other content in the courseware. + """ +@XBlock.wants("user") +# pylint: disable=abstract-method class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, LegacyXmlMixin): """ Provides a discussion forum that is inline with other content in the courseware. @@ -116,6 +180,22 @@ def is_visible(self): # return provider.provider_type == Provider.LEGACY return True + @staticmethod + def _discussion_js_resource_path(): + """ + Returns the URL for the local resource. + + Note: when running with the full Django pipeline, the file will be accessed + as a static asset which will use a CDN in production. + + For more details, see platform's xblock_local_resource_url() define in: + https://github.com/openedx/openedx-platform/blob/master/openedx/core/lib/xblock_utils/__init__.py + """ + if settings.PIPELINE.get('PIPELINE_ENABLED', False) or not getattr(settings, 'REQUIRE_DEBUG', False): + return 'discussion/public/js/discussion_bundle.js' + else: + return 'public/js/discussion_bundle.js' + @property def django_user(self): """ @@ -127,67 +207,21 @@ def django_user(self): return None return user_service._django_user # pylint: disable=protected-access - def get_all_js_files(self): - """ - Returns list of all JS files in the correct dependency order. - """ - return [ - # Vendor files (load first as dependencies) - 'static/js/vendor/Markdown.Converter.js', - 'static/js/vendor/Markdown.Sanitizer.js', - 'static/js/vendor/Markdown.Editor.js', - 'static/js/vendor/jquery.ajaxfileupload.js', - 'static/js/vendor/jquery.timeago.js', - 'static/js/vendor/jquery.timeago.locale.js', - 'static/js/vendor/jquery.truncate.js', - 'static/js/vendor/split.js', - # MathJax utilities - 'static/js/mathjax_accessible.js', - 'static/js/mathjax_delay_renderer.js', - # Core utilities and models - 'static/js/common/utils.js', - 'static/js/common/models/discussion_course_settings.js', - 'static/js/common/models/discussion_user.js', - # Core discussion functionality - # content.js must come before discussion.js because discussion.js uses Thread - 'static/js/common/content.js', - 'static/js/common/discussion.js', - 'static/js/common/mathjax_include.js', - # Custom WMD editor - 'static/js/customwmd.js', - # Views (depend on core discussion and models) - 'static/js/common/views/discussion_content_view.js', - 'static/js/common/views/discussion_inline_view.js', - 'static/js/common/views/discussion_thread_edit_view.js', - 'static/js/common/views/discussion_thread_list_view.js', - 'static/js/common/views/discussion_thread_profile_view.js', - 'static/js/common/views/discussion_thread_show_view.js', - 'static/js/common/views/discussion_thread_view.js', - 'static/js/common/views/discussion_topic_menu_view.js', - 'static/js/common/views/new_post_view.js', - 'static/js/common/views/response_comment_edit_view.js', - 'static/js/common/views/response_comment_show_view.js', - 'static/js/common/views/response_comment_view.js', - 'static/js/common/views/thread_response_edit_view.js', - 'static/js/common/views/thread_response_show_view.js', - 'static/js/common/views/thread_response_view.js', - ] - def add_resource_urls(self, fragment): """ Adds URLs for JS and CSS resources that this XBlock depends on to `fragment`. """ css_file_path = ( - 'static/css/inline-discussion-rtl.css' + 'public/css/inline-discussion-rtl.css' if get_language_bidi() - else 'static/css/inline-discussion.css' + else 'public/css/inline-discussion.css' ) - fragment.add_css(loader.load_unicode(css_file_path)) + fragment.add_css_url(self.runtime.local_resource_url(self, css_file_path)) - # Load all JS files individually in the correct order - for js_file in self.get_all_js_files(): - fragment.add_javascript(loader.load_unicode(js_file)) + bundle_path = self._discussion_js_resource_path() + bundle_url = self.runtime.local_resource_url(self, bundle_path) + fragment.add_resource_url(bundle_url, 'application/javascript') def has_permission(self, permission): # pylint: disable=unused-argument """ @@ -268,9 +302,76 @@ def author_view(self, context=None): ) return fragment + def student_view_data(self): + """ + Renders student view for LMS. + """ + + fragment = Fragment() + + if not self.is_visible: + return fragment + + self.add_resource_urls(fragment) + login_msg = '' + + if not self.django_user.is_authenticated: + qs = urllib.parse.urlencode({ + 'course_id': self.course_key, + 'enrollment_action': 'enroll', + 'email_opt_in': False, + }) + login_msg = Text(_("You are not signed in. To view the discussion content, {sign_in_link} or " + "{register_link}, and enroll in this course.")).format( + sign_in_link=HTML('{sign_in_label}').format( + sign_in_label=_('sign in'), + url='{}?{}'.format(reverse('signin_user'), qs), + ), + register_link=HTML('{register_label}').format( + register_label=_('register'), + url='{}?{}'.format(reverse('register_user'), qs), + ), + ) + + if is_discussion_enabled(self.course_key): + context = { + 'discussion_id': self.discussion_id, + 'display_name': self.display_name if self.display_name else _("Discussion"), + 'user': self.django_user, + 'course_id': self.course_key, + 'discussion_category': self.discussion_category, + 'discussion_target': self.discussion_target, + 'can_create_thread': self.has_permission("create_thread"), + 'can_create_comment': self.has_permission("create_comment"), + 'can_create_subcomment': self.has_permission("create_sub_comment"), + 'login_msg': login_msg, + } + fragment.add_content( + render_to_string('discussion/_discussion_inline.html', context) + ) + + fragment.initialize_js('DiscussionInlineBlock') + + return fragment + + def author_view(self, context=None): + """ + Renders author view for Studio. + """ + fragment = Fragment() + context = { + 'discussion_id': self.discussion_id, + 'is_visible': self.is_visible, + } + fragment.add_content( + loader.render_django_template('templates/_discussion_inline_studio.html', context) + ) + return fragment + def student_view_data(self): """ Returns a JSON representation of the student_view of this XBlock. + Returns a JSON representation of the student_view of this XBlock. """ return {'topic_id': self.discussion_id} @@ -317,3 +418,48 @@ def _apply_metadata_and_policy(cls, block, node, runtime): for field_name, value in metadata.items(): if field_name in block.fields: setattr(block, field_name, value) + return {'topic_id': cls.discussion_id} + + @classmethod + def parse_xml(cls, node, runtime, keys): + """ + Parses OLX into XBlock. + + This method is overridden here to allow parsing legacy OLX, coming from discussion XModule. + XBlock stores all the associated data, fields and children in a XML element inlined into vertical XML file + XModule stored only minimal data on the element included into vertical XML and used a dedicated "discussion" + folder in OLX to store fields and children. Also, some info was put into "policy.json" file. + + If no external data sources are found (file in "discussion" folder), it is exactly equivalent to base method + XBlock.parse_xml. Otherwise this method parses file in "discussion" folder (known as definition_xml), applies + policy.json and updates fields accordingly. + """ + block = super().parse_xml(node, runtime, keys) + + cls._apply_metadata_and_policy(block, node, runtime) + + return block + + @classmethod + def _apply_metadata_and_policy(cls, block, node, runtime): + """ + Attempt to load definition XML from "discussion" folder in OLX, than parse it and update block fields + """ + if node.get('url_name') is None: + return # Newer/XBlock XML format - no need to load an additional file. + try: + definition_xml, _ = cls.load_definition_xml(node, runtime, block.scope_ids.def_id) + except Exception as err: # pylint: disable=broad-except + log.info( + "Exception %s when trying to load definition xml for block %s - assuming XBlock export format", + err, + block + ) + return + + metadata = cls.load_metadata(definition_xml) + cls.apply_policy(metadata, runtime.get_policy(block.scope_ids.usage_id)) + + for field_name, value in metadata.items(): + if field_name in block.fields: + setattr(block, field_name, value) diff --git a/xblocks_contrib/discussion/package-lock.json b/xblocks_contrib/discussion/package-lock.json new file mode 100644 index 00000000..a2417187 --- /dev/null +++ b/xblocks_contrib/discussion/package-lock.json @@ -0,0 +1,2636 @@ +{ + "name": "discussion", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "devDependencies": { + "append-prepend-loader": "^1.0.0", + "copy-webpack-plugin": "13.0.1", + "imports-loader": "^5.0.0", + "webpack": "^5.90.0", + "webpack-cli": "^5.1.4" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.1.tgz", + "integrity": "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==", + "dev": true, + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/append-prepend-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-prepend-loader/-/append-prepend-loader-1.0.0.tgz", + "integrity": "sha512-TpqFKoWUJZgo69yFD+EZ+NBhEVAVT6LK5vgMbBEyHd65a33v/ECNq7H8THzL4eobBZaaJ21bVg5ruJeYxTSsYw==", + "dev": true, + "peerDependencies": { + "webpack": "*" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "dev": true, + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001769", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", + "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "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/copy-webpack-plugin": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz", + "integrity": "sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==", + "dev": true, + "dependencies": { + "glob-parent": "^6.0.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2", + "tinyglobby": "^0.2.12" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imports-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-5.0.0.tgz", + "integrity": "sha512-tXgL8xxZFjOjQLLiE7my00UUQfktg4G8fdpXcZphL0bJWbk9eCxKKFaCwmFRcwyRJQl95GXBL1DoE1rCS/tcPw==", + "dev": true, + "dependencies": { + "source-map-js": "^1.0.2", + "strip-comments": "^2.0.1" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "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/loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "dev": true, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.3.1", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + } + }, + "dependencies": { + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, + "@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "@types/node": { + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.1.tgz", + "integrity": "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==", + "dev": true, + "requires": { + "undici-types": "~7.16.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "requires": {} + }, + "@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true + }, + "acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "requires": {} + }, + "ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "append-prepend-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-prepend-loader/-/append-prepend-loader-1.0.0.tgz", + "integrity": "sha512-TpqFKoWUJZgo69yFD+EZ+NBhEVAVT6LK5vgMbBEyHd65a33v/ECNq7H8THzL4eobBZaaJ21bVg5ruJeYxTSsYw==", + "dev": true, + "requires": {} + }, + "baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "dev": true + }, + "browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "requires": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001769", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", + "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "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 + }, + "copy-webpack-plugin": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz", + "integrity": "sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==", + "dev": true, + "requires": { + "glob-parent": "^6.0.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2", + "tinyglobby": "^0.2.12" + } + }, + "cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "electron-to-chromium": { + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", + "dev": true + }, + "enhanced-resolve": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + } + }, + "envinfo": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "dev": true + }, + "es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "dev": true + }, + "escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true + }, + "fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "requires": {} + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, + "import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imports-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-5.0.0.tgz", + "integrity": "sha512-tXgL8xxZFjOjQLLiE7my00UUQfktg4G8fdpXcZphL0bJWbk9eCxKKFaCwmFRcwyRJQl95GXBL1DoE1rCS/tcPw==", + "dev": true, + "requires": { + "source-map-js": "^1.0.2", + "strip-comments": "^2.0.1" + } + }, + "interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true + }, + "is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "requires": { + "hasown": "^2.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "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 + }, + "loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "requires": { + "resolve": "^1.20.0" + } + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "requires": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "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 + }, + "source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true + }, + "terser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } + }, + "terser-webpack-plugin": { + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + } + }, + "tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "requires": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + } + }, + "undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "requires": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + } + }, + "watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.3.1", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" + } + }, + "webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true + } + } + }, + "webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + } + } +} diff --git a/xblocks_contrib/discussion/package.json b/xblocks_contrib/discussion/package.json new file mode 100644 index 00000000..71273a94 --- /dev/null +++ b/xblocks_contrib/discussion/package.json @@ -0,0 +1,14 @@ +{ + "private": true, + "scripts": { + "build": "webpack --config webpack.prod.config.js", + "build-dev": "webpack --config webpack.dev.config.js" + }, + "devDependencies": { + "append-prepend-loader": "^1.0.0", + "copy-webpack-plugin": "13.0.1", + "imports-loader": "^5.0.0", + "webpack": "^5.90.0", + "webpack-cli": "^5.1.4" + } +} diff --git a/xblocks_contrib/discussion/static/css/discussion.css b/xblocks_contrib/discussion/static/css/discussion.css deleted file mode 100644 index 19dca48b..00000000 --- a/xblocks_contrib/discussion/static/css/discussion.css +++ /dev/null @@ -1,9 +0,0 @@ -/* CSS for DiscussionXBlock */ - -.discussion .count { - font-weight: bold; -} - -.discussion p { - cursor: pointer; -} diff --git a/xblocks_contrib/discussion/static/js/discussion_main.js b/xblocks_contrib/discussion/static/js/discussion_main.js new file mode 100644 index 00000000..41ab4ba2 --- /dev/null +++ b/xblocks_contrib/discussion/static/js/discussion_main.js @@ -0,0 +1,40 @@ +/* + Webpack entry: imports all discussion JS in dependency order. + */ + +// Vendor +import './vendor/Markdown.Converter.js'; +import './vendor/Markdown.Sanitizer.js'; +import './vendor/Markdown.Editor.js'; +import './vendor/jquery.ajaxfileupload.js'; +import './vendor/jquery.timeago.js'; +import './vendor/jquery.timeago.locale.js'; +import './vendor/jquery.truncate.js'; +import './vendor/split.js'; +// MathJax +import './mathjax_accessible.js'; +import './mathjax_delay_renderer.js'; +// Core +import './common/utils.js'; +import './common/models/discussion_course_settings.js'; +import './common/models/discussion_user.js'; +import './common/content.js'; +import './common/discussion.js'; +import './common/mathjax_include.js'; +import './customwmd.js'; +// Views +import './common/views/discussion_content_view.js'; +import './common/views/discussion_inline_view.js'; +import './common/views/discussion_thread_edit_view.js'; +import './common/views/discussion_thread_list_view.js'; +import './common/views/discussion_thread_profile_view.js'; +import './common/views/discussion_thread_show_view.js'; +import './common/views/discussion_thread_view.js'; +import './common/views/discussion_topic_menu_view.js'; +import './common/views/new_post_view.js'; +import './common/views/response_comment_edit_view.js'; +import './common/views/response_comment_show_view.js'; +import './common/views/response_comment_view.js'; +import './common/views/thread_response_edit_view.js'; +import './common/views/thread_response_show_view.js'; +import './common/views/thread_response_view.js'; diff --git a/xblocks_contrib/discussion/templates/discussion.html b/xblocks_contrib/discussion/templates/discussion.html deleted file mode 100644 index c54902b2..00000000 --- a/xblocks_contrib/discussion/templates/discussion.html +++ /dev/null @@ -1,7 +0,0 @@ -{% load i18n %} - -
-

- DiscussionXBlock: {% trans "count is now" %} {{ count }} {% trans "click me to increment." %} -

-
diff --git a/xblocks_contrib/discussion/webpack.common.config.js b/xblocks_contrib/discussion/webpack.common.config.js new file mode 100644 index 00000000..d34f9232 --- /dev/null +++ b/xblocks_contrib/discussion/webpack.common.config.js @@ -0,0 +1,84 @@ +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +const discussionRoot = __dirname; +const staticJs = path.join(discussionRoot, 'static', 'js'); +const staticCss = path.join(discussionRoot, 'static', 'css'); + +const config = { + context: discussionRoot, + entry: './static/js/discussion_main.js', + output: { + path: path.join(__dirname, 'public', 'js'), + filename: 'discussion_bundle.js', + }, + resolve: { + modules: [staticJs, 'node_modules'], + }, + module: { + rules: [ + { + test: /Markdown\.Converter\.js$/, + use: [ + { + loader: 'append-prepend-loader', + options: { + append: '\n;window.Markdown=exports;', + }, + }, + ], + }, + { + test: /Markdown\.Sanitizer\.js$/, + use: [ + { + loader: 'append-prepend-loader', + options: { + append: '\n;window.Markdown.getSanitizingConverter=exports.getSanitizingConverter;', + }, + }, + ], + }, + // Legacy IIFE code expects this===window; imports-loader wrapper (edx-platform pattern) + // Exclude discussion_main.js (has top-level import/export). + { + test: /\.js$/, + include: [ + path.join(staticJs, 'common'), + path.join(staticJs, 'vendor'), + path.join(staticJs, 'mathjax_accessible.js'), + path.join(staticJs, 'mathjax_delay_renderer.js'), + path.join(staticJs, 'customwmd.js'), + ], + exclude: [path.join(staticJs, 'discussion_main.js')], + use: [ + { + loader: 'imports-loader', + options: { wrapper: 'window' }, + }, + ], + }, + { + test: /split\.js$/, + use: [ + { + loader: 'append-prepend-loader', + options: { + append: '\n;window._split=_split;', + }, + }, + ], + }, + ], + }, + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + { from: path.join(staticCss, 'inline-discussion.css'), to: path.join(discussionRoot, 'public', 'css', 'inline-discussion.css') }, + { from: path.join(staticCss, 'inline-discussion-rtl.css'), to: path.join(discussionRoot, 'public', 'css', 'inline-discussion-rtl.css') }, + ], + }), + ], +}; + +module.exports = config diff --git a/xblocks_contrib/discussion/webpack.dev.config.js b/xblocks_contrib/discussion/webpack.dev.config.js new file mode 100644 index 00000000..5b012cbc --- /dev/null +++ b/xblocks_contrib/discussion/webpack.dev.config.js @@ -0,0 +1,19 @@ +const {merge} = require('webpack-merge'); +const webpack = require('webpack'); +const _ = require('underscore'); +const commonConfig = require('./webpack.common.config.js'); + +module.exports = commonConfig; + +module.exports = merge(commonConfig, { + mode: 'development', + devtool: 'inline-source-map', + plugins: [ + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('development'), + 'process.env.JS_ENV_EXTRA_CONFIG': process.env.JS_ENV_EXTRA_CONFIG || '{}', + 'CAPTIONS_CONTENT_TO_REPLACE': JSON.stringify(process.env.CAPTIONS_CONTENT_TO_REPLACE || ''), + 'CAPTIONS_CONTENT_REPLACEMENT': JSON.stringify(process.env.CAPTIONS_CONTENT_REPLACEMENT || '') + }) + ] +}); \ No newline at end of file diff --git a/xblocks_contrib/discussion/webpack.prod.config.js b/xblocks_contrib/discussion/webpack.prod.config.js new file mode 100644 index 00000000..ee4cb5b0 --- /dev/null +++ b/xblocks_contrib/discussion/webpack.prod.config.js @@ -0,0 +1,12 @@ +const { merge } = require('webpack-merge'); +const webpack = require('webpack'); +const commonConfig = require('./webpack.common.config.js'); + +module.exports = merge(commonConfig, { + mode: 'production', + plugins: [ + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production'), + }), + ], +}); From b277f83ee70d3cb285e061b5d13a2956f5edab27 Mon Sep 17 00:00:00 2001 From: salman2013 Date: Thu, 19 Feb 2026 23:20:14 +0500 Subject: [PATCH 2/8] fix: resolve conflict --- xblocks_contrib/discussion/discussion.py | 130 ----------------------- 1 file changed, 130 deletions(-) diff --git a/xblocks_contrib/discussion/discussion.py b/xblocks_contrib/discussion/discussion.py index 74364229..7da1624a 100644 --- a/xblocks_contrib/discussion/discussion.py +++ b/xblocks_contrib/discussion/discussion.py @@ -1,21 +1,10 @@ """ Discussion XBlock """ -""" -Discussion XBlock -""" import logging import urllib -import markupsafe -from django.conf import settings -from django.template.loader import render_to_string -from django.urls import reverse -from django.utils.translation import get_language_bidi -import logging -import urllib - import markupsafe from django.conf import settings from django.template.loader import render_to_string @@ -23,7 +12,6 @@ from django.utils.translation import get_language_bidi from web_fragments.fragment import Fragment from xblock.completable import XBlockCompletionMode -from xblock.completable import XBlockCompletionMode from xblock.core import XBlock from xblock.fields import UNIQUE_ID, Scope, String from xblock.utils.resources import ResourceLoader @@ -36,52 +24,6 @@ Text = markupsafe.escape # pylint: disable=invalid-name -def _(text): - """ - A noop underscore function that marks strings for extraction. - """ - return text - - -def HTML(html): # pylint: disable=invalid-name - """ - Mark a string as already HTML, so that it won't be escaped before output. - - Use this function when formatting HTML into other strings. It must be - used in conjunction with ``Text()``, and both ``HTML()`` and ``Text()`` - must be closed before any calls to ``format()``:: - - <%page expression_filter="h"/> - <%! - from django.utils.translation import gettext as _ - - from openedx.core.djangolib.markup import HTML, Text - %> - ${Text(_("Write & send {start}email{end}")).format( - start=HTML("").format(user.email), - end=HTML(""), - )} - - """ - return markupsafe.Markup(html) - - -def is_discussion_enabled(course_id): # pylint: disable=unused-argument - """ - Return True if discussions are enabled; else False - """ - return settings.FEATURES.get('ENABLE_DISCUSSION_SERVICE') - - -from xblock.utils.studio_editable import StudioEditableXBlockMixin - -from xblocks_contrib.common.xml_utils import LegacyXmlMixin - -log = logging.getLogger(__name__) -loader = ResourceLoader(__name__) -Text = markupsafe.escape # pylint: disable=invalid-name - - def _(text): """ A noop underscore function that marks strings for extraction. @@ -122,12 +64,6 @@ def is_discussion_enabled(course_id): # pylint: disable=unused-argument @XBlock.needs("i18n") @XBlock.wants("user") # pylint: disable=abstract-method -class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, LegacyXmlMixin): - """ - Provides a discussion forum that is inline with other content in the courseware. - """ -@XBlock.wants("user") -# pylint: disable=abstract-method class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, LegacyXmlMixin): """ Provides a discussion forum that is inline with other content in the courseware. @@ -302,72 +238,6 @@ def author_view(self, context=None): ) return fragment - def student_view_data(self): - """ - Renders student view for LMS. - """ - - fragment = Fragment() - - if not self.is_visible: - return fragment - - self.add_resource_urls(fragment) - login_msg = '' - - if not self.django_user.is_authenticated: - qs = urllib.parse.urlencode({ - 'course_id': self.course_key, - 'enrollment_action': 'enroll', - 'email_opt_in': False, - }) - login_msg = Text(_("You are not signed in. To view the discussion content, {sign_in_link} or " - "{register_link}, and enroll in this course.")).format( - sign_in_link=HTML('{sign_in_label}').format( - sign_in_label=_('sign in'), - url='{}?{}'.format(reverse('signin_user'), qs), - ), - register_link=HTML('{register_label}').format( - register_label=_('register'), - url='{}?{}'.format(reverse('register_user'), qs), - ), - ) - - if is_discussion_enabled(self.course_key): - context = { - 'discussion_id': self.discussion_id, - 'display_name': self.display_name if self.display_name else _("Discussion"), - 'user': self.django_user, - 'course_id': self.course_key, - 'discussion_category': self.discussion_category, - 'discussion_target': self.discussion_target, - 'can_create_thread': self.has_permission("create_thread"), - 'can_create_comment': self.has_permission("create_comment"), - 'can_create_subcomment': self.has_permission("create_sub_comment"), - 'login_msg': login_msg, - } - fragment.add_content( - render_to_string('discussion/_discussion_inline.html', context) - ) - - fragment.initialize_js('DiscussionInlineBlock') - - return fragment - - def author_view(self, context=None): - """ - Renders author view for Studio. - """ - fragment = Fragment() - context = { - 'discussion_id': self.discussion_id, - 'is_visible': self.is_visible, - } - fragment.add_content( - loader.render_django_template('templates/_discussion_inline_studio.html', context) - ) - return fragment - def student_view_data(self): """ Returns a JSON representation of the student_view of this XBlock. From c762c20e904e84b666794850bdb018a8aa62de10 Mon Sep 17 00:00:00 2001 From: salman2013 Date: Thu, 19 Feb 2026 23:26:56 +0500 Subject: [PATCH 3/8] fix: resove conflicts --- xblocks_contrib/discussion/discussion.py | 45 ------------------------ 1 file changed, 45 deletions(-) diff --git a/xblocks_contrib/discussion/discussion.py b/xblocks_contrib/discussion/discussion.py index 7da1624a..e601b4b0 100644 --- a/xblocks_contrib/discussion/discussion.py +++ b/xblocks_contrib/discussion/discussion.py @@ -241,7 +241,6 @@ def author_view(self, context=None): def student_view_data(self): """ Returns a JSON representation of the student_view of this XBlock. - Returns a JSON representation of the student_view of this XBlock. """ return {'topic_id': self.discussion_id} @@ -289,47 +288,3 @@ def _apply_metadata_and_policy(cls, block, node, runtime): if field_name in block.fields: setattr(block, field_name, value) return {'topic_id': cls.discussion_id} - - @classmethod - def parse_xml(cls, node, runtime, keys): - """ - Parses OLX into XBlock. - - This method is overridden here to allow parsing legacy OLX, coming from discussion XModule. - XBlock stores all the associated data, fields and children in a XML element inlined into vertical XML file - XModule stored only minimal data on the element included into vertical XML and used a dedicated "discussion" - folder in OLX to store fields and children. Also, some info was put into "policy.json" file. - - If no external data sources are found (file in "discussion" folder), it is exactly equivalent to base method - XBlock.parse_xml. Otherwise this method parses file in "discussion" folder (known as definition_xml), applies - policy.json and updates fields accordingly. - """ - block = super().parse_xml(node, runtime, keys) - - cls._apply_metadata_and_policy(block, node, runtime) - - return block - - @classmethod - def _apply_metadata_and_policy(cls, block, node, runtime): - """ - Attempt to load definition XML from "discussion" folder in OLX, than parse it and update block fields - """ - if node.get('url_name') is None: - return # Newer/XBlock XML format - no need to load an additional file. - try: - definition_xml, _ = cls.load_definition_xml(node, runtime, block.scope_ids.def_id) - except Exception as err: # pylint: disable=broad-except - log.info( - "Exception %s when trying to load definition xml for block %s - assuming XBlock export format", - err, - block - ) - return - - metadata = cls.load_metadata(definition_xml) - cls.apply_policy(metadata, runtime.get_policy(block.scope_ids.usage_id)) - - for field_name, value in metadata.items(): - if field_name in block.fields: - setattr(block, field_name, value) From ea44307e20b844aba1a24ea433612d58108ecbd6 Mon Sep 17 00:00:00 2001 From: salman2013 Date: Thu, 19 Feb 2026 23:29:38 +0500 Subject: [PATCH 4/8] fix: resove conflicts --- xblocks_contrib/discussion/discussion.py | 1 - 1 file changed, 1 deletion(-) diff --git a/xblocks_contrib/discussion/discussion.py b/xblocks_contrib/discussion/discussion.py index e601b4b0..f553ea43 100644 --- a/xblocks_contrib/discussion/discussion.py +++ b/xblocks_contrib/discussion/discussion.py @@ -287,4 +287,3 @@ def _apply_metadata_and_policy(cls, block, node, runtime): for field_name, value in metadata.items(): if field_name in block.fields: setattr(block, field_name, value) - return {'topic_id': cls.discussion_id} From 07ea52205e5df45a8d98f1eb4d5db5ba310bf66c Mon Sep 17 00:00:00 2001 From: salman2013 Date: Fri, 20 Feb 2026 16:08:28 +0500 Subject: [PATCH 5/8] fix: fix comments and sync package versions with platform --- xblocks_contrib/discussion/package-lock.json | 229 ++++++++++++++---- xblocks_contrib/discussion/package.json | 9 +- .../discussion/webpack.common.config.js | 2 +- .../discussion/webpack.dev.config.js | 2 +- 4 files changed, 186 insertions(+), 56 deletions(-) diff --git a/xblocks_contrib/discussion/package-lock.json b/xblocks_contrib/discussion/package-lock.json index a2417187..ee66b584 100644 --- a/xblocks_contrib/discussion/package-lock.json +++ b/xblocks_contrib/discussion/package-lock.json @@ -6,10 +6,13 @@ "": { "devDependencies": { "append-prepend-loader": "^1.0.0", + "backbone": "^1", + "backbone-associations": "^0.6", + "backbone.paginator": "^2", "copy-webpack-plugin": "13.0.1", - "imports-loader": "^5.0.0", - "webpack": "^5.90.0", - "webpack-cli": "^5.1.4" + "imports-loader": "^0.8", + "webpack": "^5", + "webpack-cli": "^5" } }, "node_modules/@discoveryjs/json-ext": { @@ -387,6 +390,35 @@ "webpack": "*" } }, + "node_modules/backbone": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.6.1.tgz", + "integrity": "sha512-YQzWxOrIgL6BoFnZjThVN99smKYhyEXXFyJJ2lsF1wJLyo4t+QjmkLrH8/fN22FZ4ykF70Xq7PgTugJVR4zS9Q==", + "dev": true, + "dependencies": { + "underscore": ">=1.8.3" + } + }, + "node_modules/backbone-associations": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/backbone-associations/-/backbone-associations-0.6.2.tgz", + "integrity": "sha512-mE9eNMy+fLbFa8Gf9WNdo3+uwjUIuNoXmGT5NNlZ7Dyu0KP3Y0FHq5OFVxJx+owlbd+olWzUFL3TdhfihcqlSA==", + "dev": true, + "dependencies": { + "backbone": ">=1.0.0", + "underscore": ">=1.4.4" + } + }, + "node_modules/backbone.paginator": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/backbone.paginator/-/backbone.paginator-2.0.8.tgz", + "integrity": "sha512-8XS2CTbjnwMbJ/3Traa1te2RPecOGbZ9tc52T89pzo6NXlVEJDFnC++dp7CQLBUZpgk3g0veX8mUbEF4wbD2NQ==", + "dev": true, + "dependencies": { + "backbone": "1.1.2 || 1.2.3 || ^1.3.2", + "underscore": "^1.8.0" + } + }, "node_modules/baseline-browser-mapping": { "version": "2.9.19", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", @@ -396,6 +428,15 @@ "baseline-browser-mapping": "dist/cli.js" } }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", @@ -533,6 +574,15 @@ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", "dev": true }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/enhanced-resolve": { "version": "5.19.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", @@ -769,23 +819,16 @@ } }, "node_modules/imports-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-5.0.0.tgz", - "integrity": "sha512-tXgL8xxZFjOjQLLiE7my00UUQfktg4G8fdpXcZphL0bJWbk9eCxKKFaCwmFRcwyRJQl95GXBL1DoE1rCS/tcPw==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.8.0.tgz", + "integrity": "sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ==", "dev": true, "dependencies": { - "source-map-js": "^1.0.2", - "strip-comments": "^2.0.1" + "loader-utils": "^1.0.2", + "source-map": "^0.6.1" }, "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" + "node": ">= 4" } }, "node_modules/interpret": { @@ -886,6 +929,18 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -908,6 +963,20 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -947,6 +1016,15 @@ "node": ">= 0.6" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -1219,15 +1297,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -1238,15 +1307,6 @@ "source-map": "^0.6.0" } }, - "node_modules/strip-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", - "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -1355,6 +1415,12 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/underscore": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", + "dev": true + }, "node_modules/undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", @@ -1870,12 +1936,47 @@ "dev": true, "requires": {} }, + "backbone": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.6.1.tgz", + "integrity": "sha512-YQzWxOrIgL6BoFnZjThVN99smKYhyEXXFyJJ2lsF1wJLyo4t+QjmkLrH8/fN22FZ4ykF70Xq7PgTugJVR4zS9Q==", + "dev": true, + "requires": { + "underscore": ">=1.8.3" + } + }, + "backbone-associations": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/backbone-associations/-/backbone-associations-0.6.2.tgz", + "integrity": "sha512-mE9eNMy+fLbFa8Gf9WNdo3+uwjUIuNoXmGT5NNlZ7Dyu0KP3Y0FHq5OFVxJx+owlbd+olWzUFL3TdhfihcqlSA==", + "dev": true, + "requires": { + "backbone": ">=1.0.0", + "underscore": ">=1.4.4" + } + }, + "backbone.paginator": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/backbone.paginator/-/backbone.paginator-2.0.8.tgz", + "integrity": "sha512-8XS2CTbjnwMbJ/3Traa1te2RPecOGbZ9tc52T89pzo6NXlVEJDFnC++dp7CQLBUZpgk3g0veX8mUbEF4wbD2NQ==", + "dev": true, + "requires": { + "backbone": "1.1.2 || 1.2.3 || ^1.3.2", + "underscore": "^1.8.0" + } + }, "baseline-browser-mapping": { "version": "2.9.19", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", "dev": true }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, "browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", @@ -1960,6 +2061,12 @@ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", "dev": true }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, "enhanced-resolve": { "version": "5.19.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", @@ -2121,13 +2228,13 @@ } }, "imports-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-5.0.0.tgz", - "integrity": "sha512-tXgL8xxZFjOjQLLiE7my00UUQfktg4G8fdpXcZphL0bJWbk9eCxKKFaCwmFRcwyRJQl95GXBL1DoE1rCS/tcPw==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.8.0.tgz", + "integrity": "sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ==", "dev": true, "requires": { - "source-map-js": "^1.0.2", - "strip-comments": "^2.0.1" + "loader-utils": "^1.0.2", + "source-map": "^0.6.1" } }, "interpret": { @@ -2204,6 +2311,15 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -2216,6 +2332,17 @@ "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true }, + "loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2246,6 +2373,12 @@ "mime-db": "1.52.0" } }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -2434,12 +2567,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true - }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -2450,12 +2577,6 @@ "source-map": "^0.6.0" } }, - "strip-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", - "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", - "dev": true - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -2512,6 +2633,12 @@ "picomatch": "^4.0.3" } }, + "underscore": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", + "dev": true + }, "undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", diff --git a/xblocks_contrib/discussion/package.json b/xblocks_contrib/discussion/package.json index 71273a94..88800f1c 100644 --- a/xblocks_contrib/discussion/package.json +++ b/xblocks_contrib/discussion/package.json @@ -5,10 +5,13 @@ "build-dev": "webpack --config webpack.dev.config.js" }, "devDependencies": { + "backbone": "^1", + "backbone-associations": "^0.6", + "backbone.paginator": "^2", "append-prepend-loader": "^1.0.0", "copy-webpack-plugin": "13.0.1", - "imports-loader": "^5.0.0", - "webpack": "^5.90.0", - "webpack-cli": "^5.1.4" + "imports-loader": "^0.8", + "webpack": "^5", + "webpack-cli": "^5" } } diff --git a/xblocks_contrib/discussion/webpack.common.config.js b/xblocks_contrib/discussion/webpack.common.config.js index d34f9232..ff967390 100644 --- a/xblocks_contrib/discussion/webpack.common.config.js +++ b/xblocks_contrib/discussion/webpack.common.config.js @@ -54,7 +54,7 @@ const config = { use: [ { loader: 'imports-loader', - options: { wrapper: 'window' }, + options: 'this=>window' }, ], }, diff --git a/xblocks_contrib/discussion/webpack.dev.config.js b/xblocks_contrib/discussion/webpack.dev.config.js index 5b012cbc..f36e69c4 100644 --- a/xblocks_contrib/discussion/webpack.dev.config.js +++ b/xblocks_contrib/discussion/webpack.dev.config.js @@ -16,4 +16,4 @@ module.exports = merge(commonConfig, { 'CAPTIONS_CONTENT_REPLACEMENT': JSON.stringify(process.env.CAPTIONS_CONTENT_REPLACEMENT || '') }) ] -}); \ No newline at end of file +}); From 6e4a9d3467c767994afc3f1b81db337f15d1939f Mon Sep 17 00:00:00 2001 From: salman2013 Date: Fri, 20 Feb 2026 18:42:46 +0500 Subject: [PATCH 6/8] fix: move static folder and webpack config into assets folder --- package-lock.json | 1620 ++++++++++ .../discussion/{ => assets}/package.json | 0 .../static/css/inline-discussion-rtl.css | 0 .../static/css/inline-discussion.css | 0 .../{ => assets}/static/js/common/content.js | 0 .../static/js/common/discussion.js | 0 .../static/js/common/mathjax_include.js | 0 .../models/discussion_course_settings.js | 0 .../js/common/models/discussion_user.js | 0 .../{ => assets}/static/js/common/utils.js | 0 .../common/views/discussion_content_view.js | 0 .../js/common/views/discussion_inline_view.js | 0 .../views/discussion_thread_edit_view.js | 0 .../views/discussion_thread_list_view.js | 0 .../views/discussion_thread_profile_view.js | 0 .../views/discussion_thread_show_view.js | 0 .../js/common/views/discussion_thread_view.js | 0 .../views/discussion_topic_menu_view.js | 0 .../static/js/common/views/new_post_view.js | 0 .../views/response_comment_edit_view.js | 0 .../views/response_comment_show_view.js | 0 .../js/common/views/response_comment_view.js | 0 .../common/views/thread_response_edit_view.js | 0 .../common/views/thread_response_show_view.js | 0 .../js/common/views/thread_response_view.js | 0 .../{ => assets}/static/js/customwmd.js | 0 .../{ => assets}/static/js/discussion_main.js | 0 .../static/js/mathjax_accessible.js | 0 .../static/js/mathjax_delay_renderer.js | 0 .../static/js/vendor/Markdown.Converter.js | 0 .../static/js/vendor/Markdown.Editor.js | 0 .../static/js/vendor/Markdown.Sanitizer.js | 0 .../static/js/vendor/jquery.ajaxfileupload.js | 0 .../static/js/vendor/jquery.timeago.js | 0 .../static/js/vendor/jquery.timeago.locale.js | 0 .../static/js/vendor/jquery.truncate.js | 0 .../{ => assets}/static/js/vendor/split.js | 0 .../{ => assets}/webpack.common.config.js | 6 +- .../{ => assets}/webpack.dev.config.js | 0 .../{ => assets}/webpack.prod.config.js | 0 xblocks_contrib/discussion/package-lock.json | 2763 ----------------- 41 files changed, 1623 insertions(+), 2766 deletions(-) rename xblocks_contrib/discussion/{ => assets}/package.json (100%) rename xblocks_contrib/discussion/{ => assets}/static/css/inline-discussion-rtl.css (100%) rename xblocks_contrib/discussion/{ => assets}/static/css/inline-discussion.css (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/content.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/discussion.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/mathjax_include.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/models/discussion_course_settings.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/models/discussion_user.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/utils.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/discussion_content_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/discussion_inline_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/discussion_thread_edit_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/discussion_thread_list_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/discussion_thread_profile_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/discussion_thread_show_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/discussion_thread_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/discussion_topic_menu_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/new_post_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/response_comment_edit_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/response_comment_show_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/response_comment_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/thread_response_edit_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/thread_response_show_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/common/views/thread_response_view.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/customwmd.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/discussion_main.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/mathjax_accessible.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/mathjax_delay_renderer.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/vendor/Markdown.Converter.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/vendor/Markdown.Editor.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/vendor/Markdown.Sanitizer.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/vendor/jquery.ajaxfileupload.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/vendor/jquery.timeago.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/vendor/jquery.timeago.locale.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/vendor/jquery.truncate.js (100%) rename xblocks_contrib/discussion/{ => assets}/static/js/vendor/split.js (100%) rename xblocks_contrib/discussion/{ => assets}/webpack.common.config.js (91%) rename xblocks_contrib/discussion/{ => assets}/webpack.dev.config.js (100%) rename xblocks_contrib/discussion/{ => assets}/webpack.prod.config.js (100%) delete mode 100644 xblocks_contrib/discussion/package-lock.json diff --git a/package-lock.json b/package-lock.json index 8da32e8d..dba91ced 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,1626 @@ "workspaces": [ "xblocks_contrib/*/*" ] + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz", + "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", + "dev": true, + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/append-prepend-loader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-prepend-loader/-/append-prepend-loader-1.0.0.tgz", + "integrity": "sha512-TpqFKoWUJZgo69yFD+EZ+NBhEVAVT6LK5vgMbBEyHd65a33v/ECNq7H8THzL4eobBZaaJ21bVg5ruJeYxTSsYw==", + "dev": true, + "peerDependencies": { + "webpack": "*" + } + }, + "node_modules/assets": { + "resolved": "xblocks_contrib/discussion/assets", + "link": true + }, + "node_modules/backbone": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.6.1.tgz", + "integrity": "sha512-YQzWxOrIgL6BoFnZjThVN99smKYhyEXXFyJJ2lsF1wJLyo4t+QjmkLrH8/fN22FZ4ykF70Xq7PgTugJVR4zS9Q==", + "dev": true, + "dependencies": { + "underscore": ">=1.8.3" + } + }, + "node_modules/backbone-associations": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/backbone-associations/-/backbone-associations-0.6.2.tgz", + "integrity": "sha512-mE9eNMy+fLbFa8Gf9WNdo3+uwjUIuNoXmGT5NNlZ7Dyu0KP3Y0FHq5OFVxJx+owlbd+olWzUFL3TdhfihcqlSA==", + "dev": true, + "dependencies": { + "backbone": ">=1.0.0", + "underscore": ">=1.4.4" + } + }, + "node_modules/backbone.paginator": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/backbone.paginator/-/backbone.paginator-2.0.8.tgz", + "integrity": "sha512-8XS2CTbjnwMbJ/3Traa1te2RPecOGbZ9tc52T89pzo6NXlVEJDFnC++dp7CQLBUZpgk3g0veX8mUbEF4wbD2NQ==", + "dev": true, + "dependencies": { + "backbone": "1.1.2 || 1.2.3 || ^1.3.2", + "underscore": "^1.8.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "dev": true, + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001770", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", + "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "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/copy-webpack-plugin": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz", + "integrity": "sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==", + "dev": true, + "dependencies": { + "glob-parent": "^6.0.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2", + "tinyglobby": "^0.2.12" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.302", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", + "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imports-loader": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.8.0.tgz", + "integrity": "sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ==", + "dev": true, + "dependencies": { + "loader-utils": "^1.0.2", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "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/loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "dev": true, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/underscore": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", + "dev": true + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.105.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.2.tgz", + "integrity": "sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.3.1", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", + "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "xblocks_contrib/discussion/assets": { + "devDependencies": { + "append-prepend-loader": "^1.0.0", + "backbone": "^1", + "backbone-associations": "^0.6", + "backbone.paginator": "^2", + "copy-webpack-plugin": "13.0.1", + "imports-loader": "^0.8", + "webpack": "^5", + "webpack-cli": "^5" + } } } } diff --git a/xblocks_contrib/discussion/package.json b/xblocks_contrib/discussion/assets/package.json similarity index 100% rename from xblocks_contrib/discussion/package.json rename to xblocks_contrib/discussion/assets/package.json diff --git a/xblocks_contrib/discussion/static/css/inline-discussion-rtl.css b/xblocks_contrib/discussion/assets/static/css/inline-discussion-rtl.css similarity index 100% rename from xblocks_contrib/discussion/static/css/inline-discussion-rtl.css rename to xblocks_contrib/discussion/assets/static/css/inline-discussion-rtl.css diff --git a/xblocks_contrib/discussion/static/css/inline-discussion.css b/xblocks_contrib/discussion/assets/static/css/inline-discussion.css similarity index 100% rename from xblocks_contrib/discussion/static/css/inline-discussion.css rename to xblocks_contrib/discussion/assets/static/css/inline-discussion.css diff --git a/xblocks_contrib/discussion/static/js/common/content.js b/xblocks_contrib/discussion/assets/static/js/common/content.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/content.js rename to xblocks_contrib/discussion/assets/static/js/common/content.js diff --git a/xblocks_contrib/discussion/static/js/common/discussion.js b/xblocks_contrib/discussion/assets/static/js/common/discussion.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/discussion.js rename to xblocks_contrib/discussion/assets/static/js/common/discussion.js diff --git a/xblocks_contrib/discussion/static/js/common/mathjax_include.js b/xblocks_contrib/discussion/assets/static/js/common/mathjax_include.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/mathjax_include.js rename to xblocks_contrib/discussion/assets/static/js/common/mathjax_include.js diff --git a/xblocks_contrib/discussion/static/js/common/models/discussion_course_settings.js b/xblocks_contrib/discussion/assets/static/js/common/models/discussion_course_settings.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/models/discussion_course_settings.js rename to xblocks_contrib/discussion/assets/static/js/common/models/discussion_course_settings.js diff --git a/xblocks_contrib/discussion/static/js/common/models/discussion_user.js b/xblocks_contrib/discussion/assets/static/js/common/models/discussion_user.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/models/discussion_user.js rename to xblocks_contrib/discussion/assets/static/js/common/models/discussion_user.js diff --git a/xblocks_contrib/discussion/static/js/common/utils.js b/xblocks_contrib/discussion/assets/static/js/common/utils.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/utils.js rename to xblocks_contrib/discussion/assets/static/js/common/utils.js diff --git a/xblocks_contrib/discussion/static/js/common/views/discussion_content_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/discussion_content_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/discussion_content_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/discussion_content_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/discussion_inline_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/discussion_inline_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/discussion_inline_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/discussion_inline_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/discussion_thread_edit_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_edit_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/discussion_thread_edit_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_edit_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/discussion_thread_list_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_list_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/discussion_thread_list_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_list_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/discussion_thread_profile_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_profile_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/discussion_thread_profile_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_profile_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/discussion_thread_show_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_show_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/discussion_thread_show_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_show_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/discussion_thread_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/discussion_thread_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/discussion_thread_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/discussion_topic_menu_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/discussion_topic_menu_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/discussion_topic_menu_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/discussion_topic_menu_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/new_post_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/new_post_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/new_post_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/new_post_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/response_comment_edit_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/response_comment_edit_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/response_comment_edit_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/response_comment_edit_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/response_comment_show_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/response_comment_show_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/response_comment_show_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/response_comment_show_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/response_comment_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/response_comment_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/response_comment_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/response_comment_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/thread_response_edit_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/thread_response_edit_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/thread_response_edit_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/thread_response_edit_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/thread_response_show_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/thread_response_show_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/thread_response_show_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/thread_response_show_view.js diff --git a/xblocks_contrib/discussion/static/js/common/views/thread_response_view.js b/xblocks_contrib/discussion/assets/static/js/common/views/thread_response_view.js similarity index 100% rename from xblocks_contrib/discussion/static/js/common/views/thread_response_view.js rename to xblocks_contrib/discussion/assets/static/js/common/views/thread_response_view.js diff --git a/xblocks_contrib/discussion/static/js/customwmd.js b/xblocks_contrib/discussion/assets/static/js/customwmd.js similarity index 100% rename from xblocks_contrib/discussion/static/js/customwmd.js rename to xblocks_contrib/discussion/assets/static/js/customwmd.js diff --git a/xblocks_contrib/discussion/static/js/discussion_main.js b/xblocks_contrib/discussion/assets/static/js/discussion_main.js similarity index 100% rename from xblocks_contrib/discussion/static/js/discussion_main.js rename to xblocks_contrib/discussion/assets/static/js/discussion_main.js diff --git a/xblocks_contrib/discussion/static/js/mathjax_accessible.js b/xblocks_contrib/discussion/assets/static/js/mathjax_accessible.js similarity index 100% rename from xblocks_contrib/discussion/static/js/mathjax_accessible.js rename to xblocks_contrib/discussion/assets/static/js/mathjax_accessible.js diff --git a/xblocks_contrib/discussion/static/js/mathjax_delay_renderer.js b/xblocks_contrib/discussion/assets/static/js/mathjax_delay_renderer.js similarity index 100% rename from xblocks_contrib/discussion/static/js/mathjax_delay_renderer.js rename to xblocks_contrib/discussion/assets/static/js/mathjax_delay_renderer.js diff --git a/xblocks_contrib/discussion/static/js/vendor/Markdown.Converter.js b/xblocks_contrib/discussion/assets/static/js/vendor/Markdown.Converter.js similarity index 100% rename from xblocks_contrib/discussion/static/js/vendor/Markdown.Converter.js rename to xblocks_contrib/discussion/assets/static/js/vendor/Markdown.Converter.js diff --git a/xblocks_contrib/discussion/static/js/vendor/Markdown.Editor.js b/xblocks_contrib/discussion/assets/static/js/vendor/Markdown.Editor.js similarity index 100% rename from xblocks_contrib/discussion/static/js/vendor/Markdown.Editor.js rename to xblocks_contrib/discussion/assets/static/js/vendor/Markdown.Editor.js diff --git a/xblocks_contrib/discussion/static/js/vendor/Markdown.Sanitizer.js b/xblocks_contrib/discussion/assets/static/js/vendor/Markdown.Sanitizer.js similarity index 100% rename from xblocks_contrib/discussion/static/js/vendor/Markdown.Sanitizer.js rename to xblocks_contrib/discussion/assets/static/js/vendor/Markdown.Sanitizer.js diff --git a/xblocks_contrib/discussion/static/js/vendor/jquery.ajaxfileupload.js b/xblocks_contrib/discussion/assets/static/js/vendor/jquery.ajaxfileupload.js similarity index 100% rename from xblocks_contrib/discussion/static/js/vendor/jquery.ajaxfileupload.js rename to xblocks_contrib/discussion/assets/static/js/vendor/jquery.ajaxfileupload.js diff --git a/xblocks_contrib/discussion/static/js/vendor/jquery.timeago.js b/xblocks_contrib/discussion/assets/static/js/vendor/jquery.timeago.js similarity index 100% rename from xblocks_contrib/discussion/static/js/vendor/jquery.timeago.js rename to xblocks_contrib/discussion/assets/static/js/vendor/jquery.timeago.js diff --git a/xblocks_contrib/discussion/static/js/vendor/jquery.timeago.locale.js b/xblocks_contrib/discussion/assets/static/js/vendor/jquery.timeago.locale.js similarity index 100% rename from xblocks_contrib/discussion/static/js/vendor/jquery.timeago.locale.js rename to xblocks_contrib/discussion/assets/static/js/vendor/jquery.timeago.locale.js diff --git a/xblocks_contrib/discussion/static/js/vendor/jquery.truncate.js b/xblocks_contrib/discussion/assets/static/js/vendor/jquery.truncate.js similarity index 100% rename from xblocks_contrib/discussion/static/js/vendor/jquery.truncate.js rename to xblocks_contrib/discussion/assets/static/js/vendor/jquery.truncate.js diff --git a/xblocks_contrib/discussion/static/js/vendor/split.js b/xblocks_contrib/discussion/assets/static/js/vendor/split.js similarity index 100% rename from xblocks_contrib/discussion/static/js/vendor/split.js rename to xblocks_contrib/discussion/assets/static/js/vendor/split.js diff --git a/xblocks_contrib/discussion/webpack.common.config.js b/xblocks_contrib/discussion/assets/webpack.common.config.js similarity index 91% rename from xblocks_contrib/discussion/webpack.common.config.js rename to xblocks_contrib/discussion/assets/webpack.common.config.js index ff967390..ddce76e5 100644 --- a/xblocks_contrib/discussion/webpack.common.config.js +++ b/xblocks_contrib/discussion/assets/webpack.common.config.js @@ -9,7 +9,7 @@ const config = { context: discussionRoot, entry: './static/js/discussion_main.js', output: { - path: path.join(__dirname, 'public', 'js'), + path: path.join(__dirname, '..', 'public', 'js'), filename: 'discussion_bundle.js', }, resolve: { @@ -74,8 +74,8 @@ const config = { plugins: [ new CopyWebpackPlugin({ patterns: [ - { from: path.join(staticCss, 'inline-discussion.css'), to: path.join(discussionRoot, 'public', 'css', 'inline-discussion.css') }, - { from: path.join(staticCss, 'inline-discussion-rtl.css'), to: path.join(discussionRoot, 'public', 'css', 'inline-discussion-rtl.css') }, + { from: path.join(staticCss, 'inline-discussion.css'), to: path.join(__dirname, '..', 'public', 'css', 'inline-discussion.css') }, + { from: path.join(staticCss, 'inline-discussion-rtl.css'), to: path.join(__dirname, '..', 'public', 'css', 'inline-discussion-rtl.css') }, ], }), ], diff --git a/xblocks_contrib/discussion/webpack.dev.config.js b/xblocks_contrib/discussion/assets/webpack.dev.config.js similarity index 100% rename from xblocks_contrib/discussion/webpack.dev.config.js rename to xblocks_contrib/discussion/assets/webpack.dev.config.js diff --git a/xblocks_contrib/discussion/webpack.prod.config.js b/xblocks_contrib/discussion/assets/webpack.prod.config.js similarity index 100% rename from xblocks_contrib/discussion/webpack.prod.config.js rename to xblocks_contrib/discussion/assets/webpack.prod.config.js diff --git a/xblocks_contrib/discussion/package-lock.json b/xblocks_contrib/discussion/package-lock.json deleted file mode 100644 index ee66b584..00000000 --- a/xblocks_contrib/discussion/package-lock.json +++ /dev/null @@ -1,2763 +0,0 @@ -{ - "name": "discussion", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "devDependencies": { - "append-prepend-loader": "^1.0.0", - "backbone": "^1", - "backbone-associations": "^0.6", - "backbone.paginator": "^2", - "copy-webpack-plugin": "13.0.1", - "imports-loader": "^0.8", - "webpack": "^5", - "webpack-cli": "^5" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "25.2.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.1.tgz", - "integrity": "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==", - "dev": true, - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.0" - } - }, - "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/append-prepend-loader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-prepend-loader/-/append-prepend-loader-1.0.0.tgz", - "integrity": "sha512-TpqFKoWUJZgo69yFD+EZ+NBhEVAVT6LK5vgMbBEyHd65a33v/ECNq7H8THzL4eobBZaaJ21bVg5ruJeYxTSsYw==", - "dev": true, - "peerDependencies": { - "webpack": "*" - } - }, - "node_modules/backbone": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.6.1.tgz", - "integrity": "sha512-YQzWxOrIgL6BoFnZjThVN99smKYhyEXXFyJJ2lsF1wJLyo4t+QjmkLrH8/fN22FZ4ykF70Xq7PgTugJVR4zS9Q==", - "dev": true, - "dependencies": { - "underscore": ">=1.8.3" - } - }, - "node_modules/backbone-associations": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/backbone-associations/-/backbone-associations-0.6.2.tgz", - "integrity": "sha512-mE9eNMy+fLbFa8Gf9WNdo3+uwjUIuNoXmGT5NNlZ7Dyu0KP3Y0FHq5OFVxJx+owlbd+olWzUFL3TdhfihcqlSA==", - "dev": true, - "dependencies": { - "backbone": ">=1.0.0", - "underscore": ">=1.4.4" - } - }, - "node_modules/backbone.paginator": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/backbone.paginator/-/backbone.paginator-2.0.8.tgz", - "integrity": "sha512-8XS2CTbjnwMbJ/3Traa1te2RPecOGbZ9tc52T89pzo6NXlVEJDFnC++dp7CQLBUZpgk3g0veX8mUbEF4wbD2NQ==", - "dev": true, - "dependencies": { - "backbone": "1.1.2 || 1.2.3 || ^1.3.2", - "underscore": "^1.8.0" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.9.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", - "dev": true, - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001769", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", - "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "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/copy-webpack-plugin": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz", - "integrity": "sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==", - "dev": true, - "dependencies": { - "glob-parent": "^6.0.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.2.0", - "serialize-javascript": "^6.0.2", - "tinyglobby": "^0.2.12" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.286", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", - "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", - "dev": true - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", - "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/envinfo": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", - "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ] - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imports-loader": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.8.0.tgz", - "integrity": "sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ==", - "dev": true, - "dependencies": { - "loader-utils": "^1.0.2", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "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/loader-runner": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", - "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", - "dev": true, - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dev": true, - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", - "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.16", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", - "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/underscore": { - "version": "1.13.8", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", - "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", - "dev": true - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true - }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/watchpack": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", - "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", - "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack": { - "version": "5.105.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", - "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.28.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.19.0", - "es-module-lexer": "^2.0.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.3.1", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.16", - "watchpack": "^2.5.1", - "webpack-sources": "^3.3.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - } - }, - "dependencies": { - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true - }, - "@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true - }, - "@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "@types/node": { - "version": "25.2.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.1.tgz", - "integrity": "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==", - "dev": true, - "requires": { - "undici-types": "~7.16.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "requires": {} - }, - "@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "requires": {} - }, - "@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "requires": {} - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true - }, - "acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "dev": true, - "requires": {} - }, - "ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "append-prepend-loader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-prepend-loader/-/append-prepend-loader-1.0.0.tgz", - "integrity": "sha512-TpqFKoWUJZgo69yFD+EZ+NBhEVAVT6LK5vgMbBEyHd65a33v/ECNq7H8THzL4eobBZaaJ21bVg5ruJeYxTSsYw==", - "dev": true, - "requires": {} - }, - "backbone": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.6.1.tgz", - "integrity": "sha512-YQzWxOrIgL6BoFnZjThVN99smKYhyEXXFyJJ2lsF1wJLyo4t+QjmkLrH8/fN22FZ4ykF70Xq7PgTugJVR4zS9Q==", - "dev": true, - "requires": { - "underscore": ">=1.8.3" - } - }, - "backbone-associations": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/backbone-associations/-/backbone-associations-0.6.2.tgz", - "integrity": "sha512-mE9eNMy+fLbFa8Gf9WNdo3+uwjUIuNoXmGT5NNlZ7Dyu0KP3Y0FHq5OFVxJx+owlbd+olWzUFL3TdhfihcqlSA==", - "dev": true, - "requires": { - "backbone": ">=1.0.0", - "underscore": ">=1.4.4" - } - }, - "backbone.paginator": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/backbone.paginator/-/backbone.paginator-2.0.8.tgz", - "integrity": "sha512-8XS2CTbjnwMbJ/3Traa1te2RPecOGbZ9tc52T89pzo6NXlVEJDFnC++dp7CQLBUZpgk3g0veX8mUbEF4wbD2NQ==", - "dev": true, - "requires": { - "backbone": "1.1.2 || 1.2.3 || ^1.3.2", - "underscore": "^1.8.0" - } - }, - "baseline-browser-mapping": { - "version": "2.9.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, - "requires": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001769", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", - "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "dev": true - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "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 - }, - "copy-webpack-plugin": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.1.tgz", - "integrity": "sha512-J+YV3WfhY6W/Xf9h+J1znYuqTye2xkBUIGyTPWuBAT27qajBa5mR4f8WBmfDY3YjRftT2kqZZiLi1qf0H+UOFw==", - "dev": true, - "requires": { - "glob-parent": "^6.0.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.2.0", - "serialize-javascript": "^6.0.2", - "tinyglobby": "^0.2.12" - } - }, - "cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "electron-to-chromium": { - "version": "1.5.286", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", - "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "enhanced-resolve": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", - "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" - } - }, - "envinfo": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", - "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", - "dev": true - }, - "es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "dev": true - }, - "escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true - }, - "fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "requires": {} - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imports-loader": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.8.0.tgz", - "integrity": "sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "source-map": "^0.6.1" - } - }, - "interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true - }, - "is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "requires": { - "hasown": "^2.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "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 - }, - "loader-runner": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", - "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", - "dev": true - }, - "loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - }, - "picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "requires": { - "resolve": "^1.20.0" - } - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dev": true, - "requires": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - } - }, - "serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "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 - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", - "dev": true - }, - "terser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", - "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - } - }, - "terser-webpack-plugin": { - "version": "5.3.16", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", - "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", - "terser": "^5.31.1" - } - }, - "tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "requires": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - } - }, - "underscore": { - "version": "1.13.8", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", - "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", - "dev": true - }, - "undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "requires": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - } - }, - "watchpack": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", - "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "webpack": { - "version": "5.105.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", - "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.28.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.19.0", - "es-module-lexer": "^2.0.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.3.1", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.16", - "watchpack": "^2.5.1", - "webpack-sources": "^3.3.3" - } - }, - "webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true - } - } - }, - "webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - } - } -} From 693c11f8c6f6e06c8a8ecc41774ed606eaa6de55 Mon Sep 17 00:00:00 2001 From: salman2013 Date: Tue, 17 Mar 2026 23:26:08 +0500 Subject: [PATCH 7/8] fix: update css url --- xblocks_contrib/discussion/discussion.py | 37 ++++++++++-------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/xblocks_contrib/discussion/discussion.py b/xblocks_contrib/discussion/discussion.py index 3a28dda0..3b2d3080 100644 --- a/xblocks_contrib/discussion/discussion.py +++ b/xblocks_contrib/discussion/discussion.py @@ -114,22 +114,6 @@ def is_visible(self): """ return self.discussion_config.is_discussion_visible(self.course_key) - @staticmethod - def _discussion_js_resource_path(): - """ - Returns the URL for the local resource. - - Note: when running with the full Django pipeline, the file will be accessed - as a static asset which will use a CDN in production. - - For more details, see platform's xblock_local_resource_url() define in: - https://github.com/openedx/openedx-platform/blob/master/openedx/core/lib/xblock_utils/__init__.py - """ - if settings.PIPELINE.get('PIPELINE_ENABLED', False) or not getattr(settings, 'REQUIRE_DEBUG', False): - return 'discussion/public/js/discussion_bundle.js' - else: - return 'public/js/discussion_bundle.js' - @property def django_user(self): """ @@ -147,15 +131,24 @@ def add_resource_urls(self, fragment): """ css_file_path = ( - 'public/css/inline-discussion-rtl.css' + '/css/inline-discussion-rtl.css' if get_language_bidi() - else 'public/css/inline-discussion.css' + else '/css/inline-discussion.css' ) - fragment.add_css_url(self.runtime.local_resource_url(self, css_file_path)) - bundle_path = self._discussion_js_resource_path() - bundle_url = self.runtime.local_resource_url(self, bundle_path) - fragment.add_resource_url(bundle_url, 'application/javascript') + # Determine how static assets should be served based on Django settings. + # Open edX requires different asset paths for production vs. local development. + pipeline = getattr(settings, "PIPELINE", {}) + use_pipeline = pipeline.get("PIPELINE_ENABLED", True) or not getattr(settings, "REQUIRE_DEBUG", False) + + # When the Django pipeline is active (production), XBlock assets are namespaced + # using the package scope (e.g., "discussion/public"). + # When inactive (local dev fallback), they are served directly from "public". + # https://github.com/openedx/openedx-platform/blob/master/openedx/core/lib/xblock_utils/__init__.py#L417 + base_path = "discussion/public" if use_pipeline else "public" + + fragment.add_css_url(self.runtime.local_resource_url(self, f"{base_path}{css_file_path}")) + fragment.add_javascript_url(self.runtime.local_resource_url(self, f"{base_path}/js/discussion_bundle.js")) def has_permission(self, permission): # pylint: disable=unused-argument """ From 621e3d5046cb4fa1b4e899156db0577d2e7d2cc5 Mon Sep 17 00:00:00 2001 From: salmannawaz Date: Tue, 17 Mar 2026 23:48:15 +0500 Subject: [PATCH 8/8] Discussion XBlock: Javascript (karma) tests (#163) * chore: move discussion block karma tests * fix: revert some change * fix: add space --- package-lock.json | 529 ++++------- .../discussion/assets/jasmine.common.conf.js | 12 + .../discussion/assets/karma.conf.js | 112 +++ .../discussion/assets/package.json | 20 +- .../assets/static/js/vendor/URI.min.js | 47 + .../static/js/vendor/jquery.leanModal.js | 61 ++ .../assets/static/spec/content_spec.js | 158 ++++ .../static/spec/fixtures/templates.underscore | 889 ++++++++++++++++++ .../spec_helpers/discussion_spec_helper.js | 216 +++++ .../assets/static/spec/spec_helpers/i18n.js | 10 + .../assets/static/spec/utils_spec.js | 94 ++ .../spec/view/discussion_content_view_spec.js | 58 ++ .../spec/view/discussion_inline_view_spec.js | 257 +++++ .../view/discussion_thread_edit_view_spec.js | 184 ++++ .../view/discussion_thread_list_view_spec.js | 754 +++++++++++++++ .../discussion_thread_profile_view_spec.js | 151 +++ .../view/discussion_thread_show_view_spec.js | 199 ++++ .../spec/view/discussion_thread_view_spec.js | 367 ++++++++ .../view/discussion_topic_menu_view_spec.js | 110 +++ .../spec/view/discussion_view_spec_helper.js | 147 +++ .../static/spec/view/new_post_view_spec.js | 347 +++++++ .../view/response_comment_show_view_spec.js | 121 +++ .../spec/view/response_comment_view_spec.js | 204 ++++ .../view/thread_response_show_view_spec.js | 267 ++++++ .../spec/view/thread_response_view_spec.js | 149 +++ 25 files changed, 5133 insertions(+), 330 deletions(-) create mode 100644 xblocks_contrib/discussion/assets/jasmine.common.conf.js create mode 100644 xblocks_contrib/discussion/assets/karma.conf.js create mode 100644 xblocks_contrib/discussion/assets/static/js/vendor/URI.min.js create mode 100644 xblocks_contrib/discussion/assets/static/js/vendor/jquery.leanModal.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/content_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/fixtures/templates.underscore create mode 100644 xblocks_contrib/discussion/assets/static/spec/spec_helpers/discussion_spec_helper.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/spec_helpers/i18n.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/utils_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/discussion_content_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/discussion_inline_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_edit_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_list_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_profile_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_show_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/discussion_topic_menu_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/discussion_view_spec_helper.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/new_post_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/response_comment_show_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/response_comment_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/thread_response_show_view_spec.js create mode 100644 xblocks_contrib/discussion/assets/static/spec/view/thread_response_view_spec.js diff --git a/package-lock.json b/package-lock.json index a293a374..544844e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,17 +59,27 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" + "node_modules/@babel/core/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dependencies": { + "ms": "^2.1.3" }, "engines": { - "node": ">=6" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, + "node_modules/@babel/core/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/@babel/generator": { "version": "7.29.1", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", @@ -161,21 +171,21 @@ } }, "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dependencies": { "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", - "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dependencies": { "@babel/types": "^7.29.0" }, @@ -216,6 +226,27 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/@babel/types": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", @@ -1157,13 +1188,10 @@ "dev": true }, "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "engines": { - "node": "18 || 20 || >=22" - } + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/base": { "version": "0.11.2", @@ -1305,21 +1333,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/bootstrap": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", @@ -1342,15 +1355,13 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/braces": { @@ -1774,21 +1785,6 @@ "node": ">= 0.10.0" } }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/content-type": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", @@ -1879,19 +1875,12 @@ "dev": true }, "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "ms": "2.0.0" } }, "node_modules/decode-uri-component": { @@ -2051,17 +2040,6 @@ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" }, - "node_modules/edx-ui-toolkit/node_modules/requirejs": { - "version": "2.1.22", - "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.1.22.tgz", - "integrity": "sha512-AhZqN7UrWV8R2d1LfGfznskMJNF0Vb6yStwrCn52UbktJg6y5V1I7RoGRyJtACe86d50PyQn0Iw0jYDKMvc4iA==", - "bin": { - "r.js": "bin/r.js" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/edx-ui-toolkit/node_modules/underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", @@ -2144,16 +2122,6 @@ "integrity": "sha512-5NnE67nQSQDJHVahPJna1PQ/zCXMnQop3yUCxjKPNzCxuyPSKWTQ/5Gu5CZmjetwGLWRA+PzeF5thlbOdbQldA==", "dev": true }, - "node_modules/engine.io-client/node_modules/ws": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", - "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", - "dev": true, - "dependencies": { - "options": ">=0.0.5", - "ultron": "1.0.x" - } - }, "node_modules/engine.io-parser": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", @@ -2183,16 +2151,6 @@ "integrity": "sha512-5NnE67nQSQDJHVahPJna1PQ/zCXMnQop3yUCxjKPNzCxuyPSKWTQ/5Gu5CZmjetwGLWRA+PzeF5thlbOdbQldA==", "dev": true }, - "node_modules/engine.io/node_modules/ws": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", - "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", - "dev": true, - "dependencies": { - "options": ">=0.0.5", - "ultron": "1.0.x" - } - }, "node_modules/enhanced-resolve": { "version": "5.19.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", @@ -2603,21 +2561,6 @@ "node": ">= 0.8" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/finalhandler/node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -3000,34 +2943,6 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, - "node_modules/glob/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/globby": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", @@ -3292,9 +3207,9 @@ "peer": true }, "node_modules/immutable": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", - "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==" + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==" }, "node_modules/import-local": { "version": "3.2.0", @@ -3758,6 +3673,29 @@ "node": ">=10" } }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/istanbul-reports": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", @@ -3846,14 +3784,14 @@ "dev": true }, "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dependencies": { - "minimist": "^1.2.0" - }, + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/jszip": { @@ -3984,34 +3922,6 @@ "node": ">=10.0.0" } }, - "node_modules/karma-coverage/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/karma-coverage/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/karma-coverage/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/karma-firefox-launcher": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-2.1.3.tgz", @@ -4087,6 +3997,12 @@ "karma": ">=0.9" } }, + "node_modules/karma-regex-preprocessor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/karma-regex-preprocessor/-/karma-regex-preprocessor-1.0.1.tgz", + "integrity": "sha512-A+CTjK8VQZ1qZFnDMsuB7//2qWorOVuE2fnnZ2iDhv0H5Ug5Lv0I2FmolPV9KaTgJK1ipXHnSxVrG282fnoe7g==", + "dev": true + }, "node_modules/karma-requirejs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/karma-requirejs/-/karma-requirejs-1.1.0.tgz", @@ -4157,12 +4073,6 @@ "webpack": "^5.0.0" } }, - "node_modules/karma-webpack/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, "node_modules/karma-webpack/node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", @@ -4202,34 +4112,6 @@ "lodash": "^4.17.15" } }, - "node_modules/karma/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/karma/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/karma/node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/karma/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -4282,6 +4164,25 @@ "node": ">=4.0.0" } }, + "node_modules/loader-utils/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/loader-utils/node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -4562,9 +4463,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.1.tgz", - "integrity": "sha512-k7G3Y5QOegl380tXmZ68foBRRjE9Ljavx835ObdvmZjQ639izvZD8CS7BkWw1qKPPzHsGL/JDhl0uyU1zc2rJw==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.0.tgz", + "integrity": "sha512-540P2c5dYnJlyJxTaSloliZexv8rji6rY8FhQN+WF/82iHQfA23j/xtJx97L+mXOML27EqksSek/g4eK7jaL3g==", "dependencies": { "schema-utils": "^4.0.0", "tapable": "^2.2.1" @@ -4581,27 +4482,22 @@ } }, "node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "*" } }, "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==", + "dev": true }, "node_modules/mixin-deep": { "version": "1.3.2", @@ -4648,9 +4544,10 @@ } }, "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/nan": { "version": "2.25.0", @@ -4734,9 +4631,9 @@ } }, "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha512-Lbc7GfN7XFaK30bzUN3cDYLOkT0dH05S0ax1QikylHUD9+Z9PRF3G1iYwX3kcz+6AlzTFGkUgMxz6l3aUwbwTA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -4879,12 +4776,6 @@ "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": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==", - "dev": true - }, "node_modules/options": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", @@ -5372,15 +5263,6 @@ "node": ">=0.10.0" } }, - "node_modules/readdirp/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, "node_modules/readdirp/node_modules/expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -5560,12 +5442,6 @@ "node": ">=0.10.0" } }, - "node_modules/readdirp/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/readdirp/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -5675,11 +5551,10 @@ } }, "node_modules/requirejs": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.8.tgz", - "integrity": "sha512-7/cTSLOdYkNBNJcDMWf+luFvMriVm7eYxp4BcFCsAX0wF421Vyce5SXP17c+Jd5otXKGNehIonFlyQXSowL6Mw==", + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.1.22.tgz", + "integrity": "sha512-AhZqN7UrWV8R2d1LfGfznskMJNF0Vb6yStwrCn52UbktJg6y5V1I7RoGRyJtACe86d50PyQn0Iw0jYDKMvc4iA==", "bin": { - "r_js": "bin/r.js", "r.js": "bin/r.js" }, "engines": { @@ -5824,12 +5699,12 @@ "deprecated": "This package has been deprecated in favour of @sinonjs/samsam" }, "node_modules/sass": { - "version": "1.98.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.98.0.tgz", - "integrity": "sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A==", + "version": "1.97.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", + "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", "dependencies": { "chokidar": "^4.0.0", - "immutable": "^5.1.5", + "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { @@ -5912,6 +5787,38 @@ "node": ">= 20.0.0" } }, + "node_modules/selenium-webdriver/node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/selenium-webdriver/node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "dev": true, + "peer": true, + "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/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -6172,15 +6079,6 @@ "node": ">=0.10.0" } }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, "node_modules/snapdragon/node_modules/define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -6218,12 +6116,6 @@ "node": ">= 0.4" } }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/snapdragon/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -6355,15 +6247,6 @@ "integrity": "sha512-5NnE67nQSQDJHVahPJna1PQ/zCXMnQop3yUCxjKPNzCxuyPSKWTQ/5Gu5CZmjetwGLWRA+PzeF5thlbOdbQldA==", "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": "sha512-Lbc7GfN7XFaK30bzUN3cDYLOkT0dH05S0ax1QikylHUD9+Z9PRF3G1iYwX3kcz+6AlzTFGkUgMxz6l3aUwbwTA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -6639,13 +6522,15 @@ } }, "node_modules/tmp": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, - "peer": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, "engines": { - "node": ">=14.14" + "node": ">=0.6.0" } }, "node_modules/to-array": { @@ -6938,18 +6823,6 @@ "yallist": "^2.1.2" } }, - "node_modules/useragent/node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/useragent/node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", @@ -7215,25 +7088,13 @@ "dev": true }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", "dev": true, - "peer": true, - "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 - } + "dependencies": { + "options": ">=0.0.5", + "ultron": "1.0.x" } }, "node_modules/wtf-8": { @@ -7289,13 +7150,26 @@ "backbone-associations": "^0.6", "backbone.paginator": "^2", "copy-webpack-plugin": "13.0.1", + "draggabilly": "^3.0.0", + "edx-ui-toolkit": "^1", "imports-loader": "^0.8", + "jasmine-core": "2.6.4", + "jasmine-jquery": "git+https://git@github.com/velesin/jasmine-jquery.git#ebad463d592d3fea00c69f26ea18a930e09c7b58", + "jquery": "^2", + "karma": "^0.13", + "karma-chrome-launcher": "^3", + "karma-coverage": "^2", + "karma-firefox-launcher": "^2", + "karma-jasmine": "^0.3", + "karma-regex-preprocessor": "^1.0.1", + "karma-sourcemap-loader": "^0.4.0", + "karma-spec-reporter": "0.0.20", + "underscore": "^1", "webpack": "^5", "webpack-cli": "^5" } }, "xblocks_contrib/problem/assets": { - "name": "problem-xblock", "dependencies": { "babel-loader": "^9", "edx-ui-toolkit": "^1", @@ -7321,7 +7195,6 @@ } }, "xblocks_contrib/video/assets": { - "name": "video-xblock", "version": "1.0.0", "dependencies": { "draggabilly": "^3", diff --git a/xblocks_contrib/discussion/assets/jasmine.common.conf.js b/xblocks_contrib/discussion/assets/jasmine.common.conf.js new file mode 100644 index 00000000..398f544b --- /dev/null +++ b/xblocks_contrib/discussion/assets/jasmine.common.conf.js @@ -0,0 +1,12 @@ +/* eslint-env node */ + +'use strict'; + +// By default, fixtures are loaded from spec/javascripts/fixtures but in karma everything gets served from /base +jasmine.getFixtures().fixturesPath = '/base/static/spec/fixtures/'; + +// https://github.com/edx/js-test-tool/blob/master/js_test_tool/templates/jasmine_test_runner.html#L10 +// Stub out modal dialog alerts, which will prevent +// us from accessing the test results in the DOM +window.confirm = function() { return true; }; +window.alert = function() { }; diff --git a/xblocks_contrib/discussion/assets/karma.conf.js b/xblocks_contrib/discussion/assets/karma.conf.js new file mode 100644 index 00000000..af0577b3 --- /dev/null +++ b/xblocks_contrib/discussion/assets/karma.conf.js @@ -0,0 +1,112 @@ +/* eslint-env node */ +'use strict'; + +const path = require('path'); + +const discussionRoot = __dirname; +const uiToolkitRoot = path.dirname(require.resolve('edx-ui-toolkit/package.json')); + +module.exports = function (config) { + config.set({ + basePath: discussionRoot, + + frameworks: ['jasmine'], + + files: [ + { pattern: require.resolve('jquery/dist/jquery.js'), included: true }, + { pattern: require.resolve('jasmine-jquery/lib/jasmine-jquery.js'), included: true }, + { pattern: require.resolve('underscore/underscore.js'), included: true }, + { pattern: require.resolve('backbone/backbone.js'), included: true }, + { pattern: path.join(uiToolkitRoot, 'src/js/utils/global-loader.js'), included: true }, + { pattern: path.join(uiToolkitRoot, 'src/js/utils/string-utils.js'), included: true }, + { pattern: path.join(uiToolkitRoot, 'src/js/utils/html-utils.js'), included: true }, + { pattern: 'static/spec/spec_helpers/i18n.js', included: true }, + { pattern: 'jasmine.common.conf.js', included: true }, + { pattern: require.resolve('draggabilly/dist/draggabilly.pkgd.js'), included: true }, + { pattern: 'static/js/vendor/URI.min.js', included: true }, + { pattern: 'static/js/vendor/jquery.leanModal.js', included: true }, + { pattern: 'static/js/vendor/Markdown.Converter.js', included: true }, + { pattern: 'static/js/vendor/Markdown.Sanitizer.js', included: true }, + { pattern: 'static/js/vendor/Markdown.Editor.js', included: true }, + { pattern: 'static/js/vendor/jquery.ajaxfileupload.js', included: true }, + { pattern: 'static/js/vendor/jquery.timeago.js', included: true }, + { pattern: 'static/js/vendor/jquery.truncate.js', included: true }, + { pattern: 'static/js/vendor/split.js', included: true }, + { pattern: 'static/js/mathjax_accessible.js', included: true }, + { pattern: 'static/js/mathjax_delay_renderer.js', included: true }, + { pattern: 'static/js/common/utils.js', included: true }, + { pattern: 'static/js/common/models/*.js', included: true }, + { pattern: 'static/js/common/content.js', included: true }, + { pattern: 'static/js/common/discussion.js', included: true }, + { pattern: 'static/js/common/mathjax_include.js', included: true }, + { pattern: 'static/js/customwmd.js', included: true }, + { pattern: 'static/js/common/views/*.js', included: true }, + { pattern: 'static/spec/spec_helpers/discussion_spec_helper.js', included: true }, + { pattern: 'static/spec/view/discussion_view_spec_helper.js', included: true }, + { pattern: 'static/spec/fixtures/**/*', included: false, served: true }, + { pattern: 'static/spec/**/*_spec.js', included: true } + ], + + exclude: [ + '**/public/**' + ], + + preprocessors: { + 'static/js/**/*.js': ['sourcemap'], + 'static/spec/view/discussion_thread_view_spec.js': ['regex', 'sourcemap'], + 'static/spec/**/*.js': ['sourcemap'] + }, + + regexPreprocessor: { + rules: [ + { + fileName: 'discussion_thread_view_spec.js', + replacement: [ + { replace: /return function\(\) \{\s*/g, with: '' }, + { replace: / \};\s*\n \}\);\s*\n describe\('thread responses'/g, with: ' });\n describe(\'thread responses\'' } + ] + } + ] + }, + + plugins: [ + 'karma-regex-preprocessor', + 'karma-jasmine', + 'karma-chrome-launcher', + 'karma-firefox-launcher', + 'karma-sourcemap-loader', + 'karma-coverage', + require('karma-spec-reporter') + ], + + reporters: ['spec', 'coverage'], + + coverageReporter: { + dir: 'coverage/', + reporters: [ + { type: 'html', subdir: 'report-html' }, + { type: 'lcov', subdir: 'report-lcov' } + ] + }, + + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: false, + browsers: ['FirefoxNoUpdates'], + + customLaunchers: { + FirefoxNoUpdates: { + base: 'Firefox', + prefs: { + 'app.update.auto': false, + 'app.update.enabled': false + } + } + }, + + singleRun: true, + concurrency: Infinity, + client: { captureConsole: true } + }); +}; diff --git a/xblocks_contrib/discussion/assets/package.json b/xblocks_contrib/discussion/assets/package.json index 88800f1c..4a9a8d80 100644 --- a/xblocks_contrib/discussion/assets/package.json +++ b/xblocks_contrib/discussion/assets/package.json @@ -2,7 +2,9 @@ "private": true, "scripts": { "build": "webpack --config webpack.prod.config.js", - "build-dev": "webpack --config webpack.dev.config.js" + "build-dev": "webpack --config webpack.dev.config.js", + "test": "karma start karma.conf.js", + "test-ci": "xvfb-run --auto-servernum karma start karma.conf.js" }, "devDependencies": { "backbone": "^1", @@ -12,6 +14,20 @@ "copy-webpack-plugin": "13.0.1", "imports-loader": "^0.8", "webpack": "^5", - "webpack-cli": "^5" + "webpack-cli": "^5", + "draggabilly": "^3.0.0", + "edx-ui-toolkit": "^1", + "jasmine-core": "2.6.4", + "jasmine-jquery": "git+https://git@github.com/velesin/jasmine-jquery.git#ebad463d592d3fea00c69f26ea18a930e09c7b58", + "jquery": "^2", + "karma": "^0.13", + "karma-chrome-launcher": "^3", + "karma-coverage": "^2", + "karma-firefox-launcher": "^2", + "karma-jasmine": "^0.3", + "karma-regex-preprocessor": "^1.0.1", + "karma-sourcemap-loader": "^0.4.0", + "karma-spec-reporter": "0.0.20", + "underscore": "^1" } } diff --git a/xblocks_contrib/discussion/assets/static/js/vendor/URI.min.js b/xblocks_contrib/discussion/assets/static/js/vendor/URI.min.js new file mode 100644 index 00000000..1def2f91 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/js/vendor/URI.min.js @@ -0,0 +1,47 @@ +/*! http://mths.be/punycode v1.2.3 by @mathias */ + +/*! + * URI.js - Mutating URLs + * IPv6 Support + * + * Version: 1.11.2 + * + * Author: Rodney Rehm + * Web: http://medialize.github.com/URI.js/ + * + * Licensed under + * MIT License http://www.opensource.org/licenses/mit-license + * GPL v3 http://opensource.org/licenses/GPL-3.0 + * + */ + +/*! + * URI.js - Mutating URLs + * Second Level Domain (SLD) Support + * + * Version: 1.11.2 + * + * Author: Rodney Rehm + * Web: http://medialize.github.com/URI.js/ + * + * Licensed under + * MIT License http://www.opensource.org/licenses/mit-license + * GPL v3 http://opensource.org/licenses/GPL-3.0 + * + */ + +/*! + * URI.js - Mutating URLs + * + * Version: 1.11.2 + * + * Author: Rodney Rehm + * Web: http://medialize.github.com/URI.js/ + * + * Licensed under + * MIT License http://www.opensource.org/licenses/mit-license + * GPL v3 http://opensource.org/licenses/GPL-3.0 + * + */ + +(function(e){function S(e){throw RangeError(g[e])}function x(e,t){var n=e.length;while(n--)e[n]=t(e[n]);return e}function T(e,t){return x(e.split(m),t).join(".")}function N(e){var t=[],n=0,r=e.length,i,s;while(n=55296&&i<=56319&&n65535&&(e-=65536,t+=w(e>>>10&1023|55296),e=56320|e&1023),t+=w(e),t}).join("")}function k(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:o}function L(e,t){return e+22+75*(e<26)-((t!=0)<<5)}function A(e,t,n){var r=0;e=n?b(e/l):e>>1,e+=b(e/t);for(;e>y*a>>1;r+=o)e=b(e/y);return b(r+(y+1)*e/(e+f))}function O(e){var t=[],n=e.length,r,i=0,f=h,l=c,d,v,m,g,y,w,E,x,T,N;d=e.lastIndexOf(p),d<0&&(d=0);for(v=0;v=128&&S("not-basic"),t.push(e.charCodeAt(v));for(m=d>0?d+1:0;m=n&&S("invalid-input"),E=k(e.charCodeAt(m++)),(E>=o||E>b((s-i)/y))&&S("overflow"),i+=E*y,x=w<=l?u:w>=l+a?a:w-l;if(Eb(s/N)&&S("overflow"),y*=N}r=t.length+1,l=A(i-g,r,g==0),b(i/r)>s-f&&S("overflow"),f+=b(i/r),i%=r,t.splice(i++,0,f)}return C(t)}function M(e){var t,n,r,i,f,l,d,v,m,g,y,E=[],x,T,C,k;e=N(e),x=e.length,t=h,n=0,f=c;for(l=0;l=t&&yb((s-n)/T)&&S("overflow"),n+=(d-t)*T,t=d;for(l=0;ls&&S("overflow");if(y==t){for(v=n,m=o;;m+=o){g=m<=f?u:m>=f+a?a:m-f;if(v= 0x80 (not a basic code point)","invalid-input":"Invalid input"},y=o-u,b=Math.floor,w=String.fromCharCode,E;i={version:"1.2.3",ucs2:{decode:N,encode:C},decode:O,encode:M,toASCII:D,toUnicode:_};if(typeof define=="function"&&typeof define.amd=="object"&&define.amd)define("punycode",[],function(){return i});else if(t&&!t.nodeType)if(n)n.exports=i;else for(E in i)i.hasOwnProperty(E)&&(t[E]=i[E]);else e.punycode=i})(this),function(e,t){typeof exports=="object"?module.exports=t():typeof define=="function"&&define.amd?define("IPv6",t):e.IPv6=t(e)}(this,function(e){function n(e){var t=e.toLowerCase(),n=t.split(":"),r=n.length,i=8;n[0]===""&&n[1]===""&&n[2]===""?(n.shift(),n.shift()):n[0]===""&&n[1]===""?n.shift():n[r-1]===""&&n[r-2]===""&&n.pop(),r=n.length,n[r-1].indexOf(".")!==-1&&(i=7);var s;for(s=0;s1))break;o.splice(0,1)}n[u]=o.join("")}var f=-1,l=0,c=0,h=-1,p=!1;for(u=0;ul&&(f=h,l=c)):n[u]=="0"&&(p=!0,h=u,c=1);c>l&&(f=h,l=c),l>1&&n.splice(f,l,""),r=n.length;var d="";n[0]===""&&(beststr=":");for(u=0;u]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/ig,s.defaultPorts={http:"80",https:"443",ftp:"21",gopher:"70",ws:"80",wss:"443"},s.invalid_hostname_characters=/[^a-zA-Z0-9\.-]/,s.domAttributes={a:"href",blockquote:"cite",link:"href",base:"href",script:"src",form:"action",img:"src",area:"href",iframe:"src",embed:"src",source:"src",track:"src",input:"src"},s.getDomAttribute=function(e){if(!e||!e.nodeName)return undefined;var t=e.nodeName.toLowerCase();return t==="input"&&e.type!=="image"?undefined:s.domAttributes[t]},s.encode=v,s.decode=decodeURIComponent,s.iso8859=function(){s.encode=escape,s.decode=unescape},s.unicode=function(){s.encode=v,s.decode=decodeURIComponent},s.characters={pathname:{encode:{expression:/%(24|26|2B|2C|3B|3D|3A|40)/ig,map:{"%24":"$","%26":"&","%2B":"+","%2C":",","%3B":";","%3D":"=","%3A":":","%40":"@"}},decode:{expression:/[\/\?#]/g,map:{"/":"%2F","?":"%3F","#":"%23"}}},reserved:{encode:{expression:/%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/ig,map:{"%3A":":","%2F":"/","%3F":"?","%23":"#","%5B":"[","%5D":"]","%40":"@","%21":"!","%24":"$","%26":"&","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"="}}}},s.encodeQuery=function(e,t){var n=s.encode(e+"");return t?n.replace(/%20/g,"+"):n},s.decodeQuery=function(e,t){e+="";try{return s.decode(t?e.replace(/\+/g,"%20"):e)}catch(n){return e}},s.recodePath=function(e){var t=(e+"").split("/");for(var n=0,r=t.length;n-1&&(t.fragment=e.substring(n+1)||null,e=e.substring(0,n)),n=e.indexOf("?"),n>-1&&(t.query=e.substring(n+1)||null,e=e.substring(0,n)),e.substring(0,2)==="//"?(t.protocol=null,e=e.substring(2),e=s.parseAuthority(e,t)):(n=e.indexOf(":"),n>-1&&(t.protocol=e.substring(0,n)||null,t.protocol&&!t.protocol.match(s.protocol_expression)?t.protocol=undefined:t.protocol==="file"?e=e.substring(n+3):e.substring(n+1,n+3)==="//"?(e=e.substring(n+3),e=s.parseAuthority(e,t)):(e=e.substring(n+1),t.urn=!0))),t.path=e,t},s.parseHost=function(e,t){var n=e.indexOf("/"),r,i;return n===-1&&(n=e.length),e.charAt(0)==="["?(r=e.indexOf("]"),t.hostname=e.substring(1,r)||null,t.port=e.substring(r+2,n)||null):e.indexOf(":")!==e.lastIndexOf(":")?(t.hostname=e.substring(0,n)||null,t.port=null):(i=e.substring(0,n).split(":"),t.hostname=i[0]||null,t.port=i[1]||null),t.hostname&&e.substring(n).charAt(0)!=="/"&&(n++,e="/"+e),e.substring(n)||"/"},s.parseAuthority=function(e,t){return e=s.parseUserinfo(e,t),s.parseHost(e,t)},s.parseUserinfo=function(e,t){var n=e.indexOf("/"),r=n>-1?e.lastIndexOf("@",n):e.indexOf("@"),i;return r>-1&&(n===-1||r"); + $("body").append(overlay); + } + + options = $.extend(defaults, options); + return this.each(function() { + var o = options; + $(this).click(function(e) { + var modal_id = $(this).attr("href"); + $("#lean_overlay").click(function() { + close_modal(modal_id) + }); + $(o.closeButton).click(function() { + close_modal(modal_id) + }); + var modal_height = $(modal_id).outerHeight(); + var modal_width = $(modal_id).outerWidth(); + $("#lean_overlay").css({ + "display": "block", + opacity: 0 + }); + $("#lean_overlay").fadeTo(200, o.overlay); + $(modal_id).css({ + "display": "block", + "position": "fixed", + "opacity": 0, + "z-index": 11000, + "left": 50 + "%", + "margin-left": -(modal_width / 2) + "px", + "top": o.top + "px" + }); + $(modal_id).fadeTo(200, 1); + e.preventDefault() + }) + }); + + function close_modal(modal_id) { + $("#lean_overlay").fadeOut(200); + $(modal_id).css({ + "display": "none" + }) + } + } + }) +})(jQuery); diff --git a/xblocks_contrib/discussion/assets/static/spec/content_spec.js b/xblocks_contrib/discussion/assets/static/spec/content_spec.js new file mode 100644 index 00000000..fe1109d0 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/content_spec.js @@ -0,0 +1,158 @@ +/* globals Comments, Content, DiscussionSpecHelper, DiscussionUser, DiscussionUtil, Thread */ +(function() { + 'use strict'; + + describe('All Content', function() { + beforeEach(function() { + return DiscussionSpecHelper.setUpGlobals(); + }); + describe('Staff and TA Content', function() { + beforeEach(function() { + return DiscussionUtil.loadRoles({ + Moderator: [567], + Administrator: [567], + 'Community TA': [567] + }); + }); + it('anonymous thread should not include login role label', function() { + var anon_content; + anon_content = new Content(); + anon_content.initialize(); + expect(anon_content.get('staff_authored')).toBe(false); + return expect(anon_content.get('community_ta_authored')).toBe(false); + }); + return it('general thread should include login role label', function() { + var anon_content; + anon_content = new Content({ + user_id: '567' + }); + anon_content.initialize(); + expect(anon_content.get('staff_authored')).toBe(true); + return expect(anon_content.get('community_ta_authored')).toBe(true); + }); + }); + describe('Content', function() { + beforeEach(function() { + this.content = new Content({ + id: '01234567', + user_id: '567', + course_id: 'edX/999/test', + body: 'this is some content', + abuse_flaggers: ['123'] + }); + }); + it('should exist', function() { + return expect(Content).toBeDefined(); + }); + it('is initialized correctly', function() { + this.content.initialize(); + expect(Content.contents['01234567']).toEqual(this.content); + expect(this.content.get('id')).toEqual('01234567'); + expect(this.content.get('user_url')).toEqual('/courses/edX/999/test/discussion/forum/users/567'); + expect(this.content.get('children')).toEqual([]); + return expect(this.content.get('comments')).toEqual(jasmine.any(Comments)); + }); + it('can update info', function() { + this.content.updateInfo({ + ability: { + can_edit: true + }, + voted: true, + subscribed: true + }); + expect(this.content.get('ability')).toEqual({ + can_edit: true + }); + expect(this.content.get('voted')).toEqual(true); + return expect(this.content.get('subscribed')).toEqual(true); + }); + it('can be flagged for abuse', function() { + this.content.flagAbuse(); + return expect(this.content.get('abuse_flaggers')).toEqual(['123', '567']); + }); + return it('can be unflagged for abuse', function() { + var temp_array; + temp_array = []; + temp_array.push(window.user.get('id')); + this.content.set('abuse_flaggers', temp_array); + this.content.unflagAbuse(); + return expect(this.content.get('abuse_flaggers')).toEqual([]); + }); + }); + return describe('Comments', function() { + beforeEach(function() { + this.comment1 = new Comment({ + id: '123' + }); + this.comment2 = new Comment({ + id: '345' + }); + }); + it('can contain multiple comments', function() { + var myComments; + myComments = new Comments(); + expect(myComments.length).toEqual(0); + myComments.add(this.comment1); + expect(myComments.length).toEqual(1); + myComments.add(this.comment2); + return expect(myComments.length).toEqual(2); + }); + it('returns results to the find method', function() { + var myComments; + myComments = new Comments(); + myComments.add(this.comment1); + return expect(myComments.find('123')).toBe(this.comment1); + }); + return it('can be endorsed', function() { + DiscussionUtil.loadRoles({ + Moderator: [111], + Administrator: [222], + 'Community TA': [333] + }); + this.discussionThread = new Thread({ + id: 1, + thread_type: 'discussion', + user_id: 99 + }); + this.discussionResponse = new Comment({ + id: 1, + thread: this.discussionThread + }); + this.questionThread = new Thread({ + id: 1, + thread_type: 'question', + user_id: 99 + }); + this.questionResponse = new Comment({ + id: 1, + thread: this.questionThread + }); + window.user = new DiscussionUser({ + id: 111 + }); + expect(this.discussionResponse.canBeEndorsed()).toBe(true); + expect(this.questionResponse.canBeEndorsed()).toBe(true); + window.user = new DiscussionUser({ + id: 222 + }); + expect(this.discussionResponse.canBeEndorsed()).toBe(true); + expect(this.questionResponse.canBeEndorsed()).toBe(true); + window.user = new DiscussionUser({ + id: 333 + }); + expect(this.discussionResponse.canBeEndorsed()).toBe(true); + expect(this.questionResponse.canBeEndorsed()).toBe(true); + window.user = new DiscussionUser({ + id: 99 + }); + expect(this.discussionResponse.canBeEndorsed()).toBe(false); + expect(this.questionResponse.canBeEndorsed()).toBe(true); + window.user = new DiscussionUser({ + id: 999 + }); + expect(this.discussionResponse.canBeEndorsed()).toBe(false); + return expect(this.questionResponse.canBeEndorsed()).toBe(false); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/fixtures/templates.underscore b/xblocks_contrib/discussion/assets/static/spec/fixtures/templates.underscore new file mode 100644 index 00000000..22204f4b --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/fixtures/templates.underscore @@ -0,0 +1,889 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xblocks_contrib/discussion/assets/static/spec/spec_helpers/discussion_spec_helper.js b/xblocks_contrib/discussion/assets/static/spec/spec_helpers/discussion_spec_helper.js new file mode 100644 index 00000000..b90c4cdc --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/spec_helpers/discussion_spec_helper.js @@ -0,0 +1,216 @@ +/* global _, Content, Discussion, DiscussionCourseSettings, DiscussionUtil, DiscussionUser */ +(function() { + 'use strict'; + + this.DiscussionSpecHelper = (function() { + function DiscussionSpecHelper() { + } + + DiscussionSpecHelper.setUpGlobals = function(opts) { + var options = opts || {}; + DiscussionUtil.loadRoles(options.roles || DiscussionSpecHelper.getTestRoleInfo()); + window.$$course_id = options.courseName || 'edX/999/test'; + window.user = new DiscussionUser(options.userInfo || DiscussionSpecHelper.getTestUserInfo()); + DiscussionUtil.setUser(window.user); + }; + + DiscussionSpecHelper.getTestUserInfo = function() { + return { + username: 'test_user', + id: '567', + upvoted_ids: [] + }; + }; + + DiscussionSpecHelper.getTestRoleInfo = function() { + return { + Moderator: [], + Administrator: [], + 'Community TA': [] + }; + }; + + DiscussionSpecHelper.makeTA = function() { + return DiscussionUtil.roleIds['Community TA'].push(parseInt(DiscussionUtil.getUser().id, 10)); + }; + + DiscussionSpecHelper.makeModerator = function() { + return DiscussionUtil.roleIds.Moderator.push(parseInt(DiscussionUtil.getUser().id, 10)); + }; + + DiscussionSpecHelper.makeAjaxSpy = function(fakeAjax) { + return spyOn($, 'ajax').and.callFake(function(params) { + fakeAjax(params); + return { + always: function() { + } + }; + }); + }; + + DiscussionSpecHelper.makeEventSpy = function() { + return jasmine.createSpyObj('event', ['preventDefault', 'target']); + }; + + DiscussionSpecHelper.createTestCourseSettings = function(options) { + var context = _.extend( + { + category_map: { + children: [['Test Topic', 'entry'], ['Other Topic', 'entry']], + entries: { + 'Test Topic': { + is_divided: true, + id: 'test_topic' + }, + 'Other Topic': { + is_divided: true, + id: 'other_topic' + } + } + }, + is_discussion_division_enabled: true, + allow_anonymous: false, + allow_anonymous_to_peers: false + }, + options || {} + ); + return new DiscussionCourseSettings(context); + }; + + DiscussionSpecHelper.createTestDiscussion = function(options) { + var sortPreference = options.sort_preference, + threads = options.threads || [], + threadPages = options.thread_pages || 1, + contentInfo = options.content_info; + DiscussionSpecHelper.setUpGlobals(options); + if (contentInfo) { + Content.loadContentInfos(contentInfo); + } + return new Discussion(threads, {pages: threadPages, sort: sortPreference}); + }; + + DiscussionSpecHelper.setUnderscoreFixtures = function() { + var templateFixtures = readFixtures('templates.underscore'); + appendSetFixtures(templateFixtures); + appendSetFixtures( + '' + ); + + appendSetFixtures( + '
\n' + + '
' + ); + }; + + return DiscussionSpecHelper; + }()); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/spec_helpers/i18n.js b/xblocks_contrib/discussion/assets/static/spec/spec_helpers/i18n.js new file mode 100644 index 00000000..267fd6d3 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/spec_helpers/i18n.js @@ -0,0 +1,10 @@ +window.gettext = function(s) { return s; }; +window.ngettext = function(singular, plural, num) { return num == 1 ? singular : plural; }; + +function interpolate(fmt, obj, named) { + if (named) { + return fmt.replace(/%\(\w+\)s/g, function(match) { return String(obj[match.slice(2, -2)]); }); + } else { + return fmt.replace(/%s/g, function(match) { return String(obj.shift()); }); + } +} diff --git a/xblocks_contrib/discussion/assets/static/spec/utils_spec.js b/xblocks_contrib/discussion/assets/static/spec/utils_spec.js new file mode 100644 index 00000000..d071ad53 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/utils_spec.js @@ -0,0 +1,94 @@ +/* globals DiscussionSpecHelper, DiscussionUtil */ +(function() { + 'use strict'; + + describe('DiscussionUtil', function() { + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals(); + }); + + describe('updateWithUndo', function() { + it('calls through to safeAjax with correct params, and reverts the model in case of failure', function() { + var deferred, model, res, updates; + deferred = $.Deferred(); + spyOn($, 'ajax').and.returnValue(deferred); + spyOn(DiscussionUtil, 'safeAjax').and.callThrough(); + model = new Backbone.Model({ + hello: false, + number: 42 + }); + updates = { + hello: 'world' + }; + res = DiscussionUtil.updateWithUndo(model, updates, { + foo: 'bar' + }, 'error message'); + expect(DiscussionUtil.safeAjax).toHaveBeenCalled(); + expect(model.attributes).toEqual({ + hello: 'world', + number: 42 + }); + spyOn(DiscussionUtil, 'discussionAlert'); + DiscussionUtil.safeAjax.calls.mostRecent().args[0].error(); + expect(DiscussionUtil.discussionAlert).toHaveBeenCalledWith('Error', 'error message'); + deferred.reject(); + return expect(model.attributes).toEqual({ + hello: false, + number: 42 + }); + }); + return it('rolls back the changes if the associated element is disabled', function() { + var $elem, failed, model, res, updates; + spyOn(DiscussionUtil, 'safeAjax').and.callThrough(); + model = new Backbone.Model({ + hello: false, + number: 42 + }); + updates = { + hello: 'world' + }; + $elem = jasmine.createSpyObj('$elem', ['prop']); + $elem.prop.and.returnValue(true); + res = DiscussionUtil.updateWithUndo(model, updates, { + foo: 'bar', + $elem: $elem + }, 'error message'); + expect($elem.prop).toHaveBeenCalledWith('disabled'); + expect(DiscussionUtil.safeAjax).toHaveBeenCalled(); + expect(model.attributes).toEqual({ + hello: false, + number: 42 + }); + failed = false; + res.fail(function() { + failed = true; + }); + return expect(failed).toBe(true); + }); + }); + + describe('safeAjax', function() { + function dismissAlert() { + $('.modal#discussion-alert').remove(); + } + + it('respects global beforeSend', function() { + var beforeSendSpy = jasmine.createSpy(); + $.ajaxSetup({beforeSend: beforeSendSpy}); + + var $elem = jasmine.createSpyObj('$elem', ['prop']); + + DiscussionUtil.safeAjax({ + $elem: $elem, + url: '/', + type: 'GET', + dataType: 'json' + }).always(function() { + dismissAlert(); + }); + expect($elem.prop).toHaveBeenCalledWith('disabled', true); + expect(beforeSendSpy).toHaveBeenCalled(); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/discussion_content_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/discussion_content_view_spec.js new file mode 100644 index 00000000..fadd47ea --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/discussion_content_view_spec.js @@ -0,0 +1,58 @@ +/* globals DiscussionSpecHelper, DiscussionContentView, Thread */ +(function() { + 'use strict'; + + describe('DiscussionContentView', function() { + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + this.threadData = { + id: '01234567', + user_id: '567', + course_id: 'edX/999/test', + body: 'this is a thread', + created_at: '2013-04-03T20:08:39Z', + abuse_flaggers: ['123'], + votes: { + up_count: '42' + }, + type: 'thread', + roles: [] + }; + this.thread = new Thread(this.threadData); + this.view = new DiscussionContentView({ + model: this.thread + }); + this.view.setElement($('#fixture-element')); + return this.view.render(); + }); + + it('defines the tag', function() { + expect($('#jasmine-fixtures')).toExist(); + expect(this.view.tagName).toBeDefined(); + return expect(this.view.el.tagName.toLowerCase()).toBe('div'); + }); + + it('defines the class', function() { + return expect(this.view.model).toBeDefined(); + }); + + it('is tied to the model', function() { + return expect(this.view.model).toBeDefined(); + }); + + it('can be flagged for abuse', function() { + this.thread.flagAbuse(); + return expect(this.thread.get('abuse_flaggers')).toEqual(['123', '567']); + }); + + it('can be unflagged for abuse', function() { + var temp_array; + temp_array = []; + temp_array.push(window.user.get('id')); + this.thread.set('abuse_flaggers', temp_array); + this.thread.unflagAbuse(); + return expect(this.thread.get('abuse_flaggers')).toEqual([]); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/discussion_inline_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/discussion_inline_view_spec.js new file mode 100644 index 00000000..ed3bb4c8 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/discussion_inline_view_spec.js @@ -0,0 +1,257 @@ +/* globals + _, Discussion, DiscussionCourseSettings, DiscussionViewSpecHelper, DiscussionSpecHelper, + DiscussionInlineView, DiscussionUtil, DiscussionThreadShowView, Thread + */ +(function() { + 'use strict'; + + describe('DiscussionInlineView', function() { + var createTestView, showDiscussion, setNextAjaxResult, + TEST_THREAD_TITLE = 'Test thread title'; + + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals(); + setFixtures( + '
' + + '
' + + '

Test Discussion

' + + '
' + + ' Topic: Category / Target ' + + '
' + + '
' + + ' ' + + '
' + ); + DiscussionSpecHelper.setUnderscoreFixtures(); + this.ajaxSpy = spyOn($, 'ajax'); + + // Don't attempt to render markdown + spyOn(DiscussionUtil, 'makeWmdEditor'); + spyOn(DiscussionThreadShowView.prototype, 'convertMath'); + }); + + createTestView = function(test) { + var testView; + var courseSettings = DiscussionSpecHelper.createTestCourseSettings({ + groups: [ + { + id: 1, + name: 'Cohort1' + }, { + id: 2, + name: 'Cohort2' + } + ] + }); + setNextAjaxResult(test, { + user_info: DiscussionSpecHelper.getTestUserInfo(), + roles: DiscussionSpecHelper.getTestRoleInfo(), + course_settings: courseSettings.attributes, + discussion_data: DiscussionViewSpecHelper.makeThreadWithProps({ + commentable_id: 'test-topic', + title: TEST_THREAD_TITLE + }), + page: 1, + num_pages: 1, + content: { + endorsed_responses: [], + non_endorsed_responses: [], + children: [] + } + }); + testView = new DiscussionInlineView({ + el: $('.discussion-module') + }); + testView.render(); + return testView; + }; + + showDiscussion = function(test, testView) { + var courseSettings = DiscussionSpecHelper.createTestCourseSettings({ + groups: [ + { + id: 1, + name: 'Cohort1' + }, { + id: 2, + name: 'Cohort2' + } + ] + }); + setNextAjaxResult(test, { + user_info: DiscussionSpecHelper.getTestUserInfo(), + roles: DiscussionSpecHelper.getTestRoleInfo(), + course_settings: courseSettings.attributes, + discussion_data: DiscussionViewSpecHelper.makeThreadWithProps({ + commentable_id: 'test-topic', + title: TEST_THREAD_TITLE + }), + page: 1, + num_pages: 1, + content: { + endorsed_responses: [], + non_endorsed_responses: [], + children: [] + } + }); + testView.$('.discussion-show').click(); + }; + + setNextAjaxResult = function(test, result) { + test.ajaxSpy.and.callFake(function(params) { + var deferred = $.Deferred(); + deferred.resolve(); + params.success(result); + return deferred; + }); + }; + + describe('inline discussion', function() { + it('is shown by default', function() { + var testView = createTestView(this), + showButton = testView.$('.discussion-show'); + + // Verify that the discussion is shown without clicking anything + expect(showButton).toHaveClass('shown'); + expect(showButton.text().trim()).toEqual('Hide Discussion'); + expect(testView.$('.inline-discussion:visible')).not.toHaveClass('is-hidden'); + }); + it('is shown after "Show Discussion" is clicked while discussions are hidden', function() { + var testView = createTestView(this), + showButton = testView.$('.discussion-show'); + + // hide the discussion; discussions are loaded by default + testView.$('.discussion-show').click(); + showDiscussion(this, testView); + + // Verify that the discussion is now shown again + expect(showButton).toHaveClass('shown'); + expect(showButton.text().trim()).toEqual('Hide Discussion'); + expect(testView.$('.inline-discussion:visible')).not.toHaveClass('is-hidden'); + }); + + it('is hidden after "Hide Discussion" is clicked', function() { + var testView = createTestView(this), + showButton = testView.$('.discussion-show'); + + // Hide the discussion by clicking the toggle button + testView.$('.discussion-show').click(); + + // Verify that the discussion is now hidden + expect(showButton).not.toHaveClass('shown'); + expect(showButton.text().trim()).toEqual('Show Discussion'); + expect(testView.$('.inline-discussion:visible')).toHaveClass('is-hidden'); + }); + }); + + describe('new post form', function() { + it('should not be visible when the discussion is first shown', function() { + var testView = createTestView(this); + showDiscussion(this, testView); + expect(testView.$('.new-post-article')).toHaveClass('is-hidden'); + }); + + it('should be shown when the "Add a Post" button is clicked', function() { + var testView = createTestView(this); + showDiscussion(this, testView); + testView.$('.new-post-btn').click(); + expect(testView.$('.new-post-article')).not.toHaveClass('is-hidden'); + }); + + it('should be hidden when the "Cancel" button is clicked', function() { + var testView = createTestView(this); + showDiscussion(this, testView); + testView.$('.new-post-btn').click(); + testView.$('.forum-new-post-form .cancel').click(); + expect(testView.$('.new-post-article')).toHaveClass('is-hidden'); + }); + + it('should be hidden when the "Close" button is clicked', function() { + var testView = createTestView(this); + showDiscussion(this, testView); + testView.$('.new-post-btn').click(); + testView.$('.forum-new-post-form .add-post-cancel').click(); + expect(testView.$('.new-post-article')).toHaveClass('is-hidden'); + }); + + it('should return to the thread listing after adding a post', function() { + var testView = createTestView(this); + showDiscussion(this, testView); + + // Navigate to an individual thread + testView.$('.forum-nav-thread-link').click(); + + // Click "Add a Post", fill in the form, and submit it + testView.$('.new-post-btn').click(); + testView.$('.js-post-title').text('Test title'); + testView.$('.wmd-input').text('Test body'); + setNextAjaxResult(this, { + hello: 'world' + }); + testView.$('.forum-new-post-form .submit').click(); + + // Verify that the list of threads is shown + expect(testView.$('.inline-threads')).not.toHaveClass('is-hidden'); + + // Verify that the individual thread is no longer shown + expect(testView.$('.group-visibility-label').length).toBe(0); + }); + }); + + describe('thread listing', function() { + it('builds a view that lists the threads', function() { + var testView = createTestView(this); + showDiscussion(this, testView); + expect(testView.$('.forum-nav-thread-title').text()).toBe(TEST_THREAD_TITLE); + }); + }); + + describe('thread post drill down', function() { + it('can drill down to a thread', function() { + var testView = createTestView(this); + showDiscussion(this, testView); + testView.$('.forum-nav-thread-link').click(); + + // Verify that the list of threads is hidden + expect(testView.$('.inline-threads')).toHaveClass('is-hidden'); + + // Verify that the individual thread is shown + expect(testView.$('.group-visibility-label').text().trim()).toBe('This post is visible to everyone.'); + }); + + it('can go back to the list of threads', function() { + var testView = createTestView(this); + showDiscussion(this, testView); + testView.$('.forum-nav-thread-link').click(); + testView.$('.all-posts-btn').click(); + + // Verify that the list of threads is shown + expect(testView.$('.inline-threads')).not.toHaveClass('is-hidden'); + + // Verify that the individual thread is no longer shown + expect(testView.$('.group-visibility-label').length).toBe(0); + }); + + it('marks a thread as read once it is opened', function() { + var testView = createTestView(this); + var thread; + showDiscussion(this, testView); + thread = testView.$('.forum-nav-thread'); + + // The thread is marked as unread. + expect(thread).toHaveClass('never-read'); + + // Navigate to the thread. + thread.find('.forum-nav-thread-link').click(); + + // The thread is no longer marked as unread. + expect(thread).not.toHaveClass('never-read'); + }); + }); + }); +}()); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_edit_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_edit_view_spec.js new file mode 100644 index 00000000..1aa7b1f4 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_edit_view_spec.js @@ -0,0 +1,184 @@ +/* globals + DiscussionCourseSettings, DiscussionSpecHelper, DiscussionThreadEditView, DiscussionUtil, + DiscussionViewSpecHelper, Thread +*/ +(function() { + 'use strict'; + + describe('DiscussionThreadEditView', function() { + var testUpdate, testCancel; + + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + spyOn(DiscussionUtil, 'makeWmdEditor'); + this.threadData = DiscussionViewSpecHelper.makeThreadWithProps({ + commentable_id: 'test_topic', + title: 'test thread title' + }); + this.thread = new Thread(this.threadData); + this.course_settings = DiscussionSpecHelper.createTestCourseSettings(); + + this.createEditView = function(options) { + options = _.extend({ + container: $('#fixture-element'), + model: this.thread, + mode: 'tab', + course_settings: this.course_settings + }, options); + this.view = new DiscussionThreadEditView(options); + this.view.render(); + }; + }); + + testUpdate = function(view, thread, newTopicId, newTopicName, mode) { + var discussionMode = mode || 'tab'; + + spyOn($, 'ajax').and.callFake(function(params) { + expect(params.url.path()).toEqual(DiscussionUtil.urlFor('update_thread', 'dummy_id')); + expect(params.data.thread_type).toBe('discussion'); + if (discussionMode !== 'inline') { + expect(params.data.commentable_id).toBe(newTopicId); + } + expect(params.data.title).toBe('changed thread title'); + params.success(); + return { + always: function() { + } + }; + }); + view.$el.find('.topic-title').filter(function(idx, el) { + return $(el).data('discussionId') === newTopicId; + }).prop('selected', true); // set new topic + view.$('.post-topic').trigger('change'); + view.$('.edit-post-title').val('changed thread title'); // set new title + if (discussionMode !== 'inline') { + view.$("label[for$='post-type-discussion']").click(); // set new thread type + } + view.$('.post-update').click(); + expect($.ajax).toHaveBeenCalled(); + + expect(thread.get('title')).toBe('changed thread title'); + expect(thread.get('thread_type')).toBe('discussion'); + if (discussionMode !== 'inline') { + expect(thread.get('commentable_id')).toBe(newTopicId); + expect(thread.get('courseware_title')).toBe(newTopicName); + } + expect(view.$('.edit-post-title')).toHaveValue(''); + expect(view.$('.wmd-preview p')).toHaveText(''); + }; + + it('can save new data correctly in tab mode', function() { + this.createEditView(); + testUpdate(this.view, this.thread, 'other_topic', 'Other Topic'); + }); + + it('can save new data correctly in inline mode', function() { + this.createEditView({mode: 'inline'}); + testUpdate(this.view, this.thread, 'other_topic', 'Other Topic', 'inline'); + }); + + testCancel = function(view) { + view.$('.post-cancel').click(); + expect($('.edit-post-form')).not.toExist(); + }; + + it('can close the view in tab mode', function() { + this.createEditView(); + testCancel(this.view); + }); + + it('can close the view in inline mode', function() { + this.createEditView({mode: 'inline'}); + testCancel(this.view); + }); + + describe('Enter key behavior in title input', function() { + beforeEach(function() { + this.createEditView(); + this.titleInput = this.view.$('.edit-post-title'); + }); + + it('prevents form submission when Enter is pressed in title input', function() { + var submitSpy = jasmine.createSpy('submitSpy'); + this.view.$el.on('submit', submitSpy); + + var enterKeyEvent = $.Event('keypress', {which: 13, keyCode: 13}); + this.titleInput.trigger(enterKeyEvent); + expect(submitSpy).not.toHaveBeenCalled(); + }); + + it('prevents default behavior when Enter is pressed in title input', function() { + var enterKeyEvent = $.Event('keypress', {which: 13, keyCode: 13}); + var preventDefaultSpy = spyOn(enterKeyEvent, 'preventDefault'); + + this.titleInput.trigger(enterKeyEvent); + expect(preventDefaultSpy).toHaveBeenCalled(); + }); + + it('does not prevent non-Enter key presses in title input', function() { + var submitSpy = jasmine.createSpy('submitSpy'); + this.view.$el.on('submit', submitSpy); + + var aKeyEvent = $.Event('keypress', {which: 65, keyCode: 65}); + var preventDefaultSpy = spyOn(aKeyEvent, 'preventDefault'); + this.titleInput.trigger(aKeyEvent); + expect(preventDefaultSpy).not.toHaveBeenCalled(); + }); + + it('does not interfere with body editor when Enter is pressed', function() { + var bodyEditor = this.view.$('.edit-post-body textarea'); + var enterKeyEvent = $.Event('keypress', {which: 13, keyCode: 13}); + var preventDefaultSpy = spyOn(enterKeyEvent, 'preventDefault'); + + bodyEditor.trigger(enterKeyEvent); + expect(preventDefaultSpy).not.toHaveBeenCalled(); + }); + }); + + describe('renderComments', function() { + beforeEach(function() { + this.course_settings = new DiscussionCourseSettings({ + category_map: { + children: [ + ['Topic', 'entry'], + ['General', 'entry'], + ['Basic Question', 'entry'] + ], + entries: { + Topic: { + is_divided: true, + id: 'topic' + }, + General: { + sort_key: 'General', + is_divided: false, + id: '6.00.1x_General' + }, + 'Basic Question': { + is_divided: false, + id: "6>00'1x\"Basic_Question" + } + } + }, + is_cohorted: true + }); + }); + + it('can save new data correctly for current discussion id without dots', function() { + this.createEditView({topicId: 'topic'}); + testUpdate(this.view, this.thread, '6.00.1x_General', 'General'); + }); + + it('can save new data correctly for current discussion id with dots', function() { + this.createEditView({topicId: '6.00.1x_General'}); + testUpdate(this.view, this.thread, "6>00\'1x\"Basic_Question", 'Basic Question'); + }); + + it('can save new data correctly for current discussion id with special characters', function() { + this.createEditView({topicId: "6>00\'1x\"Basic_Question"}); + testUpdate(this.view, this.thread, '6.00.1x_General', 'General'); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_list_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_list_view_spec.js new file mode 100644 index 00000000..c0b9c60b --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_list_view_spec.js @@ -0,0 +1,754 @@ +/* globals + _, Discussion, DiscussionCourseSettings, DiscussionViewSpecHelper, DiscussionSpecHelper, + DiscussionThreadListView, DiscussionUtil, Thread +*/ +(function() { + 'use strict'; + + describe('DiscussionThreadListView', function() { + var checkThreadsOrdering, expectFilter, makeView, renderSingleThreadWithProps, setupAjax; + + beforeEach(function() { + var deferred; + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + appendSetFixtures( + '' + ); + this.threads = [ + DiscussionViewSpecHelper.makeThreadWithProps({ + id: '1', + title: 'Thread1', + votes: { + up_count: '20' + }, + pinned: true, + comments_count: 1, + created_at: '2013-04-03T20:08:39Z' + }), DiscussionViewSpecHelper.makeThreadWithProps({ + id: '2', + title: 'Thread2', + votes: { + up_count: '42' + }, + comments_count: 2, + created_at: '2013-04-03T20:07:39Z' + }), DiscussionViewSpecHelper.makeThreadWithProps({ + id: '3', + title: 'Thread3', + votes: { + up_count: '12' + }, + read: true, + comments_count: 3, + unread_comments_count: 2, + created_at: '2013-04-03T20:06:39Z' + }), DiscussionViewSpecHelper.makeThreadWithProps({ + id: '4', + title: 'Thread4', + votes: { + up_count: '25' + }, + comments_count: 0, + pinned: true, + created_at: '2013-04-03T20:05:39Z' + }) + ]; + deferred = $.Deferred(); + spyOn($, 'ajax').and.returnValue(deferred); + this.discussion = new Discussion([]); + this.view = new DiscussionThreadListView({ + collection: this.discussion, + el: $('#fixture-element'), + courseSettings: new DiscussionCourseSettings({ + is_discussion_division_enabled: true + }) + }); + return this.view.render(); + }); + + setupAjax = function(callback) { + return $.ajax.and.callFake(function(params) { + if (callback) { + callback(params); + } + params.success({ + discussion_data: [], + page: 1, + num_pages: 1 + }); + return { + always: function() { + } + }; + }); + }; + + renderSingleThreadWithProps = function(props) { + return makeView(new Discussion([new Thread(DiscussionViewSpecHelper.makeThreadWithProps(props))])).render(); + }; + + makeView = function(discussion, props) { + return new DiscussionThreadListView( + _.extend( + { + el: $('#fixture-element'), + collection: discussion, + showThreadPreview: true, + courseSettings: new DiscussionCourseSettings({ + is_discussion_division_enabled: true + }) + }, + props + ) + ); + }; + + expectFilter = function(filterVal) { + return $.ajax.and.callFake(function(params) { + _.each(['unread', 'unanswered', 'flagged'], function(paramName) { + if (paramName === filterVal) { + return expect(params.data[paramName]).toEqual(true); + } else { + return expect(params.data[paramName]).toBeUndefined(); + } + }); + return { + always: function() { + } + }; + }); + }; + + describe('should filter correctly', function() { + return _.each(['all', 'unread', 'unanswered', 'flagged'], function(filterVal) { + it('for ' + filterVal, function() { + expectFilter(filterVal); + this.view.$('.forum-nav-filter-main-control').val(filterVal).change(); + return expect($.ajax).toHaveBeenCalled(); + }); + }); + }); + + it('filter should clear search alert when alternate term was searched', function() { + var filterval = 'unread'; + expectFilter(filterval); + this.view.$('.forum-nav-filter-main-control').val(filterval); + expect($('.search-alert .message').text()) + .toEqual('There are no posts in this topic yet.'); + + filterval = 'all'; + expectFilter(filterval); + this.view.$('.forum-nav-filter-main-control').val(filterval).change(); + expect($('.search-alert .message').text()).toEqual(''); + }); + + describe('group selector', function() { + it('should not be visible to students', function() { + return expect(this.view.$('.forum-nav-filter-cohort-control:visible')).not.toExist(); + }); + it('should allow moderators to select visibility', function() { + var expectedGroupId, + self = this; + DiscussionSpecHelper.makeModerator(); + this.view.render(); + expectedGroupId = null; + setupAjax(function(params) { + return expect(params.data.group_id).toEqual(expectedGroupId); + }); + return _.each([ + { + val: '', + // eslint-disable-next-line no-void + expectedGroupId: void 0 + }, { + val: '1', + expectedGroupId: '1' + }, { + val: '2', + expectedGroupId: '2' + } + ], function(optionInfo) { + expectedGroupId = optionInfo.expectedGroupId; + self.view.$('.forum-nav-filter-cohort-control').val(optionInfo.val).change(); + expect($.ajax).toHaveBeenCalled(); + return $.ajax.calls.reset(); + }); + }); + }); + + it('search should clear filter', function() { + expectFilter(null); + this.view.$('.forum-nav-filter-main-control').val('flagged'); + this.view.searchFor('foobar'); + return expect(this.view.$('.forum-nav-filter-main-control').val()).toEqual('all'); + }); + + checkThreadsOrdering = function(view, sortOrder, type) { + expect(view.$el.find('.forum-nav-thread').children().length).toEqual(4); + expect(view.$el.find('.forum-nav-thread:nth-child(1) .forum-nav-thread-title').text()) + .toEqual(sortOrder[0]); + expect(view.$el.find('.forum-nav-thread:nth-child(2) .forum-nav-thread-title').text()) + .toEqual(sortOrder[1]); + expect(view.$el.find('.forum-nav-thread:nth-child(3) .forum-nav-thread-title').text()) + .toEqual(sortOrder[2]); + expect(view.$el.find('.forum-nav-thread:nth-child(4) .forum-nav-thread-title').text()) + .toEqual(sortOrder[3]); + return expect(view.$el.find('.forum-nav-sort-control').val()).toEqual(type); + }; + + describe('thread rendering should be correct', function() { + var checkRender; + checkRender = function(threads, type, sortOrder) { + var discussion, view, + isOrderedByVotes = type === 'votes'; + discussion = new Discussion(_.map(threads, function(thread) { + return new Thread(thread); + }), { + pages: 1, + sort: type + }); + view = makeView(discussion); + view.render(); + checkThreadsOrdering(view, sortOrder, type); + expect(view.$el.find('.forum-nav-thread-comments-count:visible').length) + .toEqual(isOrderedByVotes ? 0 : 4); + expect(view.$el.find('.forum-nav-thread-unread-comments-count:visible').length) + .toEqual(isOrderedByVotes ? 0 : 1); + expect(view.$el.find('.forum-nav-thread-votes-count:visible').length) + .toEqual(isOrderedByVotes ? 4 : 0); + if (isOrderedByVotes) { + expect(_.map(view.$el.find('.forum-nav-thread-votes-count'), function(element) { + return $(element).text().trim(); + })).toEqual(['+25 votes', '+20 votes', '+42 votes', '+12 votes']); + } else { + expect(view.$el.find('.forum-nav-thread-votes-count:visible').length) + .toEqual(0); + } + }; + + it('with sort preference "activity"', function() { + checkRender(this.threads, 'activity', ['Thread1', 'Thread2', 'Thread3', 'Thread4']); + }); + + it('with sort preference "votes"', function() { + checkRender(this.threads, 'votes', ['Thread4', 'Thread1', 'Thread2', 'Thread3']); + }); + + it('with sort preference "comments"', function() { + checkRender(this.threads, 'comments', ['Thread1', 'Thread4', 'Thread3', 'Thread2']); + }); + }); + + describe('Sort change should be correct', function() { + var changeSorting; + changeSorting = function(threads, selectedType, newType, sortOrder) { + var discussion, sortControl, sortedThreads, view; + discussion = new Discussion(_.map(threads, function(thread) { + return new Thread(thread); + }), { + pages: 1, + sort: selectedType + }); + view = makeView(discussion); + view.render(); + sortControl = view.$el.find('.forum-nav-sort-control'); + expect(sortControl.val()).toEqual(selectedType); + sortedThreads = []; + if (newType === 'activity') { + sortedThreads = [threads[0], threads[3], threads[1], threads[2]]; + } else if (newType === 'comments') { + sortedThreads = [threads[0], threads[3], threads[2], threads[1]]; + } else if (newType === 'votes') { + sortedThreads = [threads[3], threads[0], threads[1], threads[2]]; + } + $.ajax.and.callFake(function(params) { + params.success({ + discussion_data: sortedThreads, + page: 1, + num_pages: 1 + }); + return { + always: function() { + } + }; + }); + sortControl.val(newType).change(); + expect($.ajax).toHaveBeenCalled(); + expect(view.mode).toBe('commentables'); + checkThreadsOrdering(view, sortOrder, newType); + }; + + it('with sort preference activity', function() { + changeSorting( + this.threads, 'comments', 'activity', ['Thread1', 'Thread4', 'Thread3', 'Thread2'] + ); + }); + + it('with sort preference votes', function() { + changeSorting(this.threads, 'activity', 'votes', ['Thread4', 'Thread1', 'Thread2', 'Thread3']); + }); + + it('with sort preference comments', function() { + changeSorting(this.threads, 'votes', 'comments', ['Thread1', 'Thread4', 'Thread3', 'Thread2']); + }); + }); + + describe('post type renders correctly', function() { + it('for discussion', function() { + renderSingleThreadWithProps({ + thread_type: 'discussion' + }); + expect($('.forum-nav-thread-wrapper-0 .icon')).toHaveClass('fa-comments'); + return expect($('.forum-nav-thread-wrapper-0 .sr')).toHaveText('discussion'); + }); + + it('for answered question', function() { + renderSingleThreadWithProps({ + thread_type: 'question', + endorsed: true + }); + expect($('.forum-nav-thread-wrapper-0 .icon')).toHaveClass('fa-check-square-o'); + return expect($('.forum-nav-thread-wrapper-0 .sr')).toHaveText('answered question'); + }); + + it('for unanswered question', function() { + renderSingleThreadWithProps({ + thread_type: 'question', + endorsed: false + }); + expect($('.forum-nav-thread-wrapper-0 .icon')).toHaveClass('fa-question'); + return expect($('.forum-nav-thread-wrapper-0 .sr')).toHaveText('unanswered question'); + }); + }); + + describe('post labels render correctly', function() { + beforeEach(function() { + this.moderatorId = '42'; + this.administratorId = '43'; + this.communityTaId = '44'; + return DiscussionUtil.loadRoles({ + Moderator: [parseInt(this.moderatorId, 10)], + Administrator: [parseInt(this.administratorId, 10)], + 'Community TA': [parseInt(this.communityTaId, 10)] + }); + }); + + it('for pinned', function() { + renderSingleThreadWithProps({ + pinned: true + }); + return expect($('.post-label-pinned').length).toEqual(1); + }); + + it('for following', function() { + renderSingleThreadWithProps({ + subscribed: true + }); + return expect($('.post-label-following').length).toEqual(1); + }); + + it('for moderator', function() { + renderSingleThreadWithProps({ + user_id: this.moderatorId + }); + return expect($('.post-label-by-staff').length).toEqual(1); + }); + + it('for administrator', function() { + renderSingleThreadWithProps({ + user_id: this.administratorId + }); + return expect($('.post-label-by-staff').length).toEqual(1); + }); + + it('for community TA', function() { + renderSingleThreadWithProps({ + user_id: this.communityTaId + }); + return expect($('.post-label-by-community-ta').length).toEqual(1); + }); + + it('when none should be present', function() { + renderSingleThreadWithProps({}); + return expect($('.forum-nav-thread-labels').length).toEqual(0); + }); + }); + + describe('search alerts', function() { + var testAlertMessages, getAlertMessagesAndClasses; + + testAlertMessages = function(expectedMessages) { + return expect($('.search-alert .message').map(function() { + return $(this).html(); + }).get()).toEqual(expectedMessages); + }; + + getAlertMessagesAndClasses = function() { + return $('.search-alert').map(function() { + return { + text: $('.message', this).html(), + css_class: $(this).attr('class') + }; + }).get(); + }; + + it('renders and removes search alerts', function() { + var bar, foo; + testAlertMessages(['There are no posts in this topic yet.']); + this.view.clearSearchAlerts(); + testAlertMessages([]); + foo = this.view.addSearchAlert('foo'); + testAlertMessages(['foo']); + bar = this.view.addSearchAlert('bar'); + testAlertMessages(['foo', 'bar']); + this.view.removeSearchAlert(foo.cid); + testAlertMessages(['bar']); + this.view.removeSearchAlert(bar.cid); + return testAlertMessages([]); + }); + + it('renders search alert with custom class', function() { + var messages; + testAlertMessages(['There are no posts in this topic yet.']); + this.view.clearSearchAlerts(); + testAlertMessages([]); + + this.view.addSearchAlert('foo', 'custom-class'); + messages = getAlertMessagesAndClasses(); + expect(messages.length).toEqual(1); + expect(messages[0].text).toEqual('foo'); + expect(messages[0].css_class).toEqual('search-alert custom-class'); + + this.view.addSearchAlert('bar', 'other-class'); + + messages = getAlertMessagesAndClasses(); + expect(messages.length).toEqual(2); + expect(messages[0].text).toEqual('foo'); + expect(messages[0].css_class).toEqual('search-alert custom-class'); + expect(messages[1].text).toEqual('bar'); + expect(messages[1].css_class).toEqual('search-alert other-class'); + }); + + it('clears all search alerts', function() { + this.view.clearSearchAlerts(); + this.view.addSearchAlert('foo'); + this.view.addSearchAlert('bar'); + this.view.addSearchAlert('baz'); + testAlertMessages(['foo', 'bar', 'baz']); + this.view.clearSearchAlerts(); + return testAlertMessages([]); + }); + }); + + describe('search spell correction', function() { + var testCorrection; + + beforeEach(function() { + return spyOn(this.view, 'searchForUser'); + }); + + testCorrection = function(view, correctedText) { + spyOn(view, 'addSearchAlert'); + $.ajax.and.callFake(function(params) { + params.success({ + discussion_data: [], + page: 42, + num_pages: 99, + corrected_text: correctedText + }, 'success'); + return { + always: function() { + } + }; + }); + view.searchFor('dummy'); + return expect($.ajax).toHaveBeenCalled(); + }; + + it('adds a search alert when an alternate term was searched', function() { + testCorrection(this.view, 'foo'); + expect(this.view.addSearchAlert.calls.count()).toEqual(2); + return expect(this.view.addSearchAlert.calls.mostRecent().args[0]).toMatch(/foo/); + }); + + it('does not add a search alert when no alternate term was searched', function() { + testCorrection(this.view, null); + expect(this.view.addSearchAlert.calls.count()).toEqual(2); + return expect(this.view.addSearchAlert.calls.mostRecent().args[0]).toMatch(/no posts matched/i); + }); + + it('clears search alerts when a new search is performed', function() { + spyOn(this.view, 'clearSearchAlerts'); + spyOn(DiscussionUtil, 'safeAjax'); + this.view.searchFor('dummy'); + return expect(this.view.clearSearchAlerts).toHaveBeenCalled(); + }); + + it('clears search alerts when the underlying collection changes', function() { + spyOn(this.view, 'clearSearchAlerts'); + spyOn(this.view, 'renderThread'); + this.view.collection.trigger('change', new Thread({ + id: 1 + })); + return expect(this.view.clearSearchAlerts).toHaveBeenCalled(); + }); + }); + + describe('username search', function() { + var setAjaxResults; + + it('makes correct ajax calls', function() { + $.ajax.and.callFake(function(params) { + expect(params.data.username).toEqual('testing-username'); + expect(params.url.path()).toEqual(DiscussionUtil.urlFor('users')); + params.success({ + users: [] + }, 'success'); + return { + always: function() { + } + }; + }); + this.view.searchForUser('testing-username'); + return expect($.ajax).toHaveBeenCalled(); + }); + + setAjaxResults = function(threadSuccess, userResult) { + return $.ajax.and.callFake(function(params) { + if (params.data.text && threadSuccess) { + params.success({ + discussion_data: [], + page: 42, + num_pages: 99, + corrected_text: 'dummy' + }, 'success'); + } else if (params.data.username) { + params.success({ + users: userResult + }, 'success'); + } + return { + always: function() { + } + }; + }); + }; + + it('gets called after a thread search succeeds', function() { + spyOn(this.view, 'searchForUser').and.callThrough(); + setAjaxResults(true, []); + this.view.searchFor('gizmo'); + expect(this.view.searchForUser).toHaveBeenCalled(); + return expect($.ajax.calls.mostRecent().args[0].data.username).toEqual('gizmo'); + }); + + it('does not get called after a thread search fails', function() { + spyOn(this.view, 'searchForUser').and.callThrough(); + setAjaxResults(false, []); + this.view.searchFor('gizmo'); + return expect(this.view.searchForUser).not.toHaveBeenCalled(); + }); + + it('adds a search alert when an username was matched', function() { + spyOn(this.view, 'addSearchAlert'); + setAjaxResults(true, [ + { + username: 'gizmo', + id: '1' + } + ]); + this.view.searchForUser('dummy'); + expect($.ajax).toHaveBeenCalled(); + expect(this.view.addSearchAlert).toHaveBeenCalled(); + return expect(this.view.addSearchAlert.calls.mostRecent().args[0]).toMatch(/gizmo/); + }); + + it('does not add a search alert when no username was matched', function() { + spyOn(this.view, 'addSearchAlert'); + setAjaxResults(true, []); + this.view.searchForUser('dummy'); + expect($.ajax).toHaveBeenCalled(); + return expect(this.view.addSearchAlert).not.toHaveBeenCalled(); + }); + }); + + describe('thread preview body', function() { + it('should be shown when showThreadPreview is true', function() { + renderSingleThreadWithProps({ + thread_type: 'discussion' + }); + expect($('.thread-preview-body').length).toEqual(1); + }); + + it('should not show image when showThreadPreview is true', function() { + renderSingleThreadWithProps({ + thread_type: 'discussion', + body: '![customizedImageAltTitle].png' + }); + expect($('.thread-preview-body').text()).toEqual(''); + }); + + it('should not show MathJax when showThreadPreview is true', function() { + renderSingleThreadWithProps({ + thread_type: 'discussion', + body: '$$x^2 + sqrt(y)$$' + }); + expect($('.thread-preview-body').text()).toEqual(''); + }); + + it('should not be shown when showThreadPreview is false', function() { + var view, + discussion = new Discussion([]), + showThreadPreview = false; + view = makeView(discussion, showThreadPreview); + view.render(); + expect(view.$el.find('.thread-preview-body').length).toEqual(0); + }); + }); + + describe('read/unread state', function() { + it('adds never-read class to unread threads', function() { + var unreads = this.threads.filter(function(thread) { + return !thread.read && thread.unread_comments_count === thread.comments_count; + }).length; + + this.view = makeView(new Discussion(this.threads)); + this.view.render(); + expect(this.view.$('.never-read').length).toEqual(unreads); + }); + + it('shows a "x new" message for threads that are read, but have unread comments', function() { + var unreadThread = this.threads.filter(function(thread) { + return thread.read && thread.unread_comments_count !== thread.comments_count; + })[0], + newCommentsOnUnreadThread = unreadThread.unread_comments_count; + + this.view = makeView(new Discussion(this.threads)); + this.view.render(); + expect( + this.view.$('.forum-nav-thread-unread-comments-count') + .first() + .text() + .trim() + ).toEqual(newCommentsOnUnreadThread + ' new'); + }); + + it('should display every thread as read if hideReadState: true is passed to the constructor', function() { + this.view = makeView(new Discussion(this.threads), {hideReadState: true}); + this.view.render(); + expect(this.view.$('.never-read').length).toEqual(0); + }); + + it('does not show the "x new" indicator for any thread if hideReadState: true is passed', function() { + this.view = makeView(new Discussion(this.threads), {hideReadState: true}); + this.view.render(); + expect(this.view.$('.forum-nav-thread-unread-comments-count').length).toEqual(0); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_profile_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_profile_view_spec.js new file mode 100644 index 00000000..30d9549b --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_profile_view_spec.js @@ -0,0 +1,151 @@ +/* globals Discussion, DiscussionSpecHelper, DiscussionThreadProfileView, Thread */ +(function() { + 'use strict'; + + describe('DiscussionThreadProfileView', function() { + var checkBody, checkPostWithImages, makeThread, makeView, spyConvertMath; + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + this.threadData = { + id: '1', + body: 'dummy body', + discussion: new Discussion(), + abuse_flaggers: [], + commentable_id: 'dummy_discussion', + votes: { + up_count: '42' + }, + created_at: '2014-09-09T20:11:08Z' + }; + this.imageTag = ''; + }); + makeView = function(thread) { + var view; + view = new DiscussionThreadProfileView({ + model: thread + }); + spyConvertMath(view); + return view; + }; + makeThread = function(threadData) { + var thread; + thread = new Thread(threadData); + thread.discussion = new Discussion(); + return thread; + }; + spyConvertMath = function(view) { + return spyOn(view, 'convertMath').and.callFake(function() { + return this.model.set('markdownBody', this.model.get('body')); + }); + }; + checkPostWithImages = function(numberOfImages, truncatedText, threadData, imageTag) { + var expectedHtml, expectedText, i, testText, view, _i, _ref; + expectedHtml = '

'; + threadData.body = '

'; + testText = ''; + expectedText = ''; + if (truncatedText) { + testText = new Array(100).join('test '); + expectedText = testText.substring(0, 139) + '…'; + } else { + testText = 'Test body'; + expectedText = 'Test body'; + // I really have no idea what it is supposed to mean - probably just iteration, but better be safe + for ( + // eslint-disable-next-line no-multi-assign + i = _i = 0, _ref = numberOfImages - 1; + _ref >= 0 ? _i <= _ref : _i >= _ref; + i = _ref >= 0 ? ++_i : --_i + ) { + threadData.body += imageTag; + if (i === 0) { + expectedHtml += imageTag; + } else { + expectedHtml += 'image omitted'; + } + } + } + threadData.body = threadData.body + '' + testText + '

'; + if (numberOfImages > 1) { + expectedHtml = expectedHtml + '' + expectedText + + '

Some images in this post have been omitted

'; + } else { + expectedHtml = expectedHtml + '' + expectedText + '

'; + } + view = makeView(makeThread(threadData)); + view.render(); + return expect(view.$el.find('.post-body').html()).toEqual(expectedHtml); + }; + checkBody = function(truncated, view, threadData) { + var expectedOutput, inputHtmlStripped, outputHtmlStripped; + view.render(); + if (!truncated) { + expect(view.model.get('body')).toEqual(view.model.get('abbreviatedBody')); + return expect(view.$el.find('.post-body').html()).toEqual(threadData.body); + } else { + expect(view.model.get('body')).not.toEqual(view.model.get('abbreviatedBody')); + expect(view.$el.find('.post-body').html()).not.toEqual(threadData.body); + outputHtmlStripped = view.$el.find('.post-body').html().replace(/(<([^>]+)>)/ig, ''); + outputHtmlStripped = outputHtmlStripped.replace('Some images in this post have been omitted', ''); + outputHtmlStripped = outputHtmlStripped.replace('image omitted', ''); + inputHtmlStripped = threadData.body.replace(/(<([^>]+)>)/ig, ''); + expectedOutput = inputHtmlStripped.substring(0, 139) + '…'; + expect(outputHtmlStripped).toEqual(expectedOutput); + return expect(view.$el.find('.post-body').html().indexOf('…')).toBeGreaterThan(0); + } + }; + describe('Body markdown should be correct', function() { + var numImages, truncatedText, _i, _j, _len, _len1, _ref, _ref1; + it('untruncated text without markdown body', function() { + var view; + this.threadData.body = 'Test body'; + view = makeView(makeThread(this.threadData)); + return checkBody(false, view, this.threadData); + }); + it('truncated text without markdown body', function() { + var view; + this.threadData.body = new Array(100).join('test '); + view = makeView(makeThread(this.threadData)); + return checkBody(true, view, this.threadData); + }); + it('untruncated text with markdown body', function() { + var view; + this.threadData.body = '

' + this.imageTag + 'Google top search engine

'; + view = makeView(makeThread(this.threadData)); + return checkBody(false, view, this.threadData); + }); + it('truncated text with markdown body', function() { + var testText, view; + testText = new Array(100).join('test '); + this.threadData.body = '

' + this.imageTag + this.imageTag + '' + testText + '

'; + view = makeView(makeThread(this.threadData)); + return checkBody(true, view, this.threadData); + }); + _ref = [1, 2, 10]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + numImages = _ref[_i]; + _ref1 = [true, false]; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + truncatedText = _ref1[_j]; + it( + 'body with ' + numImages + ' images and ' + (truncatedText ? 'truncated' : 'untruncated') + + ' text', + // eslint-disable no-loop-func + // eslint-disable-next-line no-loop-func + function() { + return checkPostWithImages(numImages, truncatedText, this.threadData, this.imageTag); + } + // eslint-enable no-loop-func + ); + } + } + it('check the thread retrieve url', function() { + var thread; + thread = makeThread(this.threadData); + return expect(thread.urlFor('retrieve')) + .toBe('/courses/edX/999/test/discussion/forum/dummy_discussion/threads/1'); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_show_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_show_view_spec.js new file mode 100644 index 00000000..ce603770 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_show_view_spec.js @@ -0,0 +1,199 @@ +/* globals DiscussionSpecHelper, DiscussionThreadShowView, DiscussionUtil, DiscussionViewSpecHelper, Thread */ +(function() { + 'use strict'; + + var $$course_id = '$$course_id'; + describe('DiscussionThreadShowView', function() { + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals({}); + DiscussionSpecHelper.setUnderscoreFixtures(); + this.user = DiscussionUtil.getUser(); + this.threadData = { + id: 'dummy', + user_id: this.user.id, + username: this.user.get('username'), + course_id: $$course_id, + title: 'dummy title', + body: 'this is a thread', + created_at: '2013-04-03T20:08:39Z', + abuse_flaggers: [], + votes: { + up_count: 42 + }, + thread_type: 'discussion', + closed: false, + pinned: false, + type: 'thread' + }; + this.thread = new Thread(this.threadData); + this.view = new DiscussionThreadShowView({ + model: this.thread + }); + this.view.setElement($('#fixture-element')); + return spyOn(this.view, 'convertMath'); + }); + describe('voting', function() { + it('renders the vote state correctly', function() { + return DiscussionViewSpecHelper.checkRenderVote(this.view, this.thread); + }); + it('votes correctly via click', function() { + return DiscussionViewSpecHelper.checkUpvote(this.view, this.thread, this.user, $.Event('click')); + }); + it('votes correctly via spacebar', function() { + return DiscussionViewSpecHelper.checkUpvote(this.view, this.thread, this.user, $.Event('keydown', { + which: 32 + })); + }); + it('unvotes correctly via click', function() { + return DiscussionViewSpecHelper.checkUnvote(this.view, this.thread, this.user, $.Event('click')); + }); + it('unvotes correctly via spacebar', function() { + return DiscussionViewSpecHelper.checkUnvote(this.view, this.thread, this.user, $.Event('keydown', { + which: 32 + })); + }); + }); + describe('pinning', function() { + var expectPinnedRendered; + expectPinnedRendered = function(view, model) { + var button, pinned; + pinned = model.get('pinned'); + button = view.$el.find('.action-pin'); + expect(button.hasClass('is-checked')).toBe(pinned); + return expect(button.attr('aria-checked')).toEqual(pinned.toString()); + }; + it('renders the pinned state correctly', function() { + this.view.render(); + expectPinnedRendered(this.view, this.thread); + this.thread.set('pinned', false); + this.view.render(); + expectPinnedRendered(this.view, this.thread); + this.thread.set('pinned', true); + this.view.render(); + return expectPinnedRendered(this.view, this.thread); + }); + it('exposes the pinning control only to authorized users', function() { + this.thread.updateInfo({ + ability: { + can_openclose: false + } + }); + this.view.render(); + expect(this.view.$el.find('.action-pin').closest('.is-hidden')).toExist(); + this.thread.updateInfo({ + ability: { + can_openclose: true + } + }); + this.view.render(); + return expect(this.view.$el.find('.action-pin').closest('.is-hidden')).not.toExist(); + }); + it('handles events correctly', function() { + this.view.render(); + return DiscussionViewSpecHelper.checkButtonEvents(this.view, 'togglePin', '.action-pin'); + }); + }); + describe('labels', function() { + var expectOneElement; + expectOneElement = function(view, selector, visible) { + var elements; + if (typeof visible === 'undefined' || visible === null) { + visible = true; + } + view.render(); + elements = view.$el.find(selector); + expect(elements.length).toEqual(1); + if (visible) { + return expect(elements).not.toHaveClass('is-hidden'); + } else { + return expect(elements).toHaveClass('is-hidden'); + } + }; + it('displays the closed label when appropriate', function() { + expectOneElement(this.view, '.post-label-closed', false); + this.thread.set('closed', true); + return expectOneElement(this.view, '.post-label-closed'); + }); + it('displays the pinned label when appropriate', function() { + expectOneElement(this.view, '.post-label-pinned', false); + this.thread.set('pinned', true); + return expectOneElement(this.view, '.post-label-pinned'); + }); + it('displays the reported label when appropriate for a non-staff user', function() { + expectOneElement(this.view, '.post-label-reported', false); + this.thread.set('abuse_flaggers', [DiscussionUtil.getUser().id]); + expectOneElement(this.view, '.post-label-reported'); + this.thread.set('abuse_flaggers', [DiscussionUtil.getUser().id + 1]); + return expectOneElement(this.view, '.post-label-reported', false); + }); + it('displays the reported label when appropriate for a flag moderator', function() { + DiscussionSpecHelper.makeModerator(); + expectOneElement(this.view, '.post-label-reported', false); + this.thread.set('abuse_flaggers', [DiscussionUtil.getUser().id]); + expectOneElement(this.view, '.post-label-reported'); + this.thread.set('abuse_flaggers', [DiscussionUtil.getUser().id + 1]); + return expectOneElement(this.view, '.post-label-reported'); + }); + }); + describe('author display', function() { + var checkUserLink; + beforeEach(function() { + return this.thread.set('user_url', 'test_user_url'); + }); + checkUserLink = function(element, is_ta, is_staff) { + expect(element.find('.username').length).toEqual(1); + expect(element.find('.username').text()).toEqual('test_user'); + expect(element.find('.username').attr('href')).toEqual('test_user_url'); + expect(element.find('.user-label-community-ta').length).toEqual(is_ta ? 1 : 0); + return expect(element.find('.user-label-staff').length).toEqual(is_staff ? 1 : 0); + }; + it('renders correctly for a student-authored thread', function() { + var $el; + $el = $('#fixture-element').html(this.view.getAuthorDisplay()); + return checkUserLink($el, false, false); + }); + it('renders correctly for a community TA-authored thread', function() { + var $el; + this.thread.set('community_ta_authored', true); + $el = $('#fixture-element').html(this.view.getAuthorDisplay()); + return checkUserLink($el, true, false); + }); + it('renders correctly for a staff-authored thread', function() { + var $el; + this.thread.set('staff_authored', true); + $el = $('#fixture-element').html(this.view.getAuthorDisplay()); + return checkUserLink($el, false, true); + }); + it('renders correctly for an anonymously-authored thread', function() { + var $el; + this.thread.set('username', null); + $el = $('#fixture-element').html(this.view.getAuthorDisplay()); + expect($el.find('.username').length).toEqual(0); + return expect($el.text()).toMatch(/^(\s*)anonymous(\s*)$/); + }); + }); + describe('cohorting', function() { + it('renders correctly for a unified thread', function() { + this.view.render(); + return expect(this.view.$('.group-visibility-label').text().trim()) + .toEqual('This post is visible to everyone.'); + }); + it('renders correctly for a divided thread', function() { + this.thread.set('group_id', '1'); + this.thread.set('group_name', 'Mock Cohort'); + this.view.is_commentable_divided = true; + this.view.render(); + return expect(this.view.$('.group-visibility-label').text().trim()) + .toEqual('This post is visible only to Mock Cohort.'); + }); + it('renders correctly for a grouped unified thread', function() { + this.thread.set('group_id', '1'); + this.thread.set('group_name', 'Mock Cohort'); + this.view.is_commentable_divided = false; + this.view.render(); + return expect(this.view.$('.group-visibility-label').text().trim()) + .toEqual('This post is visible to everyone.'); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_view_spec.js new file mode 100644 index 00000000..dfdf7008 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/discussion_thread_view_spec.js @@ -0,0 +1,367 @@ +/* global + _, Discussion, DiscussionThreadShowView, DiscussionViewSpecHelper, DiscussionSpecHelper, DiscussionThreadView, + DiscussionUtil, Thread, DiscussionContentView, ThreadResponseShowView +*/ +(function() { + 'use strict'; + + describe('DiscussionThreadView', function() { + var assertContentVisible, assertExpandedContentVisible, assertResponseCountAndPaginationCorrect, + createAjaxResponseJson, createTestResponseJson, postResponse, renderWithContent, renderWithTestResponses; + beforeEach(function() { + var deferred; + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + jasmine.clock().install(); + this.threadData = DiscussionViewSpecHelper.makeThreadWithProps({}); + this.thread = new Thread(this.threadData); + this.discussion = new Discussion(this.thread); + deferred = $.Deferred(); + spyOn($, 'ajax').and.returnValue(deferred); + spyOn(DiscussionThreadShowView.prototype, 'convertMath'); + spyOn(DiscussionContentView.prototype, 'makeWmdEditor'); + spyOn(DiscussionUtil, 'makeWmdEditor'); + spyOn(DiscussionUtil, 'setWmdContent'); + return spyOn(ThreadResponseShowView.prototype, 'convertMath'); + }); + afterEach(function() { + $.ajax.calls.reset(); + return jasmine.clock().uninstall(); + }); + + renderWithContent = function(view, content) { + $.ajax.and.callFake(function(params) { + params.success(createAjaxResponseJson(content, false), 'success'); + return { + always: function() { + } + }; + }); + view.render(); + return jasmine.clock().tick(100); + }; + renderWithTestResponses = function(view, count, options) { + var index; + return renderWithContent(view, _.extend({ + resp_total: count, + children: count > 0 ? (function() { + var _i, _results; + _results = []; + // eslint-disable-next-line no-multi-assign + for (index = _i = 1; count >= 1 ? _i <= count : _i >= count; index = count >= 1 ? ++_i : --_i) { + _results.push(createTestResponseJson(index)); + } + return _results; + }()) : [] + }, options)); + }; + createTestResponseJson = function(index) { + return { + user_id: window.user.id, + body: 'Response ' + index, + id: 'id_' + index, + created_at: '2015-01-01T22:20:28Z' + }; + }; + assertContentVisible = function(view, selector, visible) { + var content; + content = view.$el.find(selector); + expect(content.length).toBeGreaterThan(0); + return content.each(function(i, elem) { + return expect($(elem).is(':visible')).toEqual(visible); + }); + }; + assertExpandedContentVisible = function(view, expanded) { + expect(view.$el.hasClass('expanded')).toEqual(expanded); + assertContentVisible(view, '.post-extended-content', expanded); + assertContentVisible(view, '.forum-thread-expand', !expanded); + return assertContentVisible(view, '.forum-thread-collapse', expanded); + }; + assertResponseCountAndPaginationCorrect = function(view, countText, displayCountText, buttonText) { + expect(view.$el.find('.response-count').text()).toEqual(countText); + if (displayCountText) { + expect(view.$el.find('.response-display-count').text()).toEqual(displayCountText); + } else { + expect(view.$el.find('.response-display-count').length).toEqual(0); + } + if (buttonText) { + return expect(view.$el.find('.load-response-button').text()).toEqual(buttonText); + } else { + return expect(view.$el.find('.load-response-button').length).toEqual(0); + } + }; + createAjaxResponseJson = function(content, can_act) { + return { + content: content, + annotated_content_info: { + ability: { + editable: can_act, + can_delete: can_act, + can_reply: can_act, + can_vote: can_act + } + } + }; + }; + postResponse = function(view, index) { + var responseText, testResponseJson; + testResponseJson = createTestResponseJson(index); + responseText = testResponseJson.body; + spyOn(view, 'getWmdContent').and.returnValue(responseText); + $.ajax.and.callFake(function(params) { + expect(params.type).toEqual('POST'); + expect(params.data.body).toEqual(responseText); + params.success(createAjaxResponseJson(testResponseJson, true), 'success'); + return { + always: function() { + } + }; + }); + return view.$('.discussion-submit-post').click(); + }; + describe('closed and open Threads', function() { + var checkCommentForm, checkVoteDisplay, createDiscussionThreadView; + createDiscussionThreadView = function(originallyClosed) { + var discussion, thread, threadData, view; + threadData = DiscussionViewSpecHelper.makeThreadWithProps({ + closed: originallyClosed + }); + thread = new Thread(threadData); + discussion = new Discussion(thread); + view = new DiscussionThreadView({ + model: thread, + el: $('#fixture-element'), + course_settings: DiscussionSpecHelper.createTestCourseSettings() + }); + renderWithTestResponses(view, 1); + spyOn(DiscussionUtil, 'updateWithUndo').and.callFake(function(model, updates) { + return model.set(updates); + }); + return view; + }; + checkCommentForm = function(originallyClosed) { + var view; + view = createDiscussionThreadView(originallyClosed); + expect(view.$('.comment-form').closest('li').is(':visible')).toBe(!originallyClosed); + expect(view.$('.discussion-reply-new').is(':visible')).toBe(!originallyClosed); + view.$('.action-close').click(); + expect(view.$('.comment-form').closest('li').is(':visible')).toBe(originallyClosed); + return expect(view.$('.discussion-reply-new').is(':visible')).toBe(originallyClosed); + }; + checkVoteDisplay = function(originallyClosed) { + var view; + view = createDiscussionThreadView(originallyClosed); + expect(view.$('.thread-main-wrapper .action-vote').is(':visible')).toBe(!originallyClosed); + expect(view.$('.thread-main-wrapper .display-vote').is(':visible')).toBe(originallyClosed); + view.$('.action-close').click(); + expect(view.$('.action-vote').is(':visible')).toBe(originallyClosed); + return expect(view.$('.display-vote').is(':visible')).toBe(!originallyClosed); + }; + return function() { + it( + 'Test that when a closed thread is opened the comment form is displayed', + function() { return checkCommentForm(true); } + ); + it( + 'Test that when a open thread is closed the comment form is hidden', + function() { return checkCommentForm(false); } + ); + it( + 'Test that when a closed thread is opened the vote button is displayed and ' + + 'vote count is hidden', + function() { return checkVoteDisplay(true); } + ); + it( + 'Test that when a open thread is closed the vote button is hidden and ' + + 'vote count is displayed', + function() { return checkVoteDisplay(false); } + ); + }; + }); + describe('thread responses', function() { + beforeEach(function() { + this.view = new DiscussionThreadView({ + model: this.thread, + el: $('#fixture-element'), + course_settings: DiscussionSpecHelper.createTestCourseSettings() + }); + spyOn($.fn, 'focus'); + }); + describe('responses', function() { + it('can post a first response', function() { + renderWithTestResponses(this.view, 0); + postResponse(this.view, 1); + expect(this.view.$('.forum-response').length).toBe(1); + expect(this.view.$('.post-actions-list').find('.action-edit').parent('.is-hidden').length).toBe(1); + expect(this.view.$('.response-actions-list').find('.action-edit') + .parent().not('.is-hidden').length).toBe(1); + expect(document.activeElement === this.view.$('.forum-response')[0]); + }); + it('can post a second response', function() { + renderWithTestResponses(this.view, 1); + expect(this.view.$('.forum-response').length).toBe(1); + expect(this.view.$('.post-actions-list').find('.action-edit').parent('.is-hidden').length).toBe(1); + expect(this.view.$('.response-actions-list').find('.action-edit').parent() + .not('.is-hidden').length).toBe(1); + postResponse(this.view, 2); + expect(this.view.$('.forum-response').length).toBe(2); + expect(this.view.$('.post-actions-list').find('.action-edit').parent('.is-hidden').length).toBe(1); + expect(this.view.$('.response-actions-list').find('.action-edit').parent() + .not('.is-hidden').length).toBe(2); + expect(document.activeElement === this.view.$('.forum-response')[0]); + }); + }); + describe('response count and pagination', function() { + it('correctly render for a thread with no responses', function() { + renderWithTestResponses(this.view, 0); + return assertResponseCountAndPaginationCorrect(this.view, '0 responses', null, null); + }); + it('correctly render for a thread with one response', function() { + renderWithTestResponses(this.view, 1); + return assertResponseCountAndPaginationCorrect( + this.view, '1 response', 'Showing all responses', null + ); + }); + it('correctly render for a thread with one additional page', function() { + renderWithTestResponses(this.view, 1, { + resp_total: 2 + }); + return assertResponseCountAndPaginationCorrect( + this.view, '2 responses', 'Showing first response', 'Load all responses' + ); + }); + it('correctly render for a thread with multiple additional pages', function() { + renderWithTestResponses(this.view, 2, { + resp_total: 111 + }); + return assertResponseCountAndPaginationCorrect( + this.view, '111 responses', 'Showing first 2 responses', 'Load next 100 responses' + ); + }); + describe('on clicking the load more button', function() { + beforeEach(function() { + renderWithTestResponses(this.view, 1, { + resp_total: 5 + }); + return assertResponseCountAndPaginationCorrect( + this.view, '5 responses', 'Showing first response', 'Load all responses' + ); + }); + it('correctly re-render when all threads have loaded', function() { + renderWithTestResponses(this.view, 5, { + resp_total: 5 + }); + this.view.$el.find('.load-response-button').click(); + return assertResponseCountAndPaginationCorrect( + this.view, '5 responses', 'Showing all responses', null + ); + }); + it('correctly re-render when one page remains', function() { + renderWithTestResponses(this.view, 3, { + resp_total: 42 + }); + this.view.$el.find('.load-response-button').click(); + return assertResponseCountAndPaginationCorrect( + this.view, '42 responses', 'Showing first 3 responses', 'Load all responses' + ); + }); + it('correctly re-render when multiple pages remain', function() { + renderWithTestResponses(this.view, 3, { + resp_total: 111 + }); + this.view.$el.find('.load-response-button').click(); + return assertResponseCountAndPaginationCorrect( + this.view, '111 responses', 'Showing first 3 responses', 'Load next 100 responses' + ); + }); + }); + }); + }); + describe('for question threads', function() { + var generateContent, renderTestCase; + beforeEach(function() { + this.thread.set('thread_type', 'question'); + this.view = new DiscussionThreadView({ + model: this.thread, + el: $('#fixture-element'), + course_settings: DiscussionSpecHelper.createTestCourseSettings() + }); + }); + generateContent = function(idStart, idEnd) { + return _.map(_.range(idStart, idEnd), function(i) { + return createTestResponseJson(i); + }); + }; + renderTestCase = function(view, numEndorsed, numNonEndorsed) { + renderWithContent(view, { + endorsed_responses: generateContent(0, numEndorsed), + non_endorsed_responses: generateContent(numEndorsed, numEndorsed + numNonEndorsed), + non_endorsed_resp_total: numNonEndorsed + }); + expect(view.$('.js-marked-answer-list .discussion-response').length).toEqual(numEndorsed); + expect(view.$('.js-response-list .discussion-response').length).toEqual(numNonEndorsed); + return assertResponseCountAndPaginationCorrect( + view, '' + numNonEndorsed + ' ' + (numEndorsed ? 'other ' : '') + + (numNonEndorsed === 1 ? 'response' : 'responses'), + numNonEndorsed ? 'Showing all responses' : null, null + ); + }; + _.each({ + no: 0, + one: 1, + many: 5 + }, function(numEndorsed, endorsedDesc) { + return _.each({ + no: 0, + one: 1, + many: 5 + }, function(numNonEndorsed, nonEndorsedDesc) { + it( + 'renders correctly with ' + endorsedDesc + ' marked answer(s) and ' + nonEndorsedDesc + + ' response(s)', + function() { return renderTestCase(this.view, numEndorsed, numNonEndorsed); } + ); + }); + }); + it('handles pagination correctly', function() { + renderWithContent(this.view, { + endorsed_responses: generateContent(0, 2), + non_endorsed_responses: generateContent(3, 6), + non_endorsed_resp_total: 42 + }); + DiscussionViewSpecHelper.setNextResponseContent({ + endorsed_responses: generateContent(0, 3), + non_endorsed_responses: generateContent(6, 9), + non_endorsed_resp_total: 41 + }); + this.view.$el.find('.load-response-button').click(); + expect($('.js-marked-answer-list .discussion-response').length).toEqual(3); + expect($('.js-response-list .discussion-response').length).toEqual(6); + return assertResponseCountAndPaginationCorrect( + this.view, '41 other responses', 'Showing first 6 responses', 'Load all responses' + ); + }); + }); + describe('post restrictions', function() { + beforeEach(function() { + this.thread.attributes.ability = _.extend(this.thread.attributes.ability, { + can_report: false, + can_vote: false + }); + this.view = new DiscussionThreadView({ + model: this.thread, + el: $('#fixture-element'), + course_settings: DiscussionSpecHelper.createTestCourseSettings() + }); + }); + it("doesn't show report option if can_report ability is disabled", function() { + this.view.render(); + return expect(this.view.$el.find('.action-report').closest('.actions-item')).toHaveClass('is-hidden'); + }); + it("doesn't show voting button if can_vote ability is disabled", function() { + this.view.render(); + return expect(this.view.$el.find('.action-vote').closest('.actions-item')).toHaveClass('is-disabled'); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/discussion_topic_menu_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/discussion_topic_menu_view_spec.js new file mode 100644 index 00000000..ece16187 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/discussion_topic_menu_view_spec.js @@ -0,0 +1,110 @@ +/* globals DiscussionTopicMenuView, DiscussionSpecHelper, DiscussionCourseSettings, _ */ +(function() { + 'use strict'; + + describe('DiscussionTopicMenuView', function() { + var ExpectedDiscussionId; + beforeEach(function() { + this.createTopicView = function(options) { + options = _.extend({ + course_settings: this.course_settings, + // eslint-disable-next-line no-void + topicId: void 0 + }, options); + this.view = new DiscussionTopicMenuView(options); + this.view.render().appendTo('#fixture-element'); + }; + + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + this.course_settings = new DiscussionCourseSettings({ + category_map: { + subcategories: { + 'Basic Question Types': { + subcategories: {}, + children: [ + ['Selection From Options', 'entry'], + ['Numerical Input', 'entry'], + ['Very long category name', 'entry'], + ['Very very very very long category name', 'entry'], + ['Name with HTML', 'entry'] + ], + entries: { + 'Selection From Options': { + sort_key: null, + is_divided: true, + id: 'cba3e4cd91d0466b9ac50926e495b76f' + }, + 'Numerical Input': { + sort_key: null, + is_divided: false, + id: 'c49f0dfb8fc94c9c8d9999cc95190c56' + }, + 'Very long category name': { + sort_key: null, + is_divided: false, + id: 'c49f0dfb8fc94c9c8d9999cc95190c59' + }, + 'Very very very very long category name': { + sort_key: null, + is_divided: false, + id: 'c49f0dfb8fc94c9c8d9999cc95190e32' + }, + 'Name with HTML': { + sort_key: null, + is_divided: false, + id: 'c49f0dfb8fc94c9c8d9999cc95190363' + } + + } + }, + 'Example Inline Discussion': { + subcategories: {}, + children: [ + ['What Are Your Goals for Creating a MOOC?', 'entry'] + ], + entries: { + 'What Are Your Goals for Creating a MOOC?': { + sort_key: null, + is_divided: true, + id: 'cba3e4cd91d0466b9ac50926e495b931' + } + } + } + }, + children: [ + ['Basic Question Types', 'subcategory'], + ['Example Inline Discussion', 'subcategory'] + ], + entries: {} + }, + is_cohorted: true + }); + }); + + it('defaults to first subtopic', function() { + this.createTopicView(); + expect(this.view.$el.find('option.topic-title:selected').text()).toEqual('Selection From Options'); + }); + + it('titles are escaped before display', function() { + this.createTopicView(); + $(this.view.$el.find('option.topic-title')[4]).prop('selected', true); + expect(this.view.$el.find('option.topic-title:selected').text()).toContain(''); + }); + + it('appropriate topic is selected if topicId is passed', function() { + this.createTopicView({ + topicId: 'c49f0dfb8fc94c9c8d9999cc95190c56' + }); + this.view.render(); + expect(this.view.$el.find('option.topic-title:selected').text()).toEqual('Numerical Input'); + }); + it('if general topic is not present then topiId is set to first discussion topicId', function() { + this.createTopicView({}); + this.view.render(); + ExpectedDiscussionId = this.view.$('.post-topic option').first().data('discussion-id'); + expect(this.view.getCurrentTopicId()).toEqual(ExpectedDiscussionId); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/discussion_view_spec_helper.js b/xblocks_contrib/discussion/assets/static/spec/view/discussion_view_spec_helper.js new file mode 100644 index 00000000..cca39d0c --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/discussion_view_spec_helper.js @@ -0,0 +1,147 @@ +/* globals DiscussionUtil */ +(function() { + 'use strict'; + + var __indexOf = [].indexOf || function(item) { + for (var i = 0, l = this.length; i < l; i++) { + if (i in this && this[i] === item) { + return i; + } + } + return -1; + }; + + this.DiscussionViewSpecHelper = (function() { + var triggerVoteEvent; + + function DiscussionViewSpecHelper() { + } + + DiscussionViewSpecHelper.makeThreadWithProps = function(props) { + var thread; + thread = { + id: 'dummy_id', + thread_type: 'discussion', + pinned: false, + endorsed: false, + votes: { + up_count: '0' + }, + read: false, + unread_comments_count: 0, + comments_count: 0, + abuse_flaggers: [], + body: '', + title: 'dummy title', + created_at: '2014-08-18T01:02:03Z', + ability: { + can_delete: false, + can_reply: true, + can_vote: false, + editable: false + } + }; + return $.extend(thread, props); + }; + + DiscussionViewSpecHelper.checkVoteClasses = function(view) { + var action_button, display_button; + view.render(); + display_button = view.$el.find('.display-vote'); + expect(display_button.hasClass('is-hidden')).toBe(true); + action_button = view.$el.find('.action-vote'); + return expect(action_button).not.toHaveAttr('style', 'display: inline; '); + }; + + DiscussionViewSpecHelper.expectVoteRendered = function(view, model, user) { + var button; + button = view.$el.find('.action-vote'); + expect(button.hasClass('is-checked')).toBe(user.voted(model)); + expect(button.attr('aria-checked')).toEqual(user.voted(model).toString()); + expect(button.find('.vote-count').text()).toMatch('^' + (model.get('votes').up_count) + ' Votes?$'); + return expect(button.find('.sr.js-sr-vote-count').text()) + .toMatch('^there are currently ' + (model.get('votes').up_count) + ' votes?$'); + }; + + DiscussionViewSpecHelper.checkRenderVote = function(view, model) { + view.render(); + DiscussionViewSpecHelper.expectVoteRendered(view, model, window.user); + window.user.vote(model); + view.render(); + DiscussionViewSpecHelper.expectVoteRendered(view, model, window.user); + window.user.unvote(model); + view.render(); + return DiscussionViewSpecHelper.expectVoteRendered(view, model, window.user); + }; + + triggerVoteEvent = function(view, event, expectedUrl) { + var deferred; + deferred = $.Deferred(); + spyOn($, 'ajax').and.callFake(function(params) { + expect(params.url.toString()).toEqual(expectedUrl); + return deferred; + }); + view.render(); + view.$el.find('.action-vote').trigger(event); + expect($.ajax).toHaveBeenCalled(); + return deferred.resolve(); + }; + + DiscussionViewSpecHelper.checkUpvote = function(view, model, user, event) { + var initialVoteCount, _ref, _ref1; + expect((_ref = model.id, __indexOf.call(user.get('upvoted_ids'), _ref) >= 0)).toBe(false); + initialVoteCount = model.get('votes').up_count; + triggerVoteEvent(view, event, DiscussionUtil.urlFor('upvote_' + (model.get('type')), model.id) + '?ajax=1'); + expect((_ref1 = model.id, __indexOf.call(user.get('upvoted_ids'), _ref1) >= 0)).toBe(true); + return expect(model.get('votes').up_count).toEqual(initialVoteCount + 1); + }; + + DiscussionViewSpecHelper.checkUnvote = function(view, model, user, event) { + var initialVoteCount, _ref; + user.vote(model); + expect((_ref = model.id, __indexOf.call(user.get('upvoted_ids'), _ref) >= 0)).toBe(true); + initialVoteCount = model.get('votes').up_count; + triggerVoteEvent( + view, event, DiscussionUtil.urlFor('undo_vote_for_' + (model.get('type')), model.id) + '?ajax=1' + ); + expect(user.get('upvoted_ids')).toEqual([]); + return expect(model.get('votes').up_count).toEqual(initialVoteCount - 1); + }; + + DiscussionViewSpecHelper.checkButtonEvents = function(view, viewFunc, buttonSelector) { + var button, spy; + spy = spyOn(view, viewFunc); + button = view.$el.find(buttonSelector); + button.click(); + expect(spy).toHaveBeenCalled(); + spy.calls.reset(); + button.trigger($.Event('keydown', { + which: 13 + })); + expect(spy).not.toHaveBeenCalled(); + spy.calls.reset(); + button.trigger($.Event('keydown', { + which: 32 + })); + return expect(spy).toHaveBeenCalled(); + }; + + DiscussionViewSpecHelper.checkVoteButtonEvents = function(view) { + return this.checkButtonEvents(view, 'toggleVote', '.action-vote'); + }; + + DiscussionViewSpecHelper.setNextResponseContent = function(content) { + return $.ajax.and.callFake(function(params) { + params.success({ + content: content + }); + return { + always: function() { + } + }; + }); + }; + + return DiscussionViewSpecHelper; + }()); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/new_post_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/new_post_view_spec.js new file mode 100644 index 00000000..b388526b --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/new_post_view_spec.js @@ -0,0 +1,347 @@ +/* globals Discussion, DiscussionCourseSettings, DiscussionSpecHelper, DiscussionUtil, NewPostView */ +(function() { + 'use strict'; + + describe('NewPostView', function() { + var checkVisibility; + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + window.$$course_id = 'edX/999/test'; + spyOn(DiscussionUtil, 'makeWmdEditor').and.callFake(function($content, $local, cls_identifier) { + return $local('.' + cls_identifier).html(''); + }); + this.discussion = new Discussion([], { + pages: 1 + }); + }); + checkVisibility = function(view, expectedVisible, expectedDisabled, render) { + var disabled, group_disabled; + if (render) { + view.render(); + } + expect(view.$('.group-selector-wrapper').is(':visible') || false).toEqual(expectedVisible); + disabled = view.$('.js-group-select').prop('disabled') || false; + group_disabled = view.$('.group-selector-wrapper').hasClass('disabled'); + if (expectedVisible && !expectedDisabled) { + expect(disabled).toEqual(false); + return expect(group_disabled).toEqual(false); + } else if (expectedDisabled) { + expect(disabled).toEqual(true); + return expect(group_disabled).toEqual(true); + } + }; + describe('group selector', function() { + beforeEach(function() { + this.course_settings = new DiscussionCourseSettings({ + category_map: { + children: [['Topic', 'entry'], ['General', 'entry'], ['Not Cohorted', 'entry']], + entries: { + Topic: { + is_divided: true, + id: 'topic' + }, + General: { + is_divided: true, + id: 'general' + }, + 'Not Cohorted': { + is_divided: false, + id: 'not-cohorted' + } + } + }, + allow_anonymous: false, + allow_anonymous_to_peers: false, + is_discussion_division_enabled: true, + groups: [ + { + id: 1, + name: 'Cohort1' + }, { + id: 2, + name: 'Cohort2' + } + ] + }); + this.view = new NewPostView({ + el: $('#fixture-element'), + collection: this.discussion, + course_settings: this.course_settings, + is_commententable_cohorted: true, + mode: 'tab' + }); + }); + it('is not visible to students', function() { + return checkVisibility(this.view, false, false, true); + }); + it('allows TAs to see the group selector when the topic is divided', function() { + DiscussionSpecHelper.makeTA(); + return checkVisibility(this.view, true, false, true); + }); + it('allows moderators to see the group selector when the topic is divided', function() { + DiscussionSpecHelper.makeModerator(); + return checkVisibility(this.view, true, false, true); + }); + it('only enables the group selector when applicable', function() { + DiscussionSpecHelper.makeModerator(); + checkVisibility(this.view, true, false, true); + + $('option:contains(Not Cohorted)').prop('selected', true); + $('.post-topic').trigger('change'); + checkVisibility(this.view, true, true, false); + + $('option:contains(Topic)').prop('selected', true); + $('.post-topic').trigger('change'); + return checkVisibility(this.view, true, false, false); + }); + it('visibility message changes when group is changed', function() { + DiscussionSpecHelper.makeModerator(); + checkVisibility(this.view, true, false, true); + + $('option:contains(Topic)').prop('selected', true); + $('.post-topic').trigger('change'); + expect($('.js-group-select option:selected').text()) + .toEqual('All Groups'); + expect($('.group-visibility').text().trim()) + .toEqual('This post will be visible only to All Groups.'); + + $('.js-group-select option:contains(Cohort1)').prop('selected', true); + $('.js-group-select').trigger('change'); + expect($('.js-group-select option:selected').text()) + .toEqual('Cohort1'); + expect($('.group-visibility').text().trim()) + .toEqual('This post will be visible only to Cohort1.'); + return checkVisibility(this.view, true, false, false); + }); + it('allows the user to make a group selection', function() { + var expectedGroupId, + self = this; + DiscussionSpecHelper.makeModerator(); + this.view.render(); + expectedGroupId = null; + DiscussionSpecHelper.makeAjaxSpy(function(params) { + expect(params.data.group_id).toEqual(expectedGroupId); + }); + return _.each(['1', '2', ''], function(groupIdStr) { + expectedGroupId = groupIdStr; + self.view.$('.js-group-select').val(groupIdStr); + self.view.$('.js-post-title').val('dummy title'); + self.view.$('.js-post-body textarea').val('dummy body'); + self.view.$('.forum-new-post-form').submit(); + expect($.ajax).toHaveBeenCalled(); + self.view.$('.forum-new-post-form').prop('disabled', false); + return $.ajax.calls.reset(); + }); + }); + }); + describe('always divide inline discussions ', function() { + beforeEach(function() { + this.course_settings = new DiscussionCourseSettings({ + category_map: { + children: [], + entries: {} + }, + allow_anonymous: false, + allow_anonymous_to_peers: false, + is_discussion_division_enabled: true, + groups: [ + { + id: 1, + name: 'Cohort1' + }, { + id: 2, + name: 'Cohort2' + } + ] + }); + this.view = new NewPostView({ + el: $('#fixture-element'), + collection: this.discussion, + course_settings: this.course_settings, + mode: 'tab' + }); + }); + it('disables the group menu if it is set false', function() { + DiscussionSpecHelper.makeModerator(); + this.view.is_commentable_divided = false; + return checkVisibility(this.view, true, true, true); + }); + it('enables the group menu if it is set true', function() { + DiscussionSpecHelper.makeModerator(); + this.view.is_commentable_divided = true; + return checkVisibility(this.view, true, false, true); + }); + it('is not visible to students when set false', function() { + this.view.is_commentable_divided = false; + return checkVisibility(this.view, false, false, true); + }); + it('is not visible to students when set true', function() { + this.view.is_commentable_divided = true; + return checkVisibility(this.view, false, false, true); + }); + }); + describe('cancel post resets form ', function() { + var checkPostCancelReset; + beforeEach(function() { + this.course_settings = new DiscussionCourseSettings({ + allow_anonymous_to_peers: true, + allow_anonymous: true, + category_map: { + subcategories: { + 'Week 1': { + subcategories: {}, + children: [ + ['Topic-Level Student-Visible Label', 'entry'] + ], + entries: { + 'Topic-Level Student-Visible Label': { + sort_key: null, + is_divided: false, + id: '2b3a858d0c884eb4b272dbbe3f2ffddd' + } + } + } + }, + children: [ + ['General', 'entry'], + ['Week 1', 'subcategory'] + ], + entries: { + General: { + sort_key: 'General', + is_divided: false, + id: 'i4x-waqastest-waqastest-course-waqastest' + } + } + } + }); + }); + checkPostCancelReset = function(mode, discussion, course_settings) { + var eventSpy, view; + view = new NewPostView({ + el: $('#fixture-element'), + collection: discussion, + course_settings: course_settings, + mode: mode + }); + view.render(); + eventSpy = jasmine.createSpy('eventSpy'); + view.listenTo(view, 'newPost:cancel', eventSpy); + view.$('.post-errors').html("
  • Title can't be empty
  • "); + view.$("label[for$='post-type-question']").click(); + view.$('.js-post-title').val('Test Title'); + view.$('.js-post-body textarea').val('Test body'); + view.$('.wmd-preview p').html('Test body'); + view.$('input[name=follow]').prop('checked', false); + view.$('input[name=anonymous]').prop('checked', true); + view.$('input[name=anonymous_to_peers]').prop('checked', true); + if (mode === 'tab') { + view.$("a[data-discussion-id='2b3a858d0c884eb4b272dbbe3f2ffddd']").click(); + } + view.$('.cancel').click(); + expect(eventSpy).toHaveBeenCalled(); + expect(view.$('.post-errors').html()).toEqual(''); + expect($("input[id$='post-type-discussion']")).toBeChecked(); + expect($("input[id$='post-type-question']")).not.toBeChecked(); + expect(view.$('.js-post-title').val()).toEqual(''); + expect(view.$('.js-post-body textarea').val()).toEqual(''); + expect(view.$('input[name=follow]')).toBeChecked(); + expect(view.$('input[name=anonymous]')).not.toBeChecked(); + expect(view.$('input[name=anonymous_to_peers]')).not.toBeChecked(); + if (mode === 'tab') { + return expect(view.$('.post-topic option:selected').text()).toEqual('General'); + } + }; + return _.each(['tab', 'inline'], function(mode) { + it('resets the form in ' + mode + ' mode', function() { + return checkPostCancelReset(mode, this.discussion, this.course_settings); + }); + }); + }); + describe('default topic ', function() { + beforeEach(function() { + this.course_settings = new DiscussionCourseSettings({ + allow_anonymous_to_peers: true, + allow_anonymous: true, + category_map: { + subcategories: { + 'Week 1': { + subcategories: {}, + children: [ + ['Topic-Level Student-Visible Label', 'entry'] + ], + entries: { + 'Topic-Level Student-Visible Label': { + sort_key: null, + is_divided: false, + id: '2b3a858d0c884eb4b272dbbe3f2ffddd' + } + } + } + }, + children: [ + ['First topic', 'entry'], + ['Week 1', 'subcategory'] + ], + entries: { + 'First topic': { + sort_key: 'First topic', + is_divided: false, + id: 'i4x-waqastest-waqastest-course-waqastest' + } + } + } + }); + }); + + it('should be the first topic if General is not found', function() { + var eventSpy, view; + view = new NewPostView({ + el: $('#fixture-element'), + collection: this.discussion, + course_settings: this.course_settings, + mode: 'tab' + }); + view.render(); + eventSpy = jasmine.createSpy('eventSpy'); + view.listenTo(view, 'newPost:cancel', eventSpy); + view.$('.post-errors').html("
  • Title can't be empty
  • "); + view.$("label[for$='post-type-question']").click(); + view.$('.js-post-title').val('Test Title'); + view.$('.js-post-body textarea').val('Test body'); + view.$('.wmd-preview p').html('Test body'); + view.$('input[name=follow]').prop('checked', false); + view.$('input[name=anonymous]').prop('checked', true); + view.$('input[name=anonymous_to_peers]').prop('checked', true); + view.$("a[data-discussion-id='2b3a858d0c884eb4b272dbbe3f2ffddd']").click(); + view.$('.cancel').click(); + expect(view.$('.post-topic option:selected').text()).toEqual('First topic'); + }); + }); + it('posts to the correct URL', function() { + var topicId, view; + topicId = 'test_topic'; + spyOn($, 'ajax').and.callFake(function(params) { + expect(params.url.path()).toEqual(DiscussionUtil.urlFor('create_thread', topicId)); + return { + always: function() { + } + }; + }); + view = new NewPostView({ + el: $('#fixture-element'), + collection: this.discussion, + course_settings: new DiscussionCourseSettings({ + allow_anonymous: false, + allow_anonymous_to_peers: false + }), + mode: 'inline', + topicId: topicId + }); + view.render(); + view.$('.forum-new-post-form').submit(); + return expect($.ajax).toHaveBeenCalled(); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/response_comment_show_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/response_comment_show_view_spec.js new file mode 100644 index 00000000..d210ead0 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/response_comment_show_view_spec.js @@ -0,0 +1,121 @@ +/* globals DiscussionSpecHelper, DiscussionUtil, DiscussionViewSpecHelper, ResponseCommentShowView */ +(function() { + 'use strict'; + + describe('ResponseCommentShowView', function() { + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + this.comment = new Comment({ + id: '01234567', + user_id: '567', + course_id: 'edX/999/test', + body: 'this is a response', + created_at: '2013-04-03T20:08:39Z', + abuse_flaggers: ['123'], + roles: [] + }); + this.view = new ResponseCommentShowView({ + model: this.comment + }); + return spyOn(this.view, 'convertMath'); + }); + it('defines the tag', function() { + expect($('#jasmine-fixtures')).toExist(); + expect(this.view.tagName).toBeDefined(); + return expect(this.view.el.tagName.toLowerCase()).toBe('li'); + }); + it('is tied to the model', function() { + return expect(this.view.model).toBeDefined(); + }); + describe('rendering', function() { + beforeEach(function() { + return spyOn(this.view, 'renderAttrs'); + }); + it('can be flagged for abuse', function() { + this.comment.flagAbuse(); + return expect(this.comment.get('abuse_flaggers')).toEqual(['123', '567']); + }); + it('can be unflagged for abuse', function() { + var temp_array; + temp_array = []; + temp_array.push(window.user.get('id')); + this.comment.set('abuse_flaggers', temp_array); + this.comment.unflagAbuse(); + return expect(this.comment.get('abuse_flaggers')).toEqual([]); + }); + }); + describe('_delete', function() { + it('triggers on the correct events', function() { + DiscussionUtil.loadRoles([]); + this.comment.updateInfo({ + ability: { + can_delete: true + } + }); + this.view.render(); + return DiscussionViewSpecHelper.checkButtonEvents(this.view, '_delete', '.action-delete'); + }); + it('triggers the delete event', function() { + var triggerTarget; + triggerTarget = jasmine.createSpy(); + this.view.bind('comment:_delete', triggerTarget); + this.view._delete(); + return expect(triggerTarget).toHaveBeenCalled(); + }); + }); + describe('edit', function() { + it('triggers on the correct events', function() { + DiscussionUtil.loadRoles([]); + this.comment.updateInfo({ + ability: { + can_edit: true + } + }); + this.view.render(); + return DiscussionViewSpecHelper.checkButtonEvents(this.view, 'edit', '.action-edit'); + }); + it('triggers comment:edit when the edit button is clicked', function() { + var triggerTarget; + triggerTarget = jasmine.createSpy(); + this.view.bind('comment:edit', triggerTarget); + this.view.edit(); + return expect(triggerTarget).toHaveBeenCalled(); + }); + }); + describe('labels', function() { + var expectOneElement; + expectOneElement = function(view, selector, visible) { + var elements; + if (typeof visible === 'undefined' || visible === null) { + visible = true; + } + view.render(); + elements = view.$el.find(selector); + expect(elements.length).toEqual(1); + if (visible) { + return expect(elements).not.toHaveClass('is-hidden'); + } else { + return expect(elements).toHaveClass('is-hidden'); + } + }; + it('displays the reported label when appropriate for a non-staff user', function() { + this.comment.set('abuse_flaggers', []); + expectOneElement(this.view, '.post-label-reported', false); + this.comment.set('abuse_flaggers', [DiscussionUtil.getUser().id]); + expectOneElement(this.view, '.post-label-reported'); + this.comment.set('abuse_flaggers', [DiscussionUtil.getUser().id + 1]); + return expectOneElement(this.view, '.post-label-reported', false); + }); + it('displays the reported label when appropriate for a flag moderator', function() { + DiscussionSpecHelper.makeModerator(); + this.comment.set('abuse_flaggers', []); + expectOneElement(this.view, '.post-label-reported', false); + this.comment.set('abuse_flaggers', [DiscussionUtil.getUser().id]); + expectOneElement(this.view, '.post-label-reported'); + this.comment.set('abuse_flaggers', [DiscussionUtil.getUser().id + 1]); + return expectOneElement(this.view, '.post-label-reported'); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/response_comment_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/response_comment_view_spec.js new file mode 100644 index 00000000..e7975947 --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/response_comment_view_spec.js @@ -0,0 +1,204 @@ +/* globals DiscussionSpecHelper, DiscussionUtil, ResponseCommentView, ResponseCommentShowView, user */ +(function() { + 'use strict'; + + var $$course_id = '$$course_id'; + + describe('ResponseCommentView', function() { + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals({}); + this.comment = new Comment({ + id: '01234567', + user_id: user.id, + course_id: $$course_id, + body: 'this is a response', + created_at: '2013-04-03T20:08:39Z', + abuse_flaggers: ['123'], + roles: ['Student'] + }); + DiscussionSpecHelper.setUnderscoreFixtures(); + this.view = new ResponseCommentView({ + model: this.comment, + el: $('#fixture-element') + }); + spyOn(ResponseCommentShowView.prototype, 'convertMath'); + spyOn(DiscussionUtil, 'makeWmdEditor'); + return this.view.render(); + }); + describe('_delete', function() { + var setAjaxResult; + beforeEach(function() { + this.comment.updateInfo({ + ability: { + can_delete: true + } + }); + this.event = DiscussionSpecHelper.makeEventSpy(); + this.event.target = $('body'); + spyOn(this.comment, 'remove'); + spyOn(this.view.$el, 'remove'); + $(this.event.target).prop('disabled', false); + }); + setAjaxResult = function(isSuccess) { + return spyOn($, 'ajax').and.callFake(function(params) { + (isSuccess ? params.success : params.error)({}); + return { + always: function() { + } + }; + }); + }; + it('requires confirmation before deleting', function() { + spyOn(window, 'confirm').and.returnValue(false); + setAjaxResult(true); + this.view._delete(this.event); + expect(window.confirm).toHaveBeenCalled(); + expect($.ajax).not.toHaveBeenCalled(); + return expect(this.comment.remove).not.toHaveBeenCalled(); + }); + it('removes the deleted comment object', function() { + setAjaxResult(true); + this.view._delete(this.event); + expect(this.comment.remove).toHaveBeenCalled(); + return expect(this.view.$el.remove).toHaveBeenCalled(); + }); + it('calls the ajax comment deletion endpoint', function() { + setAjaxResult(true); + this.view._delete(this.event); + expect(this.event.preventDefault).toHaveBeenCalled(); + expect($.ajax).toHaveBeenCalled(); + return expect($.ajax.calls.mostRecent().args[0].url._parts.path) + .toEqual('/courses/edX/999/test/discussion/comments/01234567/delete'); + }); + it('handles ajax errors', function() { + spyOn(DiscussionUtil, 'discussionAlert'); + setAjaxResult(false); + this.view._delete(this.event); + expect(this.event.preventDefault).toHaveBeenCalled(); + expect($.ajax).toHaveBeenCalled(); + expect(this.comment.remove).not.toHaveBeenCalled(); + expect(this.view.$el.remove).not.toHaveBeenCalled(); + return expect(DiscussionUtil.discussionAlert).toHaveBeenCalled(); + }); + it('does not delete a comment if the permission is false', function() { + this.comment.updateInfo({ + ability: { + can_delete: false + } + }); + spyOn(window, 'confirm'); + setAjaxResult(true); + this.view._delete(this.event); + expect(window.confirm).not.toHaveBeenCalled(); + expect($.ajax).not.toHaveBeenCalled(); + expect(this.comment.remove).not.toHaveBeenCalled(); + return expect(this.view.$el.remove).not.toHaveBeenCalled(); + }); + }); + describe('renderShowView', function() { + it('renders the show view, removes the edit view, and registers event handlers', function() { + spyOn(this.view, '_delete'); + spyOn(this.view, 'edit'); + this.view.renderEditView(); + this.view.renderShowView(); + this.view.showView.trigger('comment:_delete', DiscussionSpecHelper.makeEventSpy()); + expect(this.view._delete).toHaveBeenCalled(); + this.view.showView.trigger('comment:edit', DiscussionSpecHelper.makeEventSpy()); + expect(this.view.edit).toHaveBeenCalled(); + return expect(this.view.$('.edit-post-form#comment_' + this.comment.id)) + .not.toHaveClass('edit-post-form'); + }); + }); + describe('renderEditView', function() { + it('renders the edit view, removes the show view, and registers event handlers', function() { + spyOn(this.view, 'update'); + spyOn(this.view, 'cancelEdit'); + this.view.renderEditView(); + this.view.editView.trigger('comment:update', DiscussionSpecHelper.makeEventSpy()); + expect(this.view.update).toHaveBeenCalled(); + this.view.editView.trigger('comment:cancel_edit', DiscussionSpecHelper.makeEventSpy()); + expect(this.view.cancelEdit).toHaveBeenCalled(); + return expect(this.view.$('.edit-post-form#comment_' + this.comment.id)).toHaveClass('edit-post-form'); + }); + }); + describe('edit', function() { + it('triggers the appropriate event and switches to the edit view', function() { + var editTarget; + spyOn(this.view, 'renderEditView'); + editTarget = jasmine.createSpy(); + this.view.bind('comment:edit', editTarget); + this.view.edit(); + expect(this.view.renderEditView).toHaveBeenCalled(); + return expect(editTarget).toHaveBeenCalled(); + }); + }); + describe('with edit view displayed', function() { + beforeEach(function() { + return this.view.renderEditView(); + }); + describe('cancelEdit', function() { + it('triggers the appropriate event and switches to the show view', function() { + var cancelEditTarget; + spyOn(this.view, 'renderShowView'); + cancelEditTarget = jasmine.createSpy(); + this.view.bind('comment:cancel_edit', cancelEditTarget); + this.view.cancelEdit(); + expect(this.view.renderShowView).toHaveBeenCalled(); + return expect(cancelEditTarget).toHaveBeenCalled(); + }); + }); + describe('update', function() { + beforeEach(function() { + var self = this; + this.updatedBody = 'updated body'; + this.view.$el.find('.edit-comment-body').html($('')); + this.view.$el.find('.edit-comment-body textarea').val(this.updatedBody); + spyOn(this.view, 'cancelEdit'); + spyOn($, 'ajax').and.callFake(function(params) { + if (self.ajaxSucceed) { + params.success(); + } else { + params.error({ + status: 500 + }); + } + return { + always: function() { + } + }; + }); + + this.event = DiscussionSpecHelper.makeEventSpy(); + // All the way down in discussion/utils.js there's this line + // element.after(...); + // element is event.target in this case. This causes a JS exception, so we override the target + this.event.target = $('body'); + $(this.event.target).prop('disabled', false); + }); + it('calls the update endpoint correctly and displays the show view on success', function() { + this.ajaxSucceed = true; + this.view.update(this.event); + expect($.ajax).toHaveBeenCalled(); + expect($.ajax.calls.mostRecent().args[0].url._parts.path) + .toEqual('/courses/edX/999/test/discussion/comments/01234567/update'); + expect($.ajax.calls.mostRecent().args[0].data.body).toEqual(this.updatedBody); + expect(this.view.model.get('body')).toEqual(this.updatedBody); + return expect(this.view.cancelEdit).toHaveBeenCalled(); + }); + it('handles AJAX errors', function() { + var originalBody; + originalBody = this.comment.get('body'); + this.ajaxSucceed = false; + this.view.update(this.event); + expect($.ajax).toHaveBeenCalled(); + expect($.ajax.calls.mostRecent().args[0].url._parts.path) + .toEqual('/courses/edX/999/test/discussion/comments/01234567/update'); + expect($.ajax.calls.mostRecent().args[0].data.body).toEqual(this.updatedBody); + expect(this.view.model.get('body')).toEqual(originalBody); + expect(this.view.cancelEdit).not.toHaveBeenCalled(); + return expect(this.view.$('.edit-comment-form-errors > *').length).toEqual(1); + }); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/thread_response_show_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/thread_response_show_view_spec.js new file mode 100644 index 00000000..31a4599c --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/thread_response_show_view_spec.js @@ -0,0 +1,267 @@ +/* globals DiscussionViewSpecHelper, DiscussionSpecHelper, DiscussionUtil, Thread, ThreadResponseShowView */ +(function() { + 'use strict'; + + describe('ThreadResponseShowView', function() { + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + this.user = DiscussionUtil.getUser(); + this.thread = new Thread({ + thread_type: 'discussion' + }); + this.commentData = { + id: 'dummy', + user_id: '567', + course_id: 'TestOrg/TestCourse/TestRun', + body: 'this is a comment', + created_at: '2013-04-03T20:08:39Z', + endorsed: false, + endorsement: {}, + abuse_flaggers: [], + votes: { + up_count: 42 + }, + type: 'comment' + }; + this.comment = new Comment(this.commentData); + this.comment.set('thread', this.thread); + this.view = new ThreadResponseShowView({ + model: this.comment, + $el: $('#fixture-element') + }); + spyOn(ThreadResponseShowView.prototype, 'convertMath'); + return this.view.render(); + }); + describe('voting', function() { + it('renders the vote state correctly', function() { + return DiscussionViewSpecHelper.checkRenderVote(this.view, this.comment); + }); + it('check the vote classes after renders', function() { + return DiscussionViewSpecHelper.checkVoteClasses(this.view); + }); + it('votes correctly via click', function() { + return DiscussionViewSpecHelper.checkUpvote(this.view, this.comment, this.user, $.Event('click')); + }); + it('votes correctly via spacebar', function() { + return DiscussionViewSpecHelper.checkUpvote(this.view, this.comment, this.user, $.Event('keydown', { + which: 32 + })); + }); + it('unvotes correctly via click', function() { + return DiscussionViewSpecHelper.checkUnvote(this.view, this.comment, this.user, $.Event('click')); + }); + it('unvotes correctly via spacebar', function() { + return DiscussionViewSpecHelper.checkUnvote(this.view, this.comment, this.user, $.Event('keydown', { + which: 32 + })); + }); + }); + it('renders endorsement correctly for a marked answer in a question thread', function() { + var endorsement; + endorsement = { + username: 'test_endorser', + user_id: 'test_id', + time: new Date().toISOString() + }; + this.thread.set('thread_type', 'question'); + this.comment.set({ + endorsed: true, + endorsement: endorsement + }); + this.view.render(); + expect(this.view.$('.posted-details').text().replace(/\s+/g, ' ')) + .toMatch('marked as answer less than a minute ago by ' + endorsement.username); + return expect(this.view.$('.posted-details > a').attr('href')) + .toEqual('/courses/edX/999/test/discussion/forum/users/test_id'); + }); + it('renders anonymous endorsement correctly for a marked answer in a question thread', function() { + var endorsement; + endorsement = { + username: null, + time: new Date().toISOString() + }; + this.thread.set('thread_type', 'question'); + this.comment.set({ + endorsed: true, + endorsement: endorsement + }); + this.view.render(); + expect(this.view.$('.posted-details').text()).toMatch('marked as answer less than a minute ago'); + return expect(this.view.$('.posted-details').text()).not.toMatch('\sby\s'); + }); + it('renders endorsement correctly for an endorsed response in a discussion thread', function() { + var endorsement; + endorsement = { + username: 'test_endorser', + user_id: 'test_id', + time: new Date().toISOString() + }; + this.thread.set('thread_type', 'discussion'); + this.comment.set({ + endorsed: true, + endorsement: endorsement + }); + this.view.render(); + expect(this.view.$('.posted-details').text().replace(/\s+/g, ' ')) + .toMatch('endorsed less than a minute ago by ' + endorsement.username); + return expect(this.view.$('.posted-details > a').attr('href')) + .toEqual('/courses/edX/999/test/discussion/forum/users/test_id'); + }); + it('renders anonymous endorsement correctly for an endorsed response in a discussion thread', function() { + var endorsement; + endorsement = { + username: null, + time: new Date().toISOString() + }; + this.thread.set('thread_type', 'discussion'); + this.comment.set({ + endorsed: true, + endorsement: endorsement + }); + this.view.render(); + expect(this.view.$('.posted-details').text()).toMatch('endorsed less than a minute ago'); + return expect(this.view.$('.posted-details').text()).not.toMatch('\sby\s'); + }); + it('re-renders correctly when endorsement changes', function() { + spyOn($, 'ajax').and.returnValue($.Deferred()); + DiscussionUtil.loadRoles({ + Moderator: [parseInt(window.user.id)] + }); + this.thread.set('thread_type', 'question'); + this.view.render(); + expect(this.view.$('.posted-details').text()).not.toMatch('marked as answer'); + this.view.$('.action-answer').click(); + expect(this.view.$('.posted-details').text()).toMatch('marked as answer'); + this.view.$('.action-answer').click(); + expect(this.view.$('.posted-details').text()).not.toMatch('marked as answer'); + + // Previously the endorsement state would revert after a page load due to a bug in the template + this.view.render(); + expect(this.view.$('.posted-details').text()).not.toMatch('marked as answer'); + }); + it('allows a moderator to mark an answer in a question thread', function() { + var endorseButton; + spyOn($, 'ajax').and.returnValue($.Deferred()); + DiscussionUtil.loadRoles({ + Moderator: [parseInt(window.user.id)] + }); + this.thread.set({ + thread_type: 'question', + user_id: (parseInt(window.user.id) + 1).toString() + }); + this.view.render(); + endorseButton = this.view.$('.action-answer'); + expect(endorseButton.length).toEqual(1); + expect(endorseButton.closest('.actions-item')).not.toHaveClass('is-hidden'); + endorseButton.click(); + return expect(endorseButton).toHaveClass('is-checked'); + }); + it('allows the author of a question thread to mark an answer', function() { + var endorseButton; + spyOn($, 'ajax').and.returnValue($.Deferred()); + this.thread.set({ + thread_type: 'question', + user_id: window.user.id + }); + this.view.render(); + endorseButton = this.view.$('.action-answer'); + expect(endorseButton.length).toEqual(1); + expect(endorseButton.closest('.actions-item')).not.toHaveClass('is-hidden'); + endorseButton.click(); + return expect(endorseButton).toHaveClass('is-checked'); + }); + it('does not allow the author of a discussion thread to endorse', function() { + var endorseButton; + this.thread.set({ + thread_type: 'discussion', + user_id: window.user.id + }); + this.view.render(); + endorseButton = this.view.$('.action-endorse'); + expect(endorseButton.length).toEqual(1); + return expect(endorseButton.closest('.actions-item')).toHaveClass('is-hidden'); + }); + it('does not allow a student who is not the author of a question thread to mark an answer', function() { + var endorseButton; + this.thread.set({ + thread_type: 'question', + user_id: (parseInt(window.user.id) + 1).toString() + }); + this.view.render(); + endorseButton = this.view.$('.action-answer'); + expect(endorseButton.length).toEqual(1); + return expect(endorseButton.closest('.actions-item')).toHaveClass('is-hidden'); + }); + describe('labels', function() { + var expectOneElement; + expectOneElement = function(view, selector, visible) { + var elements; + if (typeof visible === 'undefined' || visible === null) { + visible = true; + } + view.render(); + elements = view.$el.find(selector); + expect(elements.length).toEqual(1); + if (visible) { + return expect(elements).not.toHaveClass('is-hidden'); + } else { + return expect(elements).toHaveClass('is-hidden'); + } + }; + it('displays the reported label when appropriate for a non-staff user', function() { + expectOneElement(this.view, '.post-label-reported', false); + this.comment.set('abuse_flaggers', [DiscussionUtil.getUser().id]); + expectOneElement(this.view, '.post-label-reported'); + this.comment.set('abuse_flaggers', [DiscussionUtil.getUser().id + 1]); + return expectOneElement(this.view, '.post-label-reported', false); + }); + it('displays the reported label when appropriate for a flag moderator', function() { + DiscussionSpecHelper.makeModerator(); + expectOneElement(this.view, '.post-label-reported', false); + this.comment.set('abuse_flaggers', [DiscussionUtil.getUser().id]); + expectOneElement(this.view, '.post-label-reported'); + this.comment.set('abuse_flaggers', [DiscussionUtil.getUser().id + 1]); + return expectOneElement(this.view, '.post-label-reported'); + }); + }); + describe('endorser display', function() { + var checkUserLink; + beforeEach(function() { + this.comment.set('endorsement', { + username: 'test_endorser', + time: new Date().toISOString() + }); + return spyOn(DiscussionUtil, 'urlFor').and.returnValue('test_endorser_url'); + }); + checkUserLink = function(element, is_ta, is_staff) { + expect(element.find('.username').length).toEqual(1); + expect(element.find('.username').text()).toEqual('test_endorser'); + expect(element.find('.username').attr('href')).toEqual('test_endorser_url'); + expect(element.find('.user-label-community-ta').length).toEqual(is_ta ? 1 : 0); + return expect(element.find('.user-label-staff').length).toEqual(is_staff ? 1 : 0); + }; + it('renders nothing when the response has not been endorsed', function() { + this.comment.set('endorsement', null); + return expect(this.view.getEndorserDisplay()).toBeNull(); + }); + it('renders correctly for a student-endorsed response', function() { + var $el; + $el = $('#fixture-element').html(this.view.getEndorserDisplay()); + return checkUserLink($el, false, false); + }); + it('renders correctly for a community TA-endorsed response', function() { + var $el; + spyOn(DiscussionUtil, 'isTA').and.returnValue(true); + $el = $('#fixture-element').html(this.view.getEndorserDisplay()); + return checkUserLink($el, true, false); + }); + it('renders correctly for a staff-endorsed response', function() { + var $el; + spyOn(DiscussionUtil, 'isStaff').and.returnValue(true); + $el = $('#fixture-element').html(this.view.getEndorserDisplay()); + return checkUserLink($el, false, true); + }); + }); + }); +}).call(this); diff --git a/xblocks_contrib/discussion/assets/static/spec/view/thread_response_view_spec.js b/xblocks_contrib/discussion/assets/static/spec/view/thread_response_view_spec.js new file mode 100644 index 00000000..918ca73f --- /dev/null +++ b/xblocks_contrib/discussion/assets/static/spec/view/thread_response_view_spec.js @@ -0,0 +1,149 @@ +/* globals DiscussionSpecHelper, ResponseCommentView, Thread, ThreadResponseView, ThreadResponseShowView, _ */ +(function() { + 'use strict'; + + describe('ThreadResponseView', function() { + beforeEach(function() { + DiscussionSpecHelper.setUpGlobals(); + DiscussionSpecHelper.setUnderscoreFixtures(); + this.thread = new Thread({ + thread_type: 'discussion' + }); + this.response = new Comment({ + children: [{}, {}], + thread: this.thread + }); + this.view = new ThreadResponseView({ + model: this.response, + el: $('#fixture-element') + }); + spyOn(ThreadResponseShowView.prototype, 'render'); + return spyOn(ResponseCommentView.prototype, 'render'); + }); + describe('closed and open Threads', function() { + var checkCommentForm; + checkCommentForm = function(closed) { + var comment, commentData, thread, view; + thread = new Thread({ + thread_type: 'discussion', + closed: closed + }); + commentData = { + id: 'dummy', + user_id: '567', + course_id: 'TestOrg/TestCourse/TestRun', + body: 'this is a comment', + created_at: '2013-04-03T20:08:39Z', + abuse_flaggers: [], + type: 'comment', + children: [], + thread: thread + }; + comment = new Comment(commentData); + view = new ThreadResponseView({ + model: comment, + el: $('#fixture-element') + }); + view.render(); + return expect(view.$('.comment-form').closest('li').is(':visible')).toBe(!closed); + }; + it('hides comment form when thread is closed', function() { + return checkCommentForm(true); + }); + it('show comment form when thread is open', function() { + return checkCommentForm(false); + }); + }); + describe('submitComment', function() { + it('focus should be in response container after a new comment is posted', function() { + this.view.render(); + expect(this.view.$('.comments')).toBeVisible(); + expect(document.activeElement === this.view.$('.forum-response')[0]); + }); + }); + describe('renderComments', function() { + it('hides "show comments" link if collapseComments is not set', function() { + this.view.render(); + expect(this.view.$('.comments')).toBeVisible(); + return expect(this.view.$('.action-show-comments')).not.toBeVisible(); + }); + it('hides "show comments" link if collapseComments is set but response has no comments', function() { + this.response = new Comment({ + children: [], + thread: this.thread + }); + this.view = new ThreadResponseView({ + model: this.response, + el: $('#fixture-element'), + collapseComments: true + }); + this.view.render(); + expect(this.view.$('.comments')).toBeVisible(); + return expect(this.view.$('.action-show-comments')).not.toBeVisible(); + }); + it( + 'hides comments if collapseComments is set and shows them when "show comments" link is clicked', + function() { + this.view = new ThreadResponseView({ + model: this.response, + el: $('#fixture-element'), + collapseComments: true + }); + this.view.render(); + expect(this.view.$('.comments')).not.toBeVisible(); + expect(this.view.$('.action-show-comments')).toBeVisible(); + this.view.$('.action-show-comments').click(); + expect(this.view.$('.comments')).toBeVisible(); + return expect(this.view.$('.action-show-comments')).not.toBeVisible(); + } + ); + it('calls renderTemplate with a temporary id if the model lacks one', function() { + this.view = new ThreadResponseView({ + model: this.response, + el: $('#fixture-element'), + collapseComments: true + }); + spyOn(_, 'extend').and.callThrough(); + spyOn(window, 'Date').and.callFake(function() { + return { + getTime: function() { + return 1; + } + }; + }); + this.view.render(); + expect(_.extend).toHaveBeenCalledWith(jasmine.any(Object), jasmine.objectContaining({ + wmdId: 1 + })); + }); + it('populates commentViews and binds events', function() { + this.view.createEditView(); + spyOn(this.view, 'cancelEdit'); + spyOn(this.view, 'cancelCommentEdits'); + spyOn(this.view, 'hideCommentForm'); + spyOn(this.view, 'showCommentForm'); + this.view.renderComments(); + expect(this.view.commentViews.length).toEqual(2); + this.view.commentViews[0].trigger('comment:edit', jasmine.createSpyObj('event', ['preventDefault'])); + expect(this.view.cancelEdit).toHaveBeenCalled(); + expect(this.view.cancelCommentEdits).toHaveBeenCalled(); + expect(this.view.hideCommentForm).toHaveBeenCalled(); + this.view.commentViews[0].trigger('comment:cancel_edit'); + return expect(this.view.showCommentForm).toHaveBeenCalled(); + }); + }); + describe('cancelCommentEdits', function() { + it('calls cancelEdit on each comment view', function() { + this.view.renderComments(); + expect(this.view.commentViews.length).toEqual(2); + _.each(this.view.commentViews, function(commentView) { + return spyOn(commentView, 'cancelEdit'); + }); + this.view.cancelCommentEdits(); + return _.each(this.view.commentViews, function(commentView) { + return expect(commentView.cancelEdit).toHaveBeenCalled(); + }); + }); + }); + }); +}).call(this);